d, nim: Add number?, fn?, macro?
authorDov Murik <dov.murik@gmail.com>
Mon, 16 Oct 2017 21:56:21 +0000 (21:56 +0000)
committerDov Murik <dov.murik@gmail.com>
Mon, 16 Oct 2017 21:56:21 +0000 (21:56 +0000)
d/mal_core.d
nim/core.nim
nim/step8_macros.nim
nim/step9_try.nim
nim/stepA_mal.nim
nim/types.nim

index 561b457..2d14fb5 100644 (file)
@@ -53,6 +53,24 @@ static MalType mal_keyword_q(MalType[] a ...)
     return bool_to_mal(s.is_keyword());
 }
 
+static MalType mal_fn_q(MalType[] a ...)
+{
+    verify_args_count(a, 1);
+    auto builtinfn = cast(MalBuiltinFunc) a[0];
+    if (builtinfn !is null) return mal_true;
+    auto malfunc = cast(MalFunc) a[0];
+    if (malfunc !is null) return bool_to_mal(!malfunc.is_macro);
+    return mal_false;
+}
+
+static MalType mal_macro_q(MalType[] a ...)
+{
+    verify_args_count(a, 1);
+    auto malfunc = cast(MalFunc) a[0];
+    if (malfunc !is null) return bool_to_mal(malfunc.is_macro);
+    return mal_false;
+}
+
 static MalType mal_pr_str(MalType[] a ...)
 {
     auto items_strs = a.map!(e => pr_str(e, true));
@@ -341,6 +359,9 @@ static this()
         "string?":  &mal_string_q,
         "keyword":  &mal_keyword,
         "keyword?": &mal_keyword_q,
+        "number?":  (a ...) => mal_type_q!MalInteger(a),
+        "fn?":      &mal_fn_q,
+        "macro?":   &mal_macro_q,
 
         "pr-str":   &mal_pr_str,
         "str":      &mal_str,
index 777e243..e992189 100644 (file)
@@ -224,6 +224,9 @@ let ns* = {
   "symbol?": fun symbol_q,
   "keyword": fun keyword,
   "keyword?": fun keyword_q,
+  "number?": fun number_q,
+  "fn?": fun fn_q,
+  "macro?": fun macro_q,
 
   "with-meta": fun with_meta,
   "meta": fun meta,
index 0f2d0fb..0cd6776 100644 (file)
@@ -18,7 +18,7 @@ proc quasiquote(ast: MalType): MalType =
 
 proc is_macro_call(ast: MalType, env: Env): bool =
   ast.kind == List and ast.list[0].kind == Symbol and
-    env.find(ast.list[0].str) != nil and env.get(ast.list[0].str).macro_q
+    env.find(ast.list[0].str) != nil and env.get(ast.list[0].str).fun_is_macro
 
 proc macroexpand(ast: MalType, env: Env): MalType =
   result = ast
index 763d67d..97884dd 100644 (file)
@@ -18,7 +18,7 @@ proc quasiquote(ast: MalType): MalType =
 
 proc is_macro_call(ast: MalType, env: Env): bool =
   ast.kind == List and ast.list[0].kind == Symbol and
-    env.find(ast.list[0].str) != nil and env.get(ast.list[0].str).macro_q
+    env.find(ast.list[0].str) != nil and env.get(ast.list[0].str).fun_is_macro
 
 proc macroexpand(ast: MalType, env: Env): MalType =
   result = ast
index 7f5f9b6..abc3fbc 100644 (file)
@@ -18,7 +18,7 @@ proc quasiquote(ast: MalType): MalType =
 
 proc is_macro_call(ast: MalType, env: Env): bool =
   ast.kind == List and ast.list.len > 0 and ast.list[0].kind == Symbol and
-    env.find(ast.list[0].str) != nil and env.get(ast.list[0].str).macro_q
+    env.find(ast.list[0].str) != nil and env.get(ast.list[0].str).fun_is_macro
 
 proc macroexpand(ast: MalType, env: Env): MalType =
   result = ast
index aeae5ea..48f442b 100644 (file)
@@ -64,7 +64,7 @@ proc hash_map*(xs: varargs[MalType]): MalType {.procvar.} =
     else: xs[i].str
     result.hash_map[s] = xs[i+1]
 
-proc macro_q*(x: MalType): bool =
+proc fun_is_macro*(x: MalType): bool =
   if x.kind == Fun: result = x.is_macro
   elif x.kind == MalFun: result = x.malfun.is_macro
   else: raise newException(ValueError, "no function")
@@ -124,6 +124,15 @@ proc keyword*(xs: varargs[MalType]): MalType {.procvar.} =
 proc keyword_q*(xs: varargs[MalType]): MalType {.procvar.} =
   boolObj(xs[0].kind == String and xs[0].str[0] == '\xff')
 
+proc number_q*(xs: varargs[MalType]): MalType {.procvar.} =
+  boolObj xs[0].kind == Number
+
+proc fn_q*(xs: varargs[MalType]): MalType {.procvar.} =
+  boolObj((xs[0].kind == MalFun or xs[0].kind == Fun) and not xs[0].fun_is_macro)
+
+proc macro_q*(xs: varargs[MalType]): MalType {.procvar.} =
+  boolObj((xs[0].kind == MalFun or xs[0].kind == Fun) and xs[0].fun_is_macro)
+
 proc atom*(xs: varargs[MalType]): MalType {.procvar.} =
   atom(xs[0])