5ae039a588a246822c7ae0b713598410aa9c79bb
5 let makeEmpty () = Env()
9 let accumulate (e
: Env) (k
, v
) = e
.Add(k
, v
); e
10 List.fold
accumulate env lst
12 let set (env : EnvChain) key node
=
14 | head::_
-> head.[key
] <- node
15 | _ -> raise
<| Error.noEnvironment
()
17 let rec find
(chain
: EnvChain) key
=
21 match env.TryGetValue(key
) with
23 | false, _ -> find rest
key
26 match find chain
key with
28 | None -> raise
<| Error.symbolNotFound
key
30 let private getNextValue
=
32 fun () -> System.Threading.Interlocked.Increment(counter)
34 let makeBuiltInFunc f
=
35 BuiltInFunc(Node.NIL, getNextValue
(), f
)
37 let makeFunc f body binds
env =
38 Func(Node.NIL, getNextValue
(), f
, body
, binds
, env)
40 let makeMacro f body binds
env =
41 Macro(Node.NIL, getNextValue
(), f
, body
, binds
, env)
44 let wrap name
f = name
, makeBuiltInFunc f
47 wrap "-" Core.subtract
48 wrap "*" Core.multiply
51 wrap "list?" Core.isList
52 wrap "empty?" Core.isEmpty
53 wrap "count" Core.count
59 wrap "pr-str" Core.pr_str
62 wrap "println" Core.println
63 wrap "read-string" Core.read_str
64 wrap "slurp" Core.slurp
66 wrap "concat" Core.concat
68 wrap "first" Core.first
70 wrap "throw" Core.throw
72 wrap "apply" Core.apply
73 wrap "nil?" (Core.isConst
Node.NIL)
74 wrap "true?" (Core.isConst
Node.TRUE)
75 wrap "false?" (Core.isConst
Node.FALSE)
76 wrap "symbol?" Core.isSymbol
77 wrap "symbol" Core.symbol
78 wrap "keyword?" Core.isKeyword
79 wrap "keyword" Core.keyword
80 wrap "sequential?" Core.isSequential
81 wrap "vector?" Core.isVector
82 wrap "vector" Core.vector
83 wrap "map?" Core.isMap
84 wrap "hash-map" Core.hashMap
85 wrap "assoc" Core.assoc
86 wrap "dissoc" Core.dissoc
88 wrap "contains?" Core.contains
91 wrap "atom" (Core.atom getNextValue
)
92 wrap "atom?" Core.isAtom
93 wrap "deref" Core.deref
94 wrap "reset!" Core.reset
95 wrap "swap!" Core.swap
98 wrap "with-meta" Core.withMeta
]
102 let makeNew outer symbols
nodes =
103 let env = (makeEmpty ())::outer
104 let rec loop symbols
nodes =
105 match symbols
, nodes with
106 | [Symbol("&"); Symbol(s
)], nodes ->
107 set env s
(Node.makeList
nodes)
109 | Symbol("&")::_, _ -> raise
<| Error.onlyOneSymbolAfterAmp
()
110 | Symbol(s
)::symbols
, n
::nodes ->
114 | _, [] -> raise
<| Error.notEnoughValues
()
115 | [], _ -> raise
<| Error.tooManyValues
()
116 | _, _ -> raise
<| Error.errExpectedX
"symbol"
119 (* Active Patterns to help with pattern matching nodes *)
120 let inline (|IsMacro|_|) env = function
121 | List(_, Symbol(sym
)::rest
) ->
122 match find
env sym
with
123 | Some(Macro(_, _, _, _, _, _) as m) -> Some(IsMacro m, rest
)