6 let compare (Types.Symbol a) (Types.Symbol b) = compare a b
10 let num_fun f
= Types.Fn
12 | [(Types.Int a
); (Types.Int b
)] -> Types.Int
(f a b
)
13 | _
-> raise
(Invalid_argument
"Numeric args required for this Mal builtin"))
15 let repl_env = ref (List.fold_left
(fun a b
-> b a
) Env.empty
16 [ Env.add
"+" (num_fun ( + ));
17 Env.add
"-" (num_fun ( - ));
18 Env.add
"*" (num_fun ( * ));
19 Env.add
"/" (num_fun ( / )) ])
21 let rec eval_ast ast env
=
25 with Not_found
-> raise
(Invalid_argument
("Symbol '" ^ s ^
"' not found")))
26 | Types.MalList xs
-> Types.MalList
(List.map
(fun x
-> eval x env
) xs
)
29 let result = eval_ast ast env
in
31 | Types.MalList
((Types.Fn f
) :: args
) -> (f args
)
34 let read str
= Reader.read_str str
35 let print exp
= Printer.pr_str exp
true
36 let rep str env
= print (eval
(read str
) env
)
41 print_string
"user> ";
42 let line = read_line
() in
44 print_endline
(rep line repl_env);
45 with End_of_file
-> ()
46 | Invalid_argument x
->
47 output_string stderr
("Invalid_argument exception: " ^ x ^
"\n");
50 with End_of_file
-> ()