roman = cluster is decode rep = null digit_value = proc (c: char) returns (int) signals (invalid) if c < 'a' then c := char$i2c(char$c2i(c) + 32) end if c = 'm' then return(1000) elseif c = 'd' then return(500) elseif c = 'c' then return(100) elseif c = 'l' then return(50) elseif c = 'x' then return(10) elseif c = 'v' then return(5) elseif c = 'i' then return(1) else signal invalid end end digit_value decode = proc (s: string) returns (int) signals (invalid) acc: int := 0 for i: int in int$from_to(1, string$size(s)) do d: int := digit_value(s[i]) if i < string$size(s) cand d < digit_value(s[i+1]) then acc := acc - d else acc := acc + d end end resignal invalid return(acc) end decode end roman start_up = proc () po: stream := stream$primary_output() tests: array[string] := array[string]$ ["MCMXC", "mdclxvi", "MmViI", "mmXXi", "INVALID"] for test: string in array[string]$elements(tests) do stream$puts(po, test || ": ") stream$putl(po, int$unparse(roman$decode(test))) except when invalid: stream$putl(po, "not a valid Roman numeral!") end end end start_up