Merge pull request #378 from asarhaddon/test-macro-not-changing-function
[jackhill/mal.git] / haxe / core / Core.hx
index 8718998..d7b82d3 100644 (file)
@@ -6,6 +6,7 @@ import types.Types.*;
 import types.MalException;
 import printer.Printer;
 import reader.Reader;
+import haxe.Timer;
 
 class Core {
     static function BoolFn(v) {
@@ -33,6 +34,11 @@ class Core {
         };
     }
 
+    static var start = Timer.stamp();
+    static function time_ms(args) {
+        return MalInt(Std.int(1000 * (Timer.stamp()-start)));
+    }
+
     static function equal_Q(args) {
         return BoolFn(_equal_Q(args[0],args[1]));
     }
@@ -179,6 +185,34 @@ class Core {
         }
     }
 
+    static function conj(args) {
+        return switch (args[0]) {
+            case MalList(l):
+                var elems = args.slice(1);
+                elems.reverse();
+                MalList(elems.concat(l));
+            case MalVector(l):
+                MalVector(l.concat(args.slice(1)));
+            case _: throw "Invalid conj call";
+        }
+    }
+
+    static function seq(args) {
+        return switch (args[0]) {
+            case MalList(l):
+                l.length > 0 ? args[0] : nil;
+            case MalVector(l):
+                l.length > 0 ? MalList(l.slice(0)) : nil;
+            case MalString(s):
+                if (s.length == 0) { return nil; }
+                MalList(s.split("").map(function(c) { return MalString(c); }));
+            case MalNil:
+                nil;
+            case _: throw "seq: called on non-sequence";
+        }
+    }
+
+
     // hash-map functions
 
     public static function get(hm:MalType, key:MalType) {
@@ -289,10 +323,14 @@ class Core {
         "nil?" => function(a) { return BoolFn(nil_Q(a[0])); },
         "true?" => function(a) { return BoolFn(true_Q(a[0])); },
         "false?" => function(a) { return BoolFn(false_Q(a[0])); },
+        "string?" => function(a) { return BoolFn(string_Q(a[0])); },
         "symbol" => symbol,
         "symbol?" => function(a) { return BoolFn(symbol_Q(a[0])); },
         "keyword" => keyword,
         "keyword?" => function(a) { return BoolFn(keyword_Q(a[0])); },
+        "number?" => function(a) { return BoolFn(number_Q(a[0])); },
+        "fn?" => function(a) { return BoolFn(_fn_Q(a[0])); },
+        "macro?" => function(a) { return BoolFn(_macro_Q(a[0])); },
 
         "pr-str" => pr_str,
         "str" => str,
@@ -310,6 +348,7 @@ class Core {
         "-" => NumOp(function(a,b) {return a-b;}),
         "*" => NumOp(function(a,b) {return a*b;}),
         "/" => NumOp(function(a,b) {return Std.int(a/b);}),
+        "time-ms" => time_ms,
 
         "list" => function(a) { return MalList(a); },
         "list?" => function(a) { return BoolFn(list_Q(a[0])); },
@@ -329,13 +368,14 @@ class Core {
         "concat" => do_concat,
         "nth" => nth,
         "first" => function(a) { return first(a[0]); },
-        "rest" => function(a) { return MalList(_list(a[0]).slice(1)); },
+        "rest" => function(a) { return rest(a[0]); },
         "empty?" => empty_Q,
         "count" => count,
         "apply" => apply,
         "map" => do_map,
 
-        "conj" => function(a) { return nil; },
+        "conj" => conj,
+        "seq" => seq,
 
         "meta" => meta,
         "with-meta" => with_meta,