+(** interpreter for interp_var*)
+class interp_var =
+ object (self)
+ inherit interp_int as super
+ method interp (env : environment) code = match code with
+ | Ast.Leaf var -> env#get_val var
+ | Ast.Node [Ast.Leaf "%let"; Ast.Node[typ; Ast.Leaf var; data]; body] ->
+ let new_val = self#interp env data in
+ let _ = env#add_val var new_val in
+ self#interp env body
+
+ | _ -> super#interp env code
+end;;
+
+let prime_op = ["+"; "-"];;
+
+(** PASS1 : uniquify the variable*)
+let rec uniquify_var_pass ast (tbl : (string, int) Hashtbl.t) = match ast with
+ | Ast.Int x -> ast
+ | Ast.Leaf var -> Ast.Leaf (var ^ "." ^ (string_of_int(Hashtbl.find tbl var)))
+ | Ast.Node [Ast.Leaf "-" ; x] -> Ast.Node [Ast.Leaf "-"; uniquify_var_pass x tbl]
+
+
+ | Ast.Node [Ast.Leaf "%let"; Ast.Node[typ; Ast.Leaf var; data]; body] ->
+ let _ = if not(Hashtbl.mem tbl var) then
+ (Hashtbl.add tbl var 0) else
+ Hashtbl.replace tbl var ((Hashtbl.find tbl var)+1) in
+ let new_var = Ast.Leaf (var ^ "." ^(string_of_int(Hashtbl.find tbl var))) in
+ let rhs = uniquify_var_pass data tbl in
+ Ast.Node [Ast.Leaf "%let"; Ast.Node[typ; new_var; rhs];
+ uniquify_var_pass body tbl]
+ | Ast.Node [Ast.Leaf op ; lhs; rhs] -> if List.mem op prime_op then
+ Ast.Node [Ast.Leaf op ;
+ uniquify_var_pass lhs tbl;
+ uniquify_var_pass rhs tbl] else
+ Ast.Node [uniquify_var_pass (Ast.Leaf op) tbl;
+ uniquify_var_pass lhs tbl;
+ uniquify_var_pass rhs tbl]
+ | _ -> ast