6 let rec iterPairs
f = function
7 | Pair(first
, second
, t
) ->
11 | _ -> raise
<| Error.errExpectedX
"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) |> makeList
16 | Vector(_, seg
) -> seg
|> Seq.map
(eval
env) |> Array.ofSeq
|> Node.ofArray
17 | Map(_, map
) -> map
|> Map.map
(fun k v
-> eval
env v
) |> makeMap
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 outer
= function
39 let inner = Env.makeNew outer
[] []
40 let binder = setBinding
inner
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 -> falseForm
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
) ->
80 let inner, form = letStarForm
env rest
82 | List(_, Symbol("if")::rest
) -> ifForm
env rest
|> eval
env
83 | List(_, Symbol("do")::rest
) -> doForm
env rest
|> eval
env
84 | List(_, Symbol("fn*")::rest
) -> fnStarForm
env rest
85 | List(_, _) as node ->
86 let resolved = node |> eval_ast
env
88 | List(_, BuiltInFunc(_, _, f)::rest
) -> f rest
89 | List(_, Func(_, _, _, body, binds
, outer)::rest
) ->
90 let inner = Env.makeNew
outer binds
rest
92 | _ -> raise
<| Error.errExpectedX
"func"
93 | node -> node |> eval_ast
env
99 | Error.ReaderError(msg
) ->
107 | Error.EvalError(msg
)
108 | Error.ReaderError(msg
) ->
121 |> Seq.choose
(fun form -> EVAL env form)
126 |> Seq.iter
(fun value
-> PRINT value
)
128 let getReadlineMode args
=
129 if args
|> Array.exists
(fun e
-> e
= "--raw") then
132 Readline.Mode.Terminal
136 let mode = getReadlineMode args
137 let env = Env.makeRootEnv
()
139 RE env "(def! not (fn* (a) (if a false true)))" |> Seq.iter ignore
142 match Readline.read
"user> " mode with