@@ -4,15 +4,17 @@ exception Cant_happen;
44exception Not_found;
55exception Bad_key;
66
7+ Control.Print.stringDepth := 9999 ;
8+
79datatype sexp_i =
810 TRUE_I
911 (* No dotted lists. Because fuck you, that's why. *)
1012 | LIST_I of sdata list
1113 | NUM_I of int
1214 | SYM_I of string
1315 | GENSYM_I of int
14- | FUNC_I of (map * sdata list * sexp_i) (* localenv * params * body; only in VAL, never in EXP *)
15- | PRIM_I of (context -> sdata list -> (context * sdata))
16+ | FUNC_I of (sexp_i * map * sdata list * sexp_i) (* name * localenv * params * body; only in VAL, never in EXP *)
17+ | PRIM_I of (string * ( context -> sdata list -> (context * sdata) ))
1618and sdata = EXP of sexp_i
1719 | VAL of sexp_i
1820and key = SYM_K of string | GENSYM_K of int
@@ -26,6 +28,31 @@ datatype input_sexp =
2628 | NUM of int
2729 | SYM of string
2830
31+
32+ fun sdata_to_string (VAL x) = " (# " ^ (sexp_i_to_string x) ^ " #)"
33+ | sdata_to_string (EXP x) = (sexp_i_to_string x)
34+ and sexp_i_to_string TRUE_I = " true"
35+ | sexp_i_to_string (NUM_I n) = Int.toString n
36+ | sexp_i_to_string (SYM_I s) = s
37+ | sexp_i_to_string (GENSYM_I n) = " <gensym " ^ (Int.toString n) ^ " >"
38+ | sexp_i_to_string (FUNC_I (name, _, _, _)) = " <function " ^ (sexp_i_to_string name) ^ " >"
39+ | sexp_i_to_string (PRIM_I (name, _)) = " <primitive function " ^ name ^ " >"
40+ | sexp_i_to_string (LIST_I l) = " (" ^ (sexp_i_list_to_string l)
41+ and sexp_i_list_to_string [] = " )"
42+ | sexp_i_list_to_string (x::xs) = (sdata_to_string x) ^ " " ^ (sexp_i_list_to_string xs)
43+
44+ and ctx_to_string ((globalenv, localenv), heap, ctr) =
45+ (map_to_string localenv) ^ " ; " ^
46+ (map_to_string globalenv) ^ " ; " ^
47+ (map_to_string heap) ^ " ; " ^ (Int.toString ctr)
48+ and map_to_string [] = " "
49+ | map_to_string ((k, v) :: rest) = (key_to_string k) ^ " ->" ^
50+ (sexp_i_to_string v) ^ " , " ^
51+ (map_to_string rest)
52+ and key_to_string (SYM_K s) = s
53+ | key_to_string (GENSYM_K i) = " <gensym " ^ (Int.toString i) ^ " >"
54+
55+
2956fun to_sdata TRUE = EXP TRUE_I
3057 | to_sdata (NUM n) = EXP (NUM_I n)
3158 | to_sdata (SYM s) = EXP (SYM_I s)
@@ -121,8 +148,8 @@ fun bind_or_set_env env heap ctr name value =
121148 | NONE => bind_env env heap ctr name value
122149
123150(* do_lambda : ctx -> sdata list -> sexp_i -> val sdata *)
124- fun do_lambda ((globalenv, localenv), heap, ctr) params body =
125- VAL (FUNC_I (localenv, params, LIST_I ( (EXP (SYM_I " progn" )) :: body )));
151+ fun do_lambda name ((globalenv, localenv), heap, ctr) params body =
152+ VAL (FUNC_I (name, localenv, params, LIST_I ( (EXP (SYM_I " progn" )) :: body )));
126153
127154(* do_define : ctx -> sexp_i -> sexp_i -> ctx *)
128155fun do_define ((globalenv, localenv), heap, ctr) name value =
@@ -135,7 +162,7 @@ fun do_define ((globalenv, localenv), heap, ctr) name value =
135162(* do_define_func : ctx -> sexp_i -> sexp_i -> ctx *)
136163(* No backpatching required due to dynamic global scope! *)
137164fun do_define_func ctx name params body = let
138- val VAL f = do_lambda ctx params body
165+ val VAL f = do_lambda name ctx params body
139166 in do_define ctx name f end
140167
141168(* bind_params : ctx -> (exp sdata) list -> (val sdata) list -> ctx *)
@@ -145,8 +172,8 @@ fun bind_params ctx [] [] = ctx
145172 in bind_params ((globalenv, localenv'), heap', ctr') params args end
146173
147174(* do_apply : ctx -> (prim | func) sexp_i -> (val sdata) list -> (ctx * sdata) *)
148- fun do_apply ctx (PRIM_I f ) args = f ctx args
149- | do_apply ((globalenv, localenv), heap, ctr) (FUNC_I (closureenv, params, body)) args =
175+ fun do_apply ctx (PRIM_I (_, f) ) args = f ctx args
176+ | do_apply ((globalenv, localenv), heap, ctr) (FUNC_I (_, closureenv, params, body)) args =
150177 let val ctx' = bind_params ((globalenv, closureenv), heap, ctr) params args
151178 in (ctx', EXP body) end
152179
@@ -178,7 +205,7 @@ and smallstep ctx (VAL x) = raise Already_done
178205 (ctx, (EXP (LIST_I ((EXP (SYM_I " progn" )) :: xs))))
179206
180207 | smallstep ctx (EXP (LIST_I ((EXP (SYM_I " lambda" )) :: (EXP (LIST_I params)) :: body))) =
181- (ctx, do_lambda ctx params body)
208+ (ctx, do_lambda (SYM_I " *anonymous closure* " ) ctx params body)
182209
183210 | smallstep ctx (EXP (LIST_I [EXP (SYM_I " define" ), EXP (SYM_I name), EXP value])) =
184211 let val (ctx', result) = (smallstep ctx (EXP value)) in
@@ -226,7 +253,7 @@ fun prim_set ctx [VAL a, VAL b] = (env_set ctx a b, VAL b)
226253
227254val init_ctx =
228255 let
229- fun defprim (env, heap, ctr) k v = bind_env env heap ctr (SYM_I k) (PRIM_I v )
256+ fun defprim (env, heap, ctr) k v = bind_env env heap ctr (SYM_I k) (PRIM_I (k, v) )
230257 val ctx = ([], [], 0 )
231258 val ctx = defprim ctx " car" prim_car
232259 val ctx = defprim ctx " cdr" prim_cdr
@@ -239,10 +266,14 @@ val init_ctx =
239266 end
240267
241268(* eval : ctx -> exp sdata -> val sdata *)
242- fun eval ctx x =
243- case smallstep ctx x of
244- (_, VAL v) => VAL v
245- | (_, EXP e) => eval ctx (EXP e)
269+ fun eval ctx x =
270+ let
271+ val _ = print (" EVAL: " ^ (sdata_to_string x) ^ " --- IN: " ^ (ctx_to_string ctx) ^ " \n " )
272+ in
273+ case smallstep ctx x of
274+ (_, VAL v) => VAL v
275+ | (_, EXP e) => eval ctx (EXP e)
276+ end
246277
247278(* Sample program: factorial
248279
0 commit comments