fun () -> System.Threading.Interlocked.Increment(counter)
let makeBuiltInFunc f =
- Func(getNextValue (), f, Node.NIL, [], [])
+ BuiltInFunc(Node.NIL, getNextValue (), f)
let makeFunc f body binds env =
- Func(getNextValue (), f, body, binds, env)
+ Func(Node.NIL, getNextValue (), f, body, binds, env)
+
+ let makeMacro f body binds env =
+ Macro(Node.NIL, getNextValue (), f, body, binds, env)
let makeRootEnv () =
let wrap name f = name, makeBuiltInFunc f
wrap "read-string" Core.read_str
wrap "slurp" Core.slurp
wrap "cons" Core.cons
- wrap "concat" Core.concat ]
+ wrap "concat" Core.concat
+ wrap "nth" Core.nth
+ wrap "first" Core.first
+ wrap "rest" Core.rest
+ wrap "throw" Core.throw
+ wrap "map" Core.map
+ wrap "apply" Core.apply
+ wrap "nil?" (Core.isConst Node.NIL)
+ wrap "true?" (Core.isConst Node.TRUE)
+ wrap "false?" (Core.isConst Node.FALSE)
+ wrap "symbol?" Core.isSymbol
+ wrap "symbol" Core.symbol
+ wrap "keyword?" Core.isKeyword
+ wrap "keyword" Core.keyword
+ wrap "sequential?" Core.isSequential
+ wrap "vector?" Core.isVector
+ wrap "vector" Core.vector
+ wrap "map?" Core.isMap
+ wrap "hash-map" Core.hashMap
+ wrap "assoc" Core.assoc
+ wrap "dissoc" Core.dissoc
+ wrap "get" Core.get
+ wrap "contains?" Core.contains
+ wrap "keys" Core.keys
+ wrap "vals" Core.vals
+ wrap "atom" (Core.atom getNextValue)
+ wrap "atom?" Core.isAtom
+ wrap "deref" Core.deref
+ wrap "reset!" Core.reset
+ wrap "swap!" Core.swap
+ wrap "conj" Core.conj
+ wrap "meta" Core.meta
+ wrap "with-meta" Core.withMeta ]
|> ofList
[ env ]
let rec loop symbols nodes =
match symbols, nodes with
| [Symbol("&"); Symbol(s)], nodes ->
- set env s (List nodes)
+ set env s (Node.makeList nodes)
env
| Symbol("&")::_, _ -> raise <| Error.onlyOneSymbolAfterAmp ()
| Symbol(s)::symbols, n::nodes ->
| [], _ -> raise <| Error.tooManyValues ()
| _, _ -> raise <| Error.errExpectedX "symbol"
loop symbols nodes
+
+ (* Active Patterns to help with pattern matching nodes *)
+ let inline (|IsMacro|_|) env = function
+ | List(_, Symbol(sym)::rest) ->
+ match find env sym with
+ | Some(Macro(_, _, _, _, _, _) as m) -> Some(IsMacro m, rest)
+ | _ -> None
+ | _ -> None