tweak lambda evaluator
[lambda.git] / code / parse.js
index 4fbab09..2718218 100644 (file)
@@ -34,10 +34,10 @@ var make_parse = function () {
         a = t.type;
         if (a === "name") {
             o = symbol_table[v];
-            if (o && typeof o !== 'function') {
-                a = "keyword";
-            } else {
+            if (!o || typeof o === 'function') {
                 o = symbol_table["(name)"];
+            } else {
+                a = o.arity || "keyword";
             }
         } else if (a ===  "number") {
             o = symbol_table["(literal)"];
@@ -65,6 +65,14 @@ var make_parse = function () {
         }
     };
 
+       try {
+               if (console && console.debug) {
+                       function print() {
+                               console.debug.apply(this, arguments);
+                       }
+               }
+       } catch (e) {}
+
     var symbol = function (id) {
         var s = symbol_table[id];
         if (!s) {
@@ -75,22 +83,8 @@ var make_parse = function () {
         return s;
     };
 
-
-//     try {
-//         if (console && console.debug) {
-//             function print() {
-//                 console.debug.apply(this, arguments);
-//             }
-//         }
-//     } catch (e) {}
-
-
-    var itself = function () {
-        return this;
-    };
-
-    var var_table = {};
-    var name_table = {};
+    var var_table;
+    var name_table;
 
     var name_handler = function () {
         var n = name_table[this.value];
@@ -132,6 +126,11 @@ var make_parse = function () {
         return body;
     };
 
+
+    var itself = function () {
+        return this;
+    };
+
     symbol("(end)");
     symbol("(name)").handler = name_handler;
     symbol("(literal)").handler = itself;
@@ -144,6 +143,51 @@ var make_parse = function () {
     symbol("lambda").handler = lambda_handler;
     symbol(".");
 
+       function make_constants() {
+
+               var constant = function (s, v) {
+                       var x = symbol(s);
+                       x.handler = function () {
+                               this.value = symbol_table[this.id].value;
+                               return this;
+                       };
+                       x.value = v;
+                       x.arity = "literal";
+                       return x;
+               };
+
+               function make_lam2(a, b, aa) {
+                       return make_lam(a, make_lam(b, aa));
+               }
+               function make_lam3(a, b, c, aa) {
+                       return make_lam(a, make_lam(b, make_lam(c, aa)));
+               }
+               function make_app3(aa, bb, cc) {
+                       return make_app(make_app(aa, bb), cc);
+               }
+               var u = make_var("u");
+               var v = make_var("v");
+               var x = make_var("x");
+               var s = make_var("s");
+               var z = make_var("z");
+               var uu = new Lambda_var(u);
+               var vv = new Lambda_var(v);
+               var xx = new Lambda_var(x);
+               var ss = new Lambda_var(s);
+               var zz = new Lambda_var(z);
+               var_table = { u: u, v: v, x: x, s: s, z: z};
+               name_table = {u: uu, v: vv, x: xx, s: ss, z: zz};
+
+               constant("S", make_lam3(u, v, x, make_app3(uu, xx, make_app(vv, xx))));
+               constant("K", make_lam2(u, v, uu));
+               constant("I", make_lam(x, xx));
+               constant("B", make_lam3(u, v, x, make_app(uu, make_app(vv, xx))));
+               constant("C", make_lam3(u, v, x, make_app3(uu, xx, vv)));
+               constant("W", make_lam2(u, v, make_app3(uu, vv, vv)));
+               constant("T", make_lam2(u, v, make_app(vv, uu)));
+       }
+       make_constants();
+
     var expression = function (in_let) {
         var t, n;
         if (token.id === "\\" || token.id === "lambda") {
@@ -168,7 +212,11 @@ var make_parse = function () {
                     n = token;
                     advance();
                 }
-                if (token.id === ".") {
+                               if (token.arity === "literal" && t.first.length === 0) {
+                                       t.first.push(n);
+                                       t.second = token;
+                                       advance();
+                               } else if (token.id === ".") {
                     t.first.push(n);
                     advance();
                     t.second = expression(in_let);
@@ -204,8 +252,8 @@ var make_parse = function () {
                     n = token;
                     advance(")");
                 } else {
-                    if (token.arity !== "name") {
-                        token.error("Expected a variable name.");
+                    if (token.arity !== "name" && token.arity !== "literal") {
+                        token.error("Expected a variable name or literal.");
                     }
                     token.first = n;
                     n = token;