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
10 /* members create, error, message, name, prototype, stringify, toSource,
14 /*global make_var, make_app, make_lam, Lambda_var */
16 var make_parse = function () {
17 var symbol_table = {};
22 var advance = function (id) {
24 if (id && token.id !== id) {
25 token.error("Expected '" + id + "'.");
27 if (token_nr >= tokens.length) {
28 token = symbol_table["(end)"];
37 if (o && typeof o !== 'function') {
40 o = symbol_table["(name)"];
42 } else if (a === "number") {
43 o = symbol_table["(literal)"];
45 } else if (a === "operator") {
48 t.error("Unknown operator.");
52 t.error("Unexpected token.");
54 token = Object.create(o);
58 token.arity = a; // will be: name, keyword, literal
62 var original_symbol = {
63 handler: function () {
64 this.error("Undefined.");
68 var symbol = function (id) {
69 var s = symbol_table[id];
71 s = Object.create(original_symbol);
80 // if (console && console.debug) {
82 // console.debug.apply(this, arguments);
88 var itself = function () {
95 var name_handler = function () {
96 var n = name_table[this.value];
98 n = make_var(this.value);
99 var_table[this.value] = n;
100 n = new Lambda_var(n);
101 name_table[this.value] = n;
104 return make_app(this.first.handler(), n);
110 var branch_handler = function () {
111 var n = this.second.handler();
113 return make_app(this.first.handler(), n);
119 var lambda_handler = function () {
120 var body = this.second.handler();
122 while (this.first.length) {
123 n = this.first.pop().value;
128 name_table[n] = new Lambda_var(v);
130 body = make_lam(v, body);
136 symbol("(name)").handler = name_handler;
137 symbol("(literal)").handler = itself;
138 symbol("let").handler = lambda_handler;
139 symbol("=").handler = branch_handler;
141 symbol(")").handler = branch_handler;
143 symbol("\\").handler = lambda_handler;
144 symbol("lambda").handler = lambda_handler;
147 var expression = function (in_let) {
149 if (token.id === "\\" || token.id === "lambda") {
150 token.value = "lambda";
154 if (n.arity !== "name") {
155 n.error("Expected a variable name.");
158 if (token.id === "(") {
161 t.second = expression(false);
166 while (token.arity === "name") {
171 if (token.id === ".") {
174 t.second = expression(in_let);
175 } else if (t.first.length === 1) {
179 t.error("Can't parse lambda abstract.");
185 while (token.id === "(") {
187 t = expression(false);
192 if (in_let && token.id === "let" || token.id === "(end)" || token.id === ")") {
196 if (token.arity !== "name") {
197 token.error("Expected a variable name.");
203 if (in_let && token.id === "in" || token.id === "(end)" || token.id === ")") {
205 } else if (token.id === "(") {
207 t = expression(false);
213 if (token.arity !== "name") {
214 token.error("Expected a variable name.");
224 return function (source) {
225 tokens = source.tokens();
232 var t = null, eq, c, base = {};
235 while (token.id === "let") {
238 if (token.arity !== "name") {
239 token.error("Expected a variable name.");
243 eq = token; // token.id === "="
245 c = expression(true);
253 target.second = expression(false);