Mercurial > repos > tabletprog
view parser.js @ 19:132c7756860e
Use populateSymbols to generate symbol tables during compilation rather than populating them as we go. This change allows us to refer to symbols defined later in the input stream and also gives the symbol table logic a single home that can be used both by the compiler and editor.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 25 Mar 2012 16:11:19 -0700 |
parents | 04ae32e91598 |
children | 40a85f135be5 |
line wrap: on
line source
function op(left, op, right) { this.left = left; this.op = op; this.right = right; } function symbol(name, symbols) { this.name = name; this.symbols = symbols; } symbol.prototype.cleanName = function() { return this.name[0] == ':' ? this.name.substr(1) : this.name; } function intlit(val) { this.val = val; } function floatlit(val) { this.val = val; } function strlit(val) { this.val = val; } function funcall(name, args) { this.name = name; this.args = args; this.receiver = null; } function object(messages) { this.messages = messages; } function lambda(args, expressions) { this.args = args; this.expressions = expressions; } function assignment(sym, expr) { this.symbol = sym; this.expression = expr; } var grammar = 'start = ws module:(object / lambda) ws { return module; };' + 'ws = ([ \\t\\n\\r] / "//" [^\\n]* "\\n")*;' + 'hws = ([ \\t] / "/*" ([^*] / "*" ! "/")* "*/" )*;' + 'expr = e:(funcall / methcall / opexpr) ws { return e; };' + 'opexpr = left:addsub hws opn:("<=" / ">=" / "<" / ">" / "=") hws right:opexpr { return new op(left, opn, right); } / addsub;' + 'addsub = left:muldiv hws opn:("+"/"-") hws right:addsub { return new op(left, opn, right); } / muldiv;'+ 'muldiv = left:primlitsym hws opn:("*"/"/") hws right:muldiv { return new op(left, opn, right); } / primlitsym;'+ 'primlitsym = hws val:(float / int / string / symbol / object / lambda / "(" expr:expr hws ")" { return expr; }) { return val; };' + 'symbol = chars:[a-zA-Z_!?@]+ trailing:(":"? [a-zA-Z_!?@0-9])* ! ":" { for (var i in trailing) { trailing[i] = trailing[i].join(""); } return new symbol(chars.join("") + trailing.join("")); };' + 'float = digits:[0-9]+ "." decimals:[0-9]+ { return new floatlit(parseFloat(digits.join("") + "." + decimals.join(""))); };' + 'int = digits:[0-9]+ { return new intlit(parseInt(digits.join(""), 10)); };' + 'string = "\\"" text:[^\\"]* "\\"" { return new strlit(text.join("")); };' + 'object = "#{" ws messages:assignment* "}" { return new object(messages); };' + 'assignment = hws sym:symbol hws "<-" expr:expr ws { return new assignment(sym, expr); }' + 'lambda = args:((& ":") argname+ )? "{" ws exprs:(assignment / expr)* "}" { return new lambda(args[1], exprs); };' + 'argname = init:":"? chars:[a-zA-Z_!?@]+ trailing:[a-zA-Z_!?@0-9]* hws { return new symbol(init + chars.join("") + trailing.join("")); };' + 'funcall = hws parts: funcallpart+ { var fun = ""; var args = []; for (var i in parts) { fun += parts[i].name; args = args.concat(parts[i].args); } return new funcall(fun, args); };' + 'funcallpart = fun:funpart args:opexpr* hws { return { name: fun, args: args}; };' + 'funpart = chars:[a-zA-Z_!?@]+ middle:[a-zA-Z_!?@0-9]* ":" & [ \\t\\n\\r] { return chars.join("") + middle.join("") + ":"; };' + 'methcall = receiver:opexpr hws info:methcallrest { info.receiver = receiver; return info; };' + 'methcallrest = funcall / unarymeth;' + 'unarymeth = name:symbol { return new funcall(name.name, []); };'; var parser = PEG.buildParser(grammar);