6 let rec iterPairs
f = function
7 | Pair(first
, second
, t
) ->
11 | _ -> raise
<| Error.expectedX
"list or vector"
13 let rec eval_ast
env = function
14 | Symbol(sym
) -> Env.get
env sym
15 | List(lst
) -> lst
|> List.map
(eval
env) |> List
16 | Vector(seg
) -> seg
|> Seq.map
(eval
env) |> Array.ofSeq
|> Node.ofArray
17 | Map(map
) -> map
|> Map.map
(fun k v
-> eval
env v
) |> Map
20 and defBangForm
env = function
24 let node = eval
env form
27 | _ -> raise
<| Error.errExpectedX
"symbol"
28 | _ -> raise
<| Error.wrongArity
()
30 and setBinding
env first
second =
31 let s = match first
with
33 | _ -> raise
<| Error.errExpectedX
"symbol"
34 let form = eval
env second
37 and letStarForm
env = function
39 let newEnv = Env.makeNew
env [] []
40 let binder = setBinding
newEnv
42 | List(_) | Vector(_) -> iterPairs
binder bindings
43 | _ -> raise
<| Error.errExpectedX
"list or vector"
45 | _ -> raise
<| Error.wrongArity
()
47 and ifForm
env = function
48 | [condForm
; trueForm
; falseForm
] -> ifForm3
env condForm trueForm falseForm
49 | [condForm
; trueForm
] -> ifForm3
env condForm trueForm
Nil
50 | _ -> raise
<| Error.wrongArity
()
52 and ifForm3
env condForm trueForm falseForm
=
53 match eval
env condForm
with
54 | Bool(false) | Nil -> eval
env falseForm
55 | _ -> eval
env trueForm
57 and doForm
env = function
62 | _ -> raise
<| Error.wrongArity
()
64 and fnStarForm outer nodes
=
65 let makeFunc binds
body =
67 let inner = Env.makeNew outer binds
nodes
69 Env.makeFunc f body binds
outer
72 | [List(binds
); body] -> makeFunc binds
body
73 | [Vector(seg
); body] -> makeFunc (List.ofSeq seg
) body
74 | [_; _] -> raise
<| Error.errExpectedX
"bindings of list or vector"
75 | _ -> raise
<| Error.wrongArity
()
77 and eval
env = function
78 | List(Symbol("def!")::rest
) -> defBangForm
env rest
79 | List(Symbol("let*")::rest
) -> letStarForm
env rest
80 | List(Symbol("if")::rest
) -> ifForm
env rest
81 | List(Symbol("do")::rest
) -> doForm
env rest
82 | List(Symbol("fn*")::rest
) -> fnStarForm
env rest
84 let resolved = node |> eval_ast
env
86 | List(Func(_, f, _, _, [])::rest
) -> f rest
87 | List(Func(_, _, body, binds
, outer)::rest
) ->
88 let inner = Env.makeNew
outer binds
rest
90 | _ -> raise
<| Error.errExpectedX
"function"
91 | node -> node |> eval_ast
env
97 | Error.ReaderError(msg
) ->
105 | Error.EvalError(msg
)
106 | Error.ReaderError(msg
) ->
119 |> Seq.choose
(fun form -> EVAL env form)
124 |> Seq.iter
(fun value
-> PRINT value
)
126 let getReadlineMode (args
: string array
) =
127 if args
.Length > 0 && args
.[0] = "--raw" then
130 Readline.Mode.Terminal
134 let mode = getReadlineMode args
135 let env = Env.makeRootEnv
()
137 RE env "(def! not (fn* (a) (if a false true)))" |> Seq.iter ignore
140 match Readline.read
"user> " mode with