+module T = Types.Types
+
let repl_env = Env.make (Some Core.ns)
let rec eval_ast ast env =
match ast with
- | Types.Symbol s -> Env.get env ast
- | Types.MalList xs -> Types.MalList (List.map (fun x -> eval x env) xs)
+ | T.Symbol s -> Env.get env ast
+ | T.List { T.value = xs; T.meta = meta }
+ -> T.List { T.value = (List.map (fun x -> eval x env) xs);
+ T.meta = meta }
+ | T.Vector { T.value = xs; T.meta = meta }
+ -> T.Vector { T.value = (List.map (fun x -> eval x env) xs);
+ T.meta = meta }
+ | T.Map { T.value = xs; T.meta = meta }
+ -> T.Map {T.meta = meta;
+ T.value = (Types.MalMap.fold
+ (fun k v m
+ -> Types.MalMap.add (eval k env) (eval v env) m)
+ xs
+ Types.MalMap.empty)}
| _ -> ast
and eval ast env =
match ast with
- | Types.MalList [(Types.Symbol "def!"); key; expr] ->
+ | T.List { T.value = [] } -> ast
+ | T.List { T.value = [(T.Symbol { T.value = "def!" }); key; expr] } ->
let value = (eval expr env) in
Env.set env key value; value
- | Types.MalList [(Types.Symbol "let*"); (Types.MalList bindings); body] ->
+ | T.List { T.value = [(T.Symbol { T.value = "let*" }); (T.Vector { T.value = bindings }); body] }
+ | T.List { T.value = [(T.Symbol { T.value = "let*" }); (T.List { T.value = bindings }); body] } ->
(let sub_env = Env.make (Some env) in
let rec bind_pairs = (function
| sym :: expr :: more ->
| [] -> ())
in bind_pairs bindings;
eval body sub_env)
- | Types.MalList ((Types.Symbol "do") :: body) ->
- List.fold_left (fun x expr -> eval expr env) Types.Nil body
- | Types.MalList [Types.Symbol "if"; test; then_expr; else_expr] ->
+ | T.List { T.value = ((T.Symbol { T.value = "do" }) :: body) } ->
+ List.fold_left (fun x expr -> eval expr env) T.Nil body
+ | T.List { T.value = [T.Symbol { T.value = "if" }; test; then_expr; else_expr] } ->
if Types.to_bool (eval test env) then (eval then_expr env) else (eval else_expr env)
- | Types.MalList [Types.Symbol "if"; test; then_expr] ->
- if Types.to_bool (eval test env) then (eval then_expr env) else Types.Nil
- | Types.MalList [Types.Symbol "fn*"; Types.MalList arg_names; expr] ->
- Types.Fn
+ | T.List { T.value = [T.Symbol { T.value = "if" }; test; then_expr] } ->
+ if Types.to_bool (eval test env) then (eval then_expr env) else T.Nil
+ | T.List { T.value = [T.Symbol { T.value = "fn*" }; T.Vector { T.value = arg_names }; expr] }
+ | T.List { T.value = [T.Symbol { T.value = "fn*" }; T.List { T.value = arg_names }; expr] } ->
+ Types.fn
(function args ->
let sub_env = Env.make (Some env) in
let rec bind_args a b =
(match a, b with
- | [Types.Symbol "&"; name], args -> Env.set sub_env name (Types.MalList args);
+ | [T.Symbol { T.value = "&" }; name], args -> Env.set sub_env name (Types.list args);
| (name :: names), (arg :: args) ->
Env.set sub_env name arg;
bind_args names args;
| _ -> raise (Invalid_argument "Bad param count in fn call"))
in bind_args arg_names args;
eval expr sub_env)
- | Types.MalList _ ->
+ | T.List _ ->
(match eval_ast ast env with
- | Types.MalList ((Types.Fn f) :: args) -> f args
+ | T.List { T.value = ((T.Fn { T.value = f }) :: args) } -> f args
| _ -> raise (Invalid_argument "Cannot invoke non-function"))
| _ -> eval_ast ast env