(* A naive imperative language with for- and while-loops sestoft@dina.kvl.dk 2001-03-07 Run this by mosmlc -c Naivestore.sig Naivestore.sml cd imp mosml -I .. imp.sml run ex1; *) app load ["Int", "Naivestore"]; open Naivestore; datatype expr = CstI of int | Var of string | Prim of string * expr list fun eval e (sto : int naivesto) : int = case e of CstI i => i | Var x => get sto x | Prim(ope, [e1, e2]) => let val i1 = eval e1 sto val i2 = eval e2 sto in case ope of "*" => i1 * i2 | "+" => i1 + i2 | "-" => i1 - i2 | "==" => if i1 = i2 then 1 else 0 | "<" => if i1 < i2 then 1 else 0 | _ => raise Fail "unknown primitive" end | Prim _ => raise Fail "unknown primitive" datatype stmt = Asgn of string * expr | If of expr * stmt * stmt | Seq of stmt list | For of string * expr * expr * stmt | While of expr * stmt | Print of expr fun exec stmt (sto : int naivesto) : int naivesto = case stmt of Asgn(x, e) => set sto (x, eval e sto) | If(e1, stmt1, stmt2) => if eval e1 sto <> 0 then exec stmt1 sto else exec stmt2 sto | Seq stmts => let fun loop [] sto = sto | loop (s1::sr) sto = loop sr (exec s1 sto) in loop stmts sto end | For(x, estart, estop, stmt) => let val start = eval estart sto val stop = eval estop sto fun loop i stoi = if i <= stop then loop (i+1) (exec stmt (set stoi (x, i))) else stoi in loop start sto end | While(e, stmt) => let fun loop stoi = if eval e stoi <> 0 then loop (exec stmt stoi) else stoi in loop sto end | Print e => (print (Int.toString (eval e sto)); print "\n"; sto) fun run stmt = (exec stmt empty; ()) (* Example programs *) val ex1 = Seq[Asgn("sum", CstI 0), For("i", CstI 0, CstI 100, Asgn("sum", Prim("+", [Var "sum", Var "i"]))), Print (Var "sum")]; val ex2 = Seq[Asgn("i", CstI 1), Asgn("sum", CstI 0), While (Prim("<", [Var "sum", CstI 10000]), Seq[Print (Var "sum"), Asgn("sum", Prim("+", [Var "sum", Var "i"])), Asgn("i", Prim("+", [CstI 1, Var "i"]))]), Print (Var "i")];