Change quasiquote algorithm
[jackhill/mal.git] / impls / miniMAL / step8_macros.json
index 77d8bcc..41fe026 100644 (file)
@@ -9,26 +9,32 @@
 
 ["def", "READ", ["fn", ["strng"], ["read-str", "strng"]]],
 
-["def", "pair?", ["fn", ["x"],
-  ["if", ["sequential?", "x"],
-    ["if", [">", ["count", "x"], 0], true, false],
-    false]]],
+["def", "starts-with", ["fn", ["ast", "sym"],
+  ["and", ["not", ["empty?", "ast"]],
+          ["let", ["a0", ["first", "ast"]],
+            ["and", ["symbol?", "a0"],
+                    ["=", "sym", ["get", "a0", ["`", "val"]]]]]]]],
+
+["def", "quasiquote-loop", ["fn", ["xs"],
+  ["if", ["empty?", "xs"],
+    ["list"],
+    ["let", ["elt", ["first", "xs"],
+             "acc", ["quasiquote-loop", ["rest", "xs"]]],
+      ["if", ["and", ["list?", "elt"],
+                     ["starts-with", "elt", ["`", "splice-unquote"]]],
+        ["list", ["symbol", ["`", "concat"]], ["nth", "elt", 1], "acc"],
+        ["list", ["symbol", ["`", "cons"]], ["quasiquote", "elt"], "acc"]]]]]],
 
 ["def", "quasiquote", ["fn", ["ast"],
-  ["if", ["not", ["pair?", "ast"]],
+  ["if", ["list?", "ast"],
+    ["if", ["starts-with", "ast", ["`", "unquote"]],
+      ["nth", "ast", 1],
+      ["quasiquote-loop", "ast"]],
+  ["if", ["vector?", "ast"],
+    ["list", ["symbol", ["`", "vec"]], ["quasiquote-loop", "ast"]],
+  ["if", ["or", ["map?", "ast"], ["symbol?", "ast"]],
     ["list", ["symbol", ["`", "quote"]], "ast"],
-  ["if", ["and", ["symbol?", ["nth", "ast", 0]],
-                 ["=", ["`", "unquote"], ["get", ["nth", "ast", 0], ["`", "val"]]]],
-    ["nth", "ast", 1],
-  ["if", ["and", ["pair?", ["nth", "ast", 0]],
-                 ["=", ["`", "splice-unquote"],
-                       ["get", ["nth", ["nth", "ast", 0], 0], ["`", "val"]]]],
-    ["list", ["symbol", ["`", "concat"]],
-             ["nth", ["nth", "ast", 0], 1],
-             ["quasiquote", ["rest", "ast"]]],
-    ["list", ["symbol", ["`", "cons"]],
-             ["quasiquote", ["nth", "ast", 0]],
-             ["quasiquote", ["rest", "ast"]]]]]]]],
+    "ast"]]]]],
 
 ["def", "macro?", ["fn", ["ast", "env"],
   ["and", ["list?", "ast"],
@@ -87,6 +93,8 @@
                   ["EVAL", ["nth", "ast", 2], "let-env"]]],
             ["if", ["=", ["`", "quote"], "a0"],
               ["nth", "ast", 1],
+            ["if", ["=", ["`", "quasiquoteexpand"], "a0"],
+              ["quasiquote", ["nth", "ast", 1]],
             ["if", ["=", ["`", "quasiquote"], "a0"],
               ["EVAL", ["quasiquote", ["nth", "ast", 1]], "env"],
             ["if", ["=", ["`", "defmacro!"], "a0"],
                            ["env-new", ["get", "f", ["`", "env"]],
                                        ["get", "f", ["`", "params"]],
                                        "args"]],
-                  ["apply", "f", "args"]]]]]]]]]]]]]]]]]]],
+                  ["apply", "f", "args"]]]]]]]]]]]]]]]]]]]],
 
 ["def", "PRINT", ["fn", ["exp"],
   ["pr-str", "exp", true]]],