git » jacl.git » commit 795d29a

quasiquote progress

author Alan Dipert
2019-10-17 08:27:41 UTC
committer Alan Dipert
2019-10-17 08:27:41 UTC
parent ed55d0965936df070cd3384d13a0c2d1d906205b

quasiquote progress

jacl.js +36 -0

diff --git a/jacl.js b/jacl.js
index b506c73..c5c9fa9 100644
--- a/jacl.js
+++ b/jacl.js
@@ -459,6 +459,27 @@ READTABLE.value = new ReadTable()
       await (new Reader(stream)).read()
     ));
   })
+  .setMacro("`", true, async stream => {
+    return new Values(Cons.listOf(
+      JACLPKG.intern('QUASIQUOTE'),
+      await new Reader(stream).read()
+    ));
+  })
+  .setMacro(",", true, async stream => {
+    const ch = await stream.read();
+    if (ch === '@') {
+      return new Values(Cons.listOf(
+        JACLPKG.intern('UNQUOTE-SPLICING'),
+        await new Reader(stream).read()
+      ));
+    } else {
+      stream.unread(ch);
+      return new Values(Cons.listOf(
+        JACLPKG.intern('UNQUOTE'),
+        await new Reader(stream).read()
+      ));
+    }
+  })
   .makeDispatchMacroChar('#', true)
   .setDispatchMacroChar('#', ':', async stream => {
     const rdr = new Reader(stream),
@@ -665,6 +686,21 @@ CLPKG.intern('QUOTE').setMacro().fvalue = function(x) {
   return Cons.listOf(JACLPKG.intern('%QUOTE'), x);
 };
 
+JACLPKG.intern('QUASIQUOTE').setMacro().fvalue = function(x) {
+  const expand = form => {
+    if (form instanceof Cons) {
+      const expanded = new Cons(expand(form.car), expand(form.cdr));
+      if (JACLPKG.intern('QUASIQUOTE') === form.car) {
+        return transformQuasiquoteArgument(form.cdr.car);
+      } else {
+        return expanded;
+      }
+    } else {
+      return form;
+    }
+  };
+};
+
 const readJsString = async stream => {
   // TODO make this a real JS string reader
   const [clStr] = await readString(stream);