1 // Parser for lambda with let written in Simplified JavaScript
2 // by Jim Pryor 2010-09-22
3 // Stripped down from Top Down Operator Precedence : parse.js
4 // http://javascript.crockford.com/tdop/index.html
5 // Douglas Crockford 2010-06-26
7 var make_parse = function () {
13 var advance = function (id) {
15 if (id && token.id !== id) {
16 token.error("Expected '" + id + "'.");
18 if (token_nr >= tokens.length) {
19 token = symbol_table["(end)"];
28 if (o && typeof o !== 'function' ) {
31 o = symbol_table["(name)"];
33 } else if (a === "number") {
34 o = symbol_table["(literal)"];
36 } else if (a === "operator") {
39 t.error("Unknown operator.");
43 t.error("Unexpected token.");
45 token = Object.create(o);
49 token.arity = a; // will be: name, keyword, literal
53 var original_symbol = {
54 handler: function () {
55 this.error("Undefined.");
59 var symbol = function (id) {
60 var s = symbol_table[id];
62 s = Object.create(original_symbol);
71 // if (console && console.debug) {
73 // console.debug.apply(this, arguments);
79 var itself = function () {
86 var name_handler = function () {
87 var n = name_table[this.value];
89 n = make_var(this.value);
90 var_table[this.value] = n;
91 n = new Lambda_var(n);
92 name_table[this.value] = n;
95 return make_app(this.first.handler(), n);
101 var branch_handler = function () {
102 var n = this.second.handler();
104 return make_app(this.first.handler(), n);
110 var lambda_handler = function () {
111 var body = this.second.handler();
113 while (this.first.length) {
114 n = this.first.pop().value;
119 name_table[n] = new Lambda_var(v);
121 body = make_lam(v, body);
127 symbol("(name)").handler = name_handler;
128 symbol("(literal)").handler = itself;
129 symbol("let").handler = lambda_handler;
130 symbol("=").handler = branch_handler;
132 symbol(")").handler = branch_handler;
134 symbol("\\").handler = lambda_handler;
135 symbol("lambda").handler = lambda_handler;
138 var expression = function (in_let) {
140 if (token.id === "\\" || token.id === "lambda") {
141 token.value = "lambda";
145 if (n.arity !== "name") {
146 n.error("Expected a variable name.");
149 if (token.id === "(") {
152 t.second = expression(false);
157 while (token.arity === "name") {
162 if (token.id === ".") {
165 t.second = expression(in_let);
166 } else if (t.first.length === 1) {
170 t.error("Can't parse lambda abstract.");
176 while (token.id === "(") {
178 t = expression(false);
183 if (in_let && token.id === "let" || token.id === "(end)" || token.id === ")") {
187 if (token.arity != "name") {
188 token.error("Expected a variable name.");
194 if (in_let && token.id === "in" || token.id === "(end)" || token.id === ")") {
196 } else if (token.id === "(") {
198 t = expression(false);
204 if (token.arity != "name") {
205 token.error("Expected a variable name.");
215 return function (source) {
216 tokens = source.tokens();
223 var t = null, eq, c, base = {};
226 while (token.id == "let") {
229 if (token.arity !== "name") {
230 token.error("Expected a variable name.");
234 eq = token; // token.id === "="
236 c = expression(true);
244 target.second = expression(false);