Task

Create a function that takes a Roman numeral as its argument and returns its value as a numeric decimal integer.

You don't need to validate the form of the Roman numeral.

Modern Roman numerals are written by expressing each decimal digit of the number to be encoded separately,

starting with the leftmost decimal digit and skipping any 0s   (zeroes).

1990 is rendered as   MCMXC     (1000 = M,   900 = CM,   90 = XC)     and

2008 is rendered as   MMVIII       (2000 = MM,   8 = VIII).

The Roman numeral for 1666,   MDCLXVI,   uses each letter in descending order.




; Roman numeral decoder
 
; First, some useful substring utilities
to starts_with? :string :prefix
  if empty? :prefix [output "true]
  if empty? :string [output "false]
  if not equal? first :string first :prefix [output "false]
  output starts_with? butfirst :string butfirst :prefix
end
 
to remove_prefix :string :prefix 
  if or empty? :prefix not starts_with? :string :prefix [output :string]
  output remove_prefix butfirst :string butfirst :prefix
end
 
; Our list of Roman numeral values
make "values [[M 1000] [CM 900] [D  500] [CD 400] [C  100] [XC 90] [L 50]
              [XL 40]  [X  10]  [IX 9]   [V  5]   [IV 4]   [I  1]]
 
; Function to do the work
to from_roman :str
 local "n make "n 0
 foreach :values [
   local "s make "s first ?
   local "v make "v last ?
   while [starts_with? :str :s] [
     make "n sum n :v
     make "str remove_prefix :str :s
   ]
 ]
 output :n
end
 
foreach [MCMXC MDCLXVI MMVIII] [print (sentence (word ? "|: |) from_roman ?)]
bye