7 type MutableList = System.Collections.Generic.List<Node>
8 let inline addToMutableList
(lst
:MutableList) item
= lst
.Add(item
); lst
10 let quote = Symbol("quote")
11 let quasiquote = Symbol("quasiquote")
12 let unquote = Symbol("unquote")
13 let spliceUnquote = Symbol("splice-unquote")
14 let deref = Symbol("deref")
15 let withMeta = Symbol("with-meta")
17 let rec readForm
= function
18 | OpenParen::rest
-> readList
[] rest
19 | OpenBracket::rest
-> readVector
(MutableList()) rest
20 | OpenBrace::rest
-> readMap
[] rest
21 | SingleQuote::rest
-> wrapForm
quote rest
22 | Backtick::rest -> wrapForm
quasiquote rest
23 | Tilde::rest -> wrapForm
unquote rest
24 | SpliceUnquote::rest -> wrapForm
spliceUnquote rest
25 | At::rest -> wrapForm
deref rest
26 | Caret::rest -> readMeta
rest
27 | tokens -> readAtom
tokens
29 and wrapForm node
tokens =
30 match readForm
tokens with
31 | Some(form
), rest -> Some(makeList
[node
; form
]), rest
32 | None, _
-> raise
<| Error.expectedXButEOF
"form"
34 and readList
acc = function
35 | CloseParen::rest -> Some(acc |> List.rev
|> makeList
), rest
36 | [] -> raise
<| Error.expectedXButEOF
"')'"
38 match readForm
tokens with
39 | Some(form
), rest -> readList
(form
::acc) rest
40 | None, _
-> raise
<| Error.expectedXButEOF
"')'"
42 and readVector
acc = function
43 | CloseBracket::rest -> Some(acc.ToArray() |> Node.ofArray
), rest
44 | [] -> raise
<| Error.expectedXButEOF
"']'"
46 match readForm
tokens with
47 | Some(form
), rest -> readVector
(addToMutableList
acc form
) rest
48 | None, _
-> raise
<| Error.expectedXButEOF
"']'"
50 and readMap
acc = function
51 | CloseBrace::rest -> Some(acc |> List.rev
|> Map.ofList
|> makeMap
), rest
52 | [] -> raise
<| Error.expectedXButEOF
"'}'"
54 match readForm
tokens with
56 match readForm
rest with
57 | Some(v
), rest -> readMap
((key
, v
)::acc) rest
58 | None, _
-> raise
<| Error.expectedXButEOF
"'}'"
59 | None, _
-> raise
<| Error.expectedXButEOF
"'}'"
61 and readMeta
= function
63 let meta, rest = readMap
[] rest
64 match readForm
rest with
65 | Some(form
), rest -> Some([withMeta; form
; meta.Value] |> makeList
), rest
66 | None, _
-> raise
<| Error.expectedXButEOF
"form"
67 | _ -> raise
<| Error.expectedXButEOF
"map"
69 and readAtom
= function
70 | Token("nil")::rest -> Node.SomeNIL, rest
71 | Token("true")::rest -> Node.SomeTRUE, rest
72 | Token("false")::rest -> Node.SomeFALSE, rest
73 | Tokenizer.String(str
)::rest -> Some(String(str
)), rest
74 | Tokenizer.Keyword(kw
)::rest -> Some(Keyword(kw
)), rest
75 | Tokenizer.Number(num
)::rest -> Some(Number(Int64.Parse(num
))), rest
76 | Token(sym
)::rest -> Some(Symbol(sym
)), rest
78 | _ -> raise
<| Error.invalidToken
()
80 let rec readForms
acc = function
83 match readForm
tokens with
84 | Some(form
), rest -> readForms
(form
::acc) rest
85 | None, rest -> readForms
acc rest
88 tokenize
str |> readForms
[]