git » jacl.git » commit 90e5942

Reading lists, but need to split out tokenization step to handle dot

author Alan Dipert
2019-08-14 12:36:08 UTC
committer Alan Dipert
2019-08-14 12:36:08 UTC
parent 87e788105a77e6710576efdd4e47f80d620ebf87

Reading lists, but need to split out tokenization step to handle dot

jacl.js +54 -7

diff --git a/jacl.js b/jacl.js
index 01c36f8..4bed07b 100644
--- a/jacl.js
+++ b/jacl.js
@@ -193,27 +193,69 @@ class ReadTable {
 
 const READTABLE = Package.get('CL').intern('*READTABLE*');
 
+// TODO
+const CLOSE_PAREN = new Object();
+const readList = async rdr => {
+  rdr.depth = (rdr.depth || 0) + 1;
+  const x = await rdr.read();
+  if (x === CLOSE_PAREN) {
+    return new Values(null);
+  } else {
+    return new Values(new Cons(x, (await readList(rdr))[0]));
+  }
+  //while (true) {
+  //  const x = await rdr.read();
+  //  if (x === CLOSE_PAREN) {
+  //    return new Values(head);
+  //  } else if (cons !== null) {
+  //    cons.cdr = new Cons(x);
+  //    cons = cons.cdr;
+  //  } else {
+  //    cons = head = new Cons(x);
+  //  }
+  //}
+}
+
 READTABLE.value = new ReadTable()
-  .setMacro(';', true, async function(stream) {
-    for await(const ch of stream) {
+  .setMacro(';', true, async rdr => {
+    for await(const ch of rdr.stream) {
       if (ch === '\n') return new Values();
     }
   })
-  .setMacro('"', true, async function(stream) {
+  .setMacro('"', true, async rdr => {
     let str = new LispString();
-    for await(const x of stream) {
+    for await(const x of rdr.stream) {
       if (x === '"') {
         return new Values(str);
       } else if(x === '\\') {
-        str.push(await stream.read());
+        str.push(await rdr.stream.read());
       } else {
         str.push(x);
       }
     }
+  })
+  .setMacro('(', true, readList)
+  .setMacro(')', true, async rdr => {
+    if (!rdr.depth || rdr.depth-- == 0) {
+      throw new Error(`Unmatched ')'`);
+    } else {
+      return new Values(CLOSE_PAREN);
+    }
   });
 
 const isWhitespace = ch => ' \t\n\r\b'.indexOf(ch) > -1;
 
+const consumeWhitespace = async stream => {
+  for await(const ch of stream) {
+    if (isWhitespace(ch)) {
+      continue;
+    } else {
+      stream.unread(ch);
+      break;
+    }
+  }
+}
+
 const isConstituent = ch => {
   return /[A-Za-z]/.test(ch)
     || '!$%&*+-./:<=>?@[]^_{}~'.indexOf(ch) > -1
@@ -268,6 +310,7 @@ const readSingleEscaped = async function(stream, token) {
   }
 };
 
+
 class Reader {
   constructor(stream) {
     this.stream = stream;
@@ -278,8 +321,12 @@ class Reader {
       if (isWhitespace(x)) {
         continue;
       } else if (macroFun = READTABLE.val().getMacro(x)) {
-        const vals = await macroFun(this.stream);
-        if (vals.length) return vals[0]; else continue;
+        const vals = await macroFun(this);
+        if (vals.length) {
+          return vals[0];
+        } else {
+          continue
+        }
       } else if (x === '\\') {
         let y = await this.stream.read();
         return readSingleEscaped(this.stream, y);