(*
*)
val int2Str = Int.toString;
val tempCtr = ref 0;
fun newtemp () =
let val n = !tempCtr
in (tempCtr := n+1; int2Str n ) end;
(* ************************************ *)
datatype exp
= Plus of exp * exp
| Times of exp * exp
| Num of int
| Var of string
| Assign of string * exp
;
fun mean x =
case x of
Plus(x,y) => (mean x) + (mean y)
| Times(x,y) => (mean x) * (mean y)
| Num n => n
(* *************************************** *)
fun mean2 x =
case x of
Plus(x,y) =>
let val (namex,codex) = (mean2 x)
val (namey,codey) = (mean2 y)
val new = newtemp()
in (new, codex ^ codey ^
(new ^ " = " ^namex ^ " + " ^ namey))
end
| Times(x,y) =>
let val (namex,codex) = (mean2 x)
val (namey,codey) = (mean2 y)
val new = newtemp()
in (new, codex ^ codey ^
(new ^ " = " ^namex ^ " * " ^ namey))
end
| Num n => let val new = newtemp()
in (new, new ^" = "^(int2Str n)) end
(* *************************************** *)
exception NoSuchVar of string;
fun mean3 x env =
case x of
Var s =>
(case List.find (fn (x,v) => x=s) env of
NONE => raise (NoSuchVar s)
| SOME(_,v) => v)
| Plus(x,y) => (mean3 x) env + (mean3 y) env
| Times(x,y) => (mean3 x) env * (mean3 y) env
| Num n => n
(* ************************************* *)
fun update [] var value = [(var,value)]
| update ((s,v)::xs) var value =
if s=var then (s,value)::xs
else (s,v)::(update xs var value);
fun mean4 x env =
case x of
Var s =>
(case List.find (fn (x,v) => x=s) env of
NONE => raise (NoSuchVar s)
| SOME(_,v) => (env,v))
| Plus(x,y) =>
let val (env2,x') = (mean4 x) env
val (env3,y') = (mean4 y) env2
in (env3,x' + y') end
| Times(x,y) =>
let val (env2,x') = (mean4 x) env
val (env3,y') = (mean4 y) env2
in (env3,x' * y') end
| Num n => (env,n)
| Assign(x,exp) =>
let val (env2,exp') = (mean4 exp) env
in (update env x exp',exp') end;
(* *)