git » jacl.git » commit 87e7881

Symbols are ... done?

author Alan Dipert
2019-08-13 16:17:45 UTC
committer Alan Dipert
2019-08-13 16:17:45 UTC
parent 11a36fadd9de5bdd13f16b0272313beeb7806a5d

Symbols are ... done?

jacl.js +35 -14

diff --git a/jacl.js b/jacl.js
index 632c4e1..01c36f8 100644
--- a/jacl.js
+++ b/jacl.js
@@ -57,15 +57,31 @@ class LispSymbol {
   popBinding() {
     this.value = this.stack.pop();
   }
+  static intern(packageName, name) {
+    if (readInteger(packageName))
+      throw new Error(`Symbol package must not be number: '${packageName}'`);
+    if (readInteger(name))
+      throw new Error(`Symbol name must not be number: '${name}'`);
+    return Package.get(packageName, true).intern(name);
+  }
   static fromString(token) {
     if (/^:[^:]+$/.test(token)) {
-      const kw = token.substring(1);
-      if (readInteger(kw))
-        throw new Error(`Must not have number syntax after ':': '${token}'`);
-      return Package.get('KEYWORD').intern(kw)
-    } else {
-      throw new Error(`TODO: other symbols`);
+      return LispSymbol.intern('KEYWORD', token.substring(1));
+    }
+
+    const singleMarkerRe = /^([^:]+):([^:]+)$/;
+    const doubleMarkerRe = /^([^:]+)::([^:]+)$/;
+
+    for (const re of [singleMarkerRe, doubleMarkerRe]) {
+      const match = token.match(re);
+      if (match) return LispSymbol.intern(...match.slice(1));
     }
+
+    if (token.indexOf(':') < 0) {
+      return PACKAGE.val().intern(token);
+    }
+
+    throw new Error(`Unknown symbol syntax: '${token}'`);
   }
 }
 
@@ -98,8 +114,12 @@ class Package {
     if (this.name === 'KEYWORD') this.exports.set(name, sym);
     return sym;
   }
-  static get(packageName) {
-    return PACKAGES.get(packageName) || null;
+  static get(packageName, throwNotFound = false) {
+    const pkg = PACKAGES.get(packageName);
+    if (!pkg && throwNotFound) {
+      throw new Error(`Package '${packageName}' does not exist`);
+    }
+    return pkg;
   }
   static makePackage(name, ...aliases) {
     const newPackage = new Package(name);
@@ -108,10 +128,13 @@ class Package {
   }
 }
 
-Package.makePackage('JSCL');
+Package.makePackage('JACL');
 Package.makePackage('CL', 'COMMON-LISP');
 Package.makePackage('KEYWORD');
 
+const PACKAGE = Package.get('CL').intern('*PACKAGE*');
+PACKAGE.value = Package.get('CL');
+
 class BufferedStream {
   constructor() {
     this.buf = [];
@@ -177,20 +200,18 @@ READTABLE.value = new ReadTable()
     }
   })
   .setMacro('"', true, async function(stream) {
-    let str = '';
+    let str = new LispString();
     for await(const x of stream) {
       if (x === '"') {
         return new Values(str);
       } else if(x === '\\') {
-        str += await stream.read();
+        str.push(await stream.read());
       } else {
-        str += x;
+        str.push(x);
       }
     }
   });
 
-//const isTerminating = ch => '\")(`,\';'.indexOf(ch) > -1;
-
 const isWhitespace = ch => ' \t\n\r\b'.indexOf(ch) > -1;
 
 const isConstituent = ch => {