PrintEnglishImpl.mesa
Copyright c 1985 by Xerox Corporation. All rights reserved.
Doug Terry July 8, 1985 2:06:25 pm PDT
Doug Terry, March 4, 1986 2:52:29 pm PST
DIRECTORY
Commander USING [Register, CommandProc],
CommandTool USING [ArgumentVector, Failed, Parse, NextArgument],
Convert USING [Error, IntFromRope],
IO USING [PutF, rope],
Rope USING [ROPE, Cat, Substr],
PrintEnglish;
PrintEnglishImpl: CEDAR PROGRAM
IMPORTS Commander, CommandTool, Convert, IO, Rope
EXPORTS PrintEnglish
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
largestMajor: INT = 3; -- the largest INT is in the billions
majors: ARRAY [0..21] OF ROPE = [
-- most of these are not currently used, but are included for completeness
"",
" thousand",
" million",
" billion",
" trillion",
" quadrillion",
" quintillion",
" sextillion",
" septillion",
" octillion",
" nonillion",
" decillion",
" undecillion",
" duodecillion",
" tredecillion",
" quattuordecillion",
" quindecillion",
" sexdecillion",
" septendecillion",
" octodecillion",
" novemdecillion",
" vigintillion"
];
ones: ARRAY [0..9] OF ROPE = [
" zero",
" one",
" two",
" three",
" four",
" five",
" six",
" seven",
" eight",
" nine"
];
teens: ARRAY [0..9] OF ROPE = [
" ten",
" eleven",
" twelve",
" thirteen",
" fourteen",
" fifteen",
" sixteen",
" seventeen",
" eighteen",
" nineteen"
];
tens: ARRAY [0..9] OF ROPE = [
" zero",
" ten",
" twenty",
" thirty",
" forty",
" fifty",
" sixty",
" seventy",
" eighty",
" ninety"
];
Power: PROC [i: INT, power: INT] RETURNS [INT] ~ {
result: INT ← 1;
THROUGH [1..power] DO
result ← result * i;
ENDLOOP;
RETURN[result];
};
SmallIntToEnglish: PROC [i: INT] RETURNS [r: ROPE] ~ {
digit: INT;
r ← NIL;
digit ← i/100;
IF digit # 0 THEN
r ← Rope.Cat[r, ones[digit], " hundred"];
i ← i MOD 100;
IF i IN [10..19] THEN {
r ← Rope.Cat[r, teens[i-10]];
RETURN;
};
digit ← i/10;
IF digit # 0 THEN
r ← Rope.Cat[r, tens[digit]];
i ← i MOD 10;
IF i # 0 THEN
r ← Rope.Cat[r, ones[i]];
};
IntToEnglish: PUBLIC PROC [i: INT] RETURNS [r: ROPE] ~ {
Converts integer numbers to their English equivalents.
high: INT;
mIndex: INT ← largestMajor;
mValue: INT;
r ← NIL;
WHILE mIndex >= 0 DO
mValue ← Power[1000, mIndex];
high ← i / mValue;
IF high # 0 THEN {
r ← Rope.Cat[r, SmallIntToEnglish[high], majors[mIndex]];
i ← i MOD mValue;
};
mIndex ← mIndex -1;
ENDLOOP;
IF r = NIL THEN r ← " zero";
r ← Rope.Substr[base: r, start: 1]; -- to remove initial blank space
};
Number: Commander.CommandProc = {
[cmd: Commander.Handle] RETURNS [result: REF ANY ← NIL, msg: ROPE ← NIL]
i: INT;
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd: cmd ! CommandTool.Failed => GOTO SyntaxError];
IF argv.argc < 2 THEN GOTO SyntaxError;
i ← Convert.IntFromRope[argv[1] ! Convert.Error => GOTO SyntaxError];
i ← Convert.IntFromRope[CommandTool.NextArgument[cmd] ! Convert.Error => GOTO SyntaxError];
IO.PutF[cmd.out, "%g\n", IO.rope[IntToEnglish[i]]];
EXITS
SyntaxError => IO.PutF[cmd.err, "Integer not specified.\n"];
};
Commander.Register[key: "Number", proc: Number,
doc: "Print out the english equivalent of an integer"];
END.
Doug Terry, February 27, 1986 1:06:05 pm PST
changes to: DIRECTORY, PrintEnglishImpl, IMPORTS, EXPORTS, ~, Power, SmallIntToEnglish, IntToEnglish, Number, END
Doug Terry, February 27, 1986 1:10:18 pm PST
changes to: DIRECTORY, IMPORTS, Number
Doug Terry, February 28, 1986 4:27:28 pm PST
changes to: IntToEnglish, DIRECTORY
Doug Terry, March 4, 1986 2:52:29 pm PST
changes to: DIRECTORY, Number