X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=code%2Fparse.js;h=9712809b40c5d7d608b48543eb4c5270cc4e6712;hp=8a4761b50be13482cdf30a8be23527b9198aae9d;hb=c51047cd5851147777c81822d00b1dd6e35988d5;hpb=847feba6f0cf9ca175f3786dbcefacdc3f1cac5a;ds=sidebyside diff --git a/code/parse.js b/code/parse.js index 8a4761b5..9712809b 100644 --- a/code/parse.js +++ b/code/parse.js @@ -4,6 +4,9 @@ // http://javascript.crockford.com/tdop/index.html // Douglas Crockford 2010-06-26 +// See also http://effbot.org/zone/simple-top-down-parsing.htm + + /*jslint onevar: false */ @@ -65,6 +68,7 @@ var make_parse = function () { } }; + /* try { if (console && console.debug) { function print() { @@ -72,6 +76,7 @@ var make_parse = function () { } } } catch (e) {} + */ var symbol = function (id) { var s = symbol_table[id]; @@ -126,13 +131,8 @@ var make_parse = function () { return body; }; - var number_handler = function () { - - }; - symbol("(end)"); symbol("(name)").handler = name_handler; - symbol("(number)").handler = number_handler; symbol("let").handler = lambda_handler; symbol("=").handler = branch_handler; symbol("in"); @@ -140,27 +140,13 @@ var make_parse = function () { symbol("("); symbol("\\").handler = lambda_handler; symbol("lambda").handler = lambda_handler; + symbol("\u03bb").handler = lambda_handler; + // symbol("\u2203").handler = exists_handler; + // symbol("\u2200").handler = forall_handler; symbol("."); function make_constants() { - var constant = function (s, v) { - var x = symbol(s); - x.handler = function () { - this.value = symbol_table[this.id].value; - if (this.first) { - return make_app(this.first.handler(), this.value); - } else { - return this.value; - } - }; - // constants have their own id and arity = literal - // numbers have id = "(number)" and arity = literal - x.arity = "literal"; - x.value = v; - return x; - }; - function make_lam2(a, b, aa) { return make_lam(a, make_lam(b, aa)); } @@ -182,14 +168,62 @@ var make_parse = function () { 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}; + number_table = {}; + + // constants have their own id and arity = literal + // numbers have id = "(number)" and arity = literal + symbol("(number)").handler = function () { + var n = this.value; + var res = number_table[n]; + if (!res) { + res = zz; + while (n > 0) { + n -= 1; + res = make_app(ss, res); + } + res = make_lam2(s, z, res); + number_table[this.value] = res; + } + if (this.first) { + return make_app(this.first.handler(), res); + } else { + return res; + } + } + + var constant = function (s, v) { + var x = symbol(s); + x.handler = function () { + this.value = symbol_table[this.id].value; + if (this.first) { + return make_app(this.first.handler(), this.value); + } else { + return this.value; + } + }; + x.arity = "literal"; + x.value = v; + return x; + }; 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))); + + // trush \uv.vu = CI = box constant("T", make_lam2(u, v, make_app(vv, uu))); + // vireo \uvw.wuv = pair + constant("V", make_lam3(u, v, x, make_app3(xx, uu, vv))); + // warbler \uv.uvv = C(BM(BBT) = C(BS(C(BBI)I))I + constant("W", make_lam2(u, v, make_app3(uu, vv, vv))); + // mockingbird \u.uu = SII = omega + constant("M", make_lam(u, make_app(uu, uu))); + // lark \uv.u(vv) = CBM = BWB + constant("L", make_lam2(u, v, make_app(uu, make_app(vv, vv)))); + // Y is SLL + } make_constants(); @@ -212,9 +246,11 @@ var make_parse = function () { return t; } else { t.first = []; - while (token.arity === "name") { - t.first.push(n); - n = token; + while (token.arity === "name" || token.id === "\\") { + if (token.id !== "\\") { + t.first.push(n); + n = token; + } advance(); } if (token.arity === "literal" && t.first.length === 0) { @@ -272,7 +308,7 @@ var make_parse = function () { tokens = source.tokens(); token_nr = 0; advance(); - + // let n = c in b // (\n. b) c @@ -302,7 +338,7 @@ var make_parse = function () { target = t; advance("in"); } - + target.second = expression(false); advance("(end)");