(*
*) 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; (**)