ML RPN Solution
This solution was written by David MacQueen. The code can be found in ~jalewis/451/ml/rpn.sml. It does not handle all the requirements of the assignment, such as reading multiple lines from a file or handling errors.
(* polish.sml *)
structure RevPolish : sig val execute : unit -> int end =
struct
datatype token = INT of int | PLUS | MINUS | TIMES | MOD | DIV
exception ERROR of string
fun error s = raise (ERROR s)
fun token s =
if Char.isDigit(String.sub(s,0)) orelse
(String.sub(s,0) = #"~")
then case Int.fromString s
of SOME n => INT n
| NONE => error ("bad token "^s)
else case s
of "+" => PLUS
| "-" => MINUS
| "*" => TIMES
| "DIV" => DIV
| "MOD" => MOD
| _ => error ("bad token "^s);
fun getStrings () : string list =
String.tokens Char.isSpace (TextIO.inputLine TextIO.stdIn)
fun getTokens () =
map token (getStrings())
fun interp (nil: token list, [n]: int list) = n
| interp ((INT n)::rest,s) = interp(rest,n::s)
| interp (PLUS::rest,m::n::s) = interp(rest,m+n::s)
| interp (MINUS::rest,m::n::s) = interp(rest,m-n::s)
| interp (TIMES::rest,m::n::s) = interp(rest,m*n::s)
| interp (DIV::rest,m::n::s) = interp(rest,m div n::s)
| interp (MOD::rest,m::n::s) = interp(rest,m mod n::s)
| interp _ = error "bad expression"
fun execute () =
interp(getTokens(),nil)
handle ERROR s => (print (s^"\n"); 0)
end (* structure RevPolish *)