RosettaCodeData/Task/Roman-numerals-Encode/Cowgol/roman-numerals-encode.cowgol

59 lines
1.4 KiB
Plaintext

include "cowgol.coh";
include "argv.coh";
# Encode the given number as a Roman numeral
sub decimalToRoman(num: uint16, buf: [uint8]): (rslt: [uint8]) is
# return the start of the buffer for easy printing
rslt := buf;
# Add string to buffer
sub Add(str: [uint8]) is
while [str] != 0 loop
[buf] := [str];
buf := @next buf;
str := @next str;
end loop;
end sub;
# Table of Roman numerals
record Roman is
value: uint16;
string: [uint8];
end record;
var numerals: Roman[] := {
{1000, "M"}, {900, "CM"}, {500, "D"}, {400, "CD"},
{100, "C"}, {90, "XC"}, {50, "L"}, {40, "XL"},
{10, "X"}, {9, "IX"}, {5, "V"}, {4, "IV"},
{1, "I"}
};
var curNum := &numerals as [Roman];
while num != 0 loop
while num >= curNum.value loop
Add(curNum.string);
num := num - curNum.value;
end loop;
curNum := @next curNum;
end loop;
[buf] := 0; # terminate the string
end sub;
# Read numbers from the command line and print the corresponding Roman numerals
ArgvInit();
var buffer: uint8[100];
loop
var argmt := ArgvNext();
if argmt == (0 as [uint8]) then
break;
end if;
var dummy: [uint8];
var number: int32;
(number, dummy) := AToI(argmt);
print(decimalToRoman(number as uint16, &buffer as [uint8]));
print_nl();
end loop;