mirror of
https://github.com/kanaka/mal.git
synced 2024-09-20 01:57:09 +03:00
Ocaml: All optional tests passing up thru step 4
This commit is contained in:
parent
e64878d0af
commit
04e33074cc
@ -27,7 +27,11 @@ let init env = begin
|
||||
Env.set env (Types.symbol "count")
|
||||
(T.Fn (function [T.List {T.value = xs}] -> T.Int (List.length xs) | _ -> T.Int 0));
|
||||
Env.set env (Types.symbol "=")
|
||||
(T.Fn (function [a; b] -> T.Bool (a = b) | _ -> T.Bool false));
|
||||
(T.Fn (function
|
||||
| [T.List a; T.Vector b] -> T.Bool (a = b)
|
||||
| [T.Vector a; T.List b] -> T.Bool (a = b)
|
||||
| [a; b] -> T.Bool (a = b)
|
||||
| _ -> T.Bool false));
|
||||
|
||||
Env.set env (Types.symbol "pr-str")
|
||||
(T.Fn (function xs ->
|
||||
|
@ -69,7 +69,9 @@ and read_form all_tokens =
|
||||
| "^" ->
|
||||
let meta = read_form tokens in
|
||||
let value = read_form meta.tokens in
|
||||
{form = with_meta value.form meta.form; tokens = value.tokens}
|
||||
{(*form = with_meta value.form meta.form;*)
|
||||
form = Types.list [Types.symbol "with-meta"; value.form; meta.form];
|
||||
tokens = value.tokens}
|
||||
| "(" ->
|
||||
let list_reader = read_list {list_form = []; tokens = tokens} in
|
||||
{form = Types.list list_reader.list_form;
|
||||
|
@ -23,9 +23,19 @@ let repl_env = ref (List.fold_left (fun a b -> b a) Env.empty
|
||||
let rec eval_ast ast env =
|
||||
match ast with
|
||||
| T.Symbol { T.value = s } ->
|
||||
(try Env.find s !env
|
||||
with Not_found -> raise (Invalid_argument ("Symbol '" ^ s ^ "' not found")))
|
||||
| T.List { T.value = xs } -> Types.list (List.map (fun x -> eval x env) xs)
|
||||
(try Env.find s !env
|
||||
with Not_found -> raise (Invalid_argument ("Symbol '" ^ s ^ "' not found")))
|
||||
| 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 =
|
||||
let result = eval_ast ast env in
|
||||
|
@ -17,14 +17,25 @@ end
|
||||
let rec eval_ast ast env =
|
||||
match ast with
|
||||
| T.Symbol s -> Env.get env ast
|
||||
| T.List { T.value = xs } -> Types.list (List.map (fun x -> eval x env) xs)
|
||||
| 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
|
||||
| T.List { T.value = [(T.Symbol { T.value = "def!" }); key; expr] } ->
|
||||
let value = (eval expr env) in
|
||||
Env.set env key value; value
|
||||
| T.List { T.value = [(T.Symbol { T.value = "let*" }); (T.List { T.value = 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 ->
|
||||
|
@ -5,14 +5,25 @@ let repl_env = Env.make (Some Core.ns)
|
||||
let rec eval_ast ast env =
|
||||
match ast with
|
||||
| T.Symbol s -> Env.get env ast
|
||||
| T.List { T.value = xs } -> Types.list (List.map (fun x -> eval x env) xs)
|
||||
| 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
|
||||
| T.List { T.value = [(T.Symbol { T.value = "def!" }); key; expr] } ->
|
||||
let value = (eval expr env) in
|
||||
Env.set env key value; value
|
||||
| T.List { T.value = [(T.Symbol { T.value = "let*" }); (T.List { T.value = 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 ->
|
||||
@ -28,7 +39,8 @@ and eval ast env =
|
||||
if Types.to_bool (eval test env) then (eval then_expr env) else (eval else_expr env)
|
||||
| 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.List { T.value = arg_names }; expr] } ->
|
||||
| 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] } ->
|
||||
T.Fn
|
||||
(function args ->
|
||||
let sub_env = Env.make (Some env) in
|
||||
|
Loading…
Reference in New Issue
Block a user