1310d812282f36d798c857a3c0c14b8f89d44ced
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(getNextValue
(), f
)
37 let makeFunc f body binds
env =
38 Func(getNextValue
(), f
, body
, binds
, env)
40 let makeMacro f body binds
env =
41 Macro(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
90 wrap "vals" Core.vals
]
94 let makeNew outer symbols
nodes =
95 let env = (makeEmpty ())::outer
96 let rec loop symbols
nodes =
97 match symbols
, nodes with
98 | [Symbol("&"); Symbol(s
)], nodes ->
99 set env s
(List nodes)
101 | Symbol("&")::_, _ -> raise
<| Error.onlyOneSymbolAfterAmp
()
102 | Symbol(s
)::symbols
, n
::nodes ->
106 | _, [] -> raise
<| Error.notEnoughValues
()
107 | [], _ -> raise
<| Error.tooManyValues
()
108 | _, _ -> raise
<| Error.errExpectedX
"symbol"
111 (* Active Patterns to help with pattern matching nodes *)
112 let inline (|IsMacro|_|) env = function
113 | List(Symbol(sym
)::rest
) ->
114 match find
env sym
with
115 | Some(Macro(_, _, _, _, _) as m) -> Some(IsMacro m, rest
)