fsharp: step 3: Improved Env to work with chains. Implemented the def! special form.
[jackhill/mal.git] / fsharp / eval.fs
CommitLineData
8f1ee487
PS
1module Eval
2
3 open Types
4
5 type Env = Map<string, Node>
6
6c47cf67 7 let errFuncExpected () = EvalError("expected function")
37bb752e
PS
8 let errNodeExpected () = EvalError("expected node")
9 let errSymbolExpected () = EvalError("expected symbol")
8f1ee487
PS
10
11 let rec eval_ast env = function
37bb752e 12 | Symbol(sym) -> Env.get env sym
8f1ee487
PS
13 | List(lst) -> lst |> List.map (eval env) |> List
14 | Vector(arr) -> arr |> Array.map (eval env) |> Vector
15 | Map(map) -> map |> Map.map (fun k v -> eval env v) |> Map
16 | node -> node
17
37bb752e
PS
18 and def env = function
19 | symb::node::[] ->
20 match symb with
21 | Symbol(sym) ->
22 let node = eval env node
23 Env.set env sym node
24 node
25 | _ -> raise <| errSymbolExpected ()
26 | _ -> raise <| Core.errArity ()
27
8f1ee487 28 and eval env = function
37bb752e 29 | List(Symbol("def!")::rest) -> def env rest
8f1ee487
PS
30 | List(_) as node ->
31 let resolved = node |> eval_ast env
32 match resolved with
33 | List(Func({F = f})::rest) -> f rest
6c47cf67 34 | _ -> raise <| errFuncExpected ()
8f1ee487 35 | node -> node |> eval_ast env