Travis: add remaining implementations.
[jackhill/mal.git] / fsharp / env.fs
index 0b9f6a5..5ae039a 100644 (file)
@@ -32,10 +32,13 @@ module Env
         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
@@ -60,7 +63,39 @@ module Env
               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 ]
 
@@ -69,7 +104,7 @@ module 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 -> 
@@ -80,3 +115,11 @@ module Env
             | [], _ -> 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