37ba56c2d62c065dd8f4932fb5f1b65469b9364e
6 type MutableList = System.Collections.Generic.List<Node>
7 let inline addToMutableList
(lst
:MutableList) item
= lst
.Add(item
); lst
9 let errExpectedButEOF tok
= ReaderError(sprintf
"Expected %s, got EOF" tok
)
10 let errInvalid () = ReaderError("Invalid token")
12 let quote = Symbol("quote")
13 let quasiquote = Symbol("quasiquote")
14 let unquote = Symbol("unquote")
15 let spliceUnquote = Symbol("splice-unquote")
16 let deref = Symbol("deref")
17 let withMeta = Symbol("with-meta")
19 let rec readForm
= function
20 | OpenParen::rest
-> readList
[] rest
21 | OpenBracket::rest
-> readVector
(MutableList()) rest
22 | OpenBrace::rest
-> readMap
[] rest
23 | SingleQuote::rest
-> wrapForm
quote rest
24 | Backtick::rest -> wrapForm
quasiquote rest
25 | Tilde::rest -> wrapForm
unquote rest
26 | SpliceUnquote::rest -> wrapForm
spliceUnquote rest
27 | At::rest -> wrapForm
deref rest
28 | Caret::rest -> readMeta
rest
29 | tokens -> readAtom
tokens
31 and wrapForm node
tokens =
32 match readForm
tokens with
33 | Some(form
), rest -> Some(List([node
; form
])), rest
34 | None, _
-> raise
<| errExpectedButEOF "form"
36 and readList
acc = function
37 | CloseParen::rest -> Some(List(acc |> List.rev
)), rest
38 | [] -> raise
<| errExpectedButEOF "')'"
40 match readForm
tokens with
41 | Some(form
), rest -> readList
(form
::acc) rest
42 | None, _
-> raise
<| errExpectedButEOF "')'"
44 and readVector
acc = function
45 | CloseBracket::rest -> Some(acc.ToArray() |> makeVector
), rest
46 | [] -> raise
<| errExpectedButEOF "']'"
48 match readForm
tokens with
49 | Some(form
), rest -> readVector
(addToMutableList
acc form
) rest
50 | None, _
-> raise
<| errExpectedButEOF "']'"
52 and readMap
acc = function
53 | CloseBrace::rest -> Some(Map(acc |> List.rev
|> Map.ofList
)), rest
54 | [] -> raise
<| errExpectedButEOF "'}'"
56 match readForm
tokens with
58 match readForm
rest with
59 | Some(v
), rest -> readMap
((key
, v
)::acc) rest
60 | None, _
-> raise
<| errExpectedButEOF "'}'"
61 | None, _
-> raise
<| errExpectedButEOF "'}'"
63 and readMeta
= function
65 let meta, rest = readMap
[] rest
66 match readForm
rest with
67 | Some(form
), rest -> Some(List([withMeta; form
; meta.Value])), rest
68 | None, _
-> raise
<| errExpectedButEOF "form"
69 | _ -> raise
<| errExpectedButEOF "map"
71 and readAtom
= function
72 | Token("nil")::rest -> SomeNIL, rest
73 | Token("true")::rest -> SomeTRUE, rest
74 | Token("false")::rest -> SomeFALSE, rest
75 | Tokenizer.String(str
)::rest -> Some(String(str
)), rest
76 | Tokenizer.Keyword(kw
)::rest -> Some(Keyword(kw
)), rest
77 | Tokenizer.Number(num
)::rest -> Some(Number(Int64.Parse(num
))), rest
78 | Token(sym
)::rest -> Some(Symbol(sym
)), rest
80 | _ -> raise
<| errInvalid ()
82 let rec readForms
acc = function
85 match readForm
tokens with
86 | Some(form
), rest -> readForms
(form
::acc) rest
87 | None, rest -> readForms
acc rest
90 tokenize
str |> readForms
[]