8 let compare (Types.Symbol a) (Types.Symbol b) = compare a b
12 let num_fun f
= Types.fn
14 | [(T.Int a
); (T.Int b
)] -> T.Int
(f a b
)
15 | _
-> raise
(Invalid_argument
"Numeric args required for this Mal builtin"))
17 let repl_env = ref (List.fold_left
(fun a b
-> b a
) Env.empty
18 [ Env.add
"+" (num_fun ( + ));
19 Env.add
"-" (num_fun ( - ));
20 Env.add
"*" (num_fun ( * ));
21 Env.add
"/" (num_fun ( / )) ])
23 let rec eval_ast ast env
=
25 | T.Symbol
{ T.value = s
} ->
27 with Not_found
-> raise
(Invalid_argument
("Symbol '" ^ s ^
"' not found")))
28 | T.List
{ T.value = xs
; T.meta
= meta
}
29 -> T.List
{ T.value = (List.map
(fun x
-> eval x env
) xs
);
31 | T.Vector
{ T.value = xs
; T.meta
= meta
}
32 -> T.Vector
{ T.value = (List.map
(fun x
-> eval x env
) xs
);
34 | T.Map
{ T.value = xs
; T.meta
= meta
}
35 -> T.Map
{T.meta
= meta
;
36 T.value = (Types.MalMap.fold
38 -> Types.MalMap.add
(eval k env
) (eval v env
) m
)
43 let result = eval_ast ast env
in
45 | T.List
{ T.value = ((T.Fn
{ T.value = f
}) :: args
) } -> (f args
)
48 let read str
= Reader.read_str str
49 let print exp
= Printer.pr_str exp
true
50 let rep str env
= print (eval
(read str
) env
)
55 print_string
"user> ";
56 let line = read_line
() in
58 print_endline
(rep line repl_env);
59 with End_of_file
-> ()
60 | Invalid_argument x
->
61 output_string stderr
("Invalid_argument exception: " ^ x ^
"\n");
64 with End_of_file
-> ()