tweak lambda evaluator
[lambda.git] / code / parse.js
index fe079dc..dfa0640 100644 (file)
@@ -1,8 +1,17 @@
 // Parser for lambda with let written in Simplified JavaScript
-//             by Jim Pryor 2010-09-22
-//             Stripped down from Top Down Operator Precedence : parse.js
-//             http://javascript.crockford.com/tdop/index.html
-//             Douglas Crockford 2010-06-26
+//      by Jim Pryor 2010-09-22
+//      Stripped down from Top Down Operator Precedence : parse.js
+//      http://javascript.crockford.com/tdop/index.html
+//      Douglas Crockford 2010-06-26
+
+/*jslint onevar: false
+ */
+
+/*   members create, error, message, name, prototype, stringify, toSource,
+    toString, write
+*/
+
+/*global make_var, make_app, make_lam, Lambda_var */
 
 var make_parse = function () {
     var symbol_table = {};
@@ -24,12 +33,12 @@ var make_parse = function () {
         v = t.value;
         a = t.type;
         if (a === "name") {
-                       o = symbol_table[v];
-                       if (o && typeof o !== 'function' ) {
-                               a = "keyword";
-                       } else {
-                               o = symbol_table["(name)"];
-                       }
+            o = symbol_table[v];
+            if (o && typeof o !== 'function') {
+                a = "keyword";
+            } else {
+                o = symbol_table["(name)"];
+            }
         } else if (a ===  "number") {
             o = symbol_table["(literal)"];
             a = "literal";
@@ -38,7 +47,7 @@ var make_parse = function () {
             if (!o) {
                 t.error("Unknown operator.");
             }
-                       a = "keyword";
+            a = "keyword";
         } else {
             t.error("Unexpected token.");
         }
@@ -53,7 +62,7 @@ var make_parse = function () {
     var original_symbol = {
         handler: function () {
             this.error("Undefined.");
-        },
+        }
     };
 
     var symbol = function (id) {
@@ -80,171 +89,171 @@ var make_parse = function () {
         return this;
     };
 
-       var var_table = {};
-       var name_table = {};
-
-       var name_handler = function () {
-               var n = name_table[this.value];
-               if (!n) {
-                       n = make_var(this.value);
-                       var_table[this.value] = n;
-                       n = new Lambda_var(n);
-                       name_table[this.value] = n;
-               }
-               if (this.first) {
-                       return make_app(this.first.handler(), n);
-               } else {
-                       return n;
-               }
-       };
+    var var_table = {};
+    var name_table = {};
 
-       var branch_handler = function () {
-               var n = this.second.handler();
-               if (this.first) {
-                       return make_app(this.first.handler(), n);
-               } else {
-                       return n;
-               }
-       };
+    var name_handler = function () {
+        var n = name_table[this.value];
+        if (!n) {
+            n = make_var(this.value);
+            var_table[this.value] = n;
+            n = new Lambda_var(n);
+            name_table[this.value] = n;
+        }
+        if (this.first) {
+            return make_app(this.first.handler(), n);
+        } else {
+            return n;
+        }
+    };
 
-       var lambda_handler = function () {
-               var body = this.second.handler();
-               var n, v;
-               while (this.first.length) {
-                       n = this.first.pop().value;
-                       v = var_table[n];
-                       if (!v) {
-                               v = make_var(n);
-                               var_table[n] = v;
-                               name_table[n] = new Lambda_var(v);
-                       }
-                       body = make_lam(v, body);
-               }
-               return body;
-       };
+    var branch_handler = function () {
+        var n = this.second.handler();
+        if (this.first) {
+            return make_app(this.first.handler(), n);
+        } else {
+            return n;
+        }
+    };
+
+    var lambda_handler = function () {
+        var body = this.second.handler();
+        var n, v;
+        while (this.first.length) {
+            n = this.first.pop().value;
+            v = var_table[n];
+            if (!v) {
+                v = make_var(n);
+                var_table[n] = v;
+                name_table[n] = new Lambda_var(v);
+            }
+            body = make_lam(v, body);
+        }
+        return body;
+    };
 
     symbol("(end)");
-       symbol("(name)").handler = name_handler;
+    symbol("(name)").handler = name_handler;
     symbol("(literal)").handler = itself;
-       symbol("let").handler = lambda_handler;
-       symbol("=").handler = branch_handler;
-       symbol("in");
-       symbol(")").handler = branch_handler;
-       symbol("(");
-       symbol("\\").handler = lambda_handler;
-       symbol("lambda").handler = lambda_handler;
-       symbol(".");
-
-       var expression = function (in_let) {
-               var t, n;
-               if (token.id === "\\" || token.id === "lambda") {
-                       token.value = "lambda";
-                       t = token;
-                       advance();
-                       n = token;
-                       if (n.arity !== "name") {
-                               n.error("Expected a variable name.");
-                       }
-                       advance();
-                       if (token.id === "(") {
-                               t.first = [n];
-                               advance();
-                               t.second = expression(false);
-                               advance(")");
-                               return t;
-                       } else {
-                               t.first = [];
-                               while (token.arity === "name") {
-                                       t.first.push(n);
-                                       n = token;
-                                       advance();
-                               }
-                               if (token.id === ".") {
-                                       t.first.push(n);
-                                       advance();
-                                       t.second = expression(in_let);
-                               } else if (t.first.length === 1) {
-                                       t.second = n;
-                               } else {
-                                       t.first.push(n);
-                                       t.error("Can't parse lambda abstract.");
-                               }
-                               return t;
-                       };
-               } else {
-                       n = null;
-                       while (token.id === "(") {
-                               advance();
-                               t = expression(false);
-                               token.first = n;
-                               token.second = t;
-                               n = token;
-                               advance(")");
-                               if (in_let && token.id === "let" || token.id === "(end)" || token.id === ")") {
-                                       return n;
-                               }
-                       }
-                       if (token.arity != "name") {
-                               token.error("Expected a variable name.");
-                       }
-                       token.first = n;
-                       n = token;
-                       advance();
-                       while (true) {
-                               if (in_let && token.id === "in" || token.id === "(end)" || token.id === ")") {
-                                       return n;
-                               } else if (token.id === "(") {
-                                       advance();
-                                       t = expression(false);
-                                       token.first = n;
-                                       token.second = t;
-                                       n = token;
-                                       advance(")");
-                               } else {
-                                       if (token.arity != "name") {
-                                               token.error("Expected a variable name.");
-                                       }
-                                       token.first = n;
-                                       n = token;
-                                       advance();
-                               }
-                       }
-               }
-       }
+    symbol("let").handler = lambda_handler;
+    symbol("=").handler = branch_handler;
+    symbol("in");
+    symbol(")").handler = branch_handler;
+    symbol("(");
+    symbol("\\").handler = lambda_handler;
+    symbol("lambda").handler = lambda_handler;
+    symbol(".");
+
+    var expression = function (in_let) {
+        var t, n;
+        if (token.id === "\\" || token.id === "lambda") {
+            token.value = "lambda";
+            t = token;
+            advance();
+            n = token;
+            if (n.arity !== "name") {
+                n.error("Expected a variable name.");
+            }
+            advance();
+            if (token.id === "(") {
+                t.first = [n];
+                advance();
+                t.second = expression(false);
+                advance(")");
+                return t;
+            } else {
+                t.first = [];
+                while (token.arity === "name") {
+                    t.first.push(n);
+                    n = token;
+                    advance();
+                }
+                if (token.id === ".") {
+                    t.first.push(n);
+                    advance();
+                    t.second = expression(in_let);
+                } else if (t.first.length === 1) {
+                    t.second = n;
+                } else {
+                    t.first.push(n);
+                    t.error("Can't parse lambda abstract.");
+                }
+                return t;
+            }
+        } else {
+            n = null;
+            while (token.id === "(") {
+                advance();
+                t = expression(false);
+                token.first = n;
+                token.second = t;
+                n = token;
+                advance(")");
+                if (in_let && token.id === "let" || token.id === "(end)" || token.id === ")") {
+                    return n;
+                }
+            }
+            if (token.arity !== "name") {
+                token.error("Expected a variable name.");
+            }
+            token.first = n;
+            n = token;
+            advance();
+            while (true) {
+                if (in_let && token.id === "in" || token.id === "(end)" || token.id === ")") {
+                    return n;
+                } else if (token.id === "(") {
+                    advance();
+                    t = expression(false);
+                    token.first = n;
+                    token.second = t;
+                    n = token;
+                    advance(")");
+                } else {
+                    if (token.arity !== "name") {
+                        token.error("Expected a variable name.");
+                    }
+                    token.first = n;
+                    n = token;
+                    advance();
+                }
+            }
+        }
+       };
 
     return function (source) {
-               tokens = source.tokens();
+        tokens = source.tokens();
         token_nr = 0;
         advance();
-               
-               // let n = c in b
-               // (\n. b) c
-
-               var t = null, eq, c, base = {};
-               var target = base;
-
-               while (token.id == "let") {
-                       t = token;
-                       advance();
-                       if (token.arity !== "name") {
-                               token.error("Expected a variable name.");
-                       }
-                       t.first = [token];
-                       advance();
-                       eq = token; // token.id === "="
-                       advance("=");
-                       c = expression(true);
-                       c.first = eq;
-                       eq.second = t;
-                       target.second = c;
-                       target = t;
-                       advance("in");
-               }
-       
-               target.second = expression(false);
+        
+        // let n = c in b
+        // (\n. b) c
+
+        var t = null, eq, c, base = {};
+        var target = base;
+
+        while (token.id === "let") {
+            t = token;
+            advance();
+            if (token.arity !== "name") {
+                token.error("Expected a variable name.");
+            }
+            t.first = [token];
+            advance();
+            eq = token; // token.id === "="
+            advance("=");
+            c = expression(true);
+            c.first = eq;
+            eq.second = t;
+            target.second = c;
+            target = t;
+            advance("in");
+        }
+    
+        target.second = expression(false);
 
         advance("(end)");
-               return base.second;
+        return base.second;
     };
 
 };