Mercurial > repos > tabletprog
diff parser.js @ 217:adad61ea2f3a
Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 21 Dec 2013 12:07:51 -0800 |
parents | e01137a97654 |
children | 7435367a932a |
line wrap: on
line diff
--- a/parser.js Sat Dec 21 12:07:00 2013 -0800 +++ b/parser.js Sat Dec 21 12:07:51 2013 -0800 @@ -2,18 +2,28 @@ function op(left, op, right) { this.left = left; + if (op instanceof Array) { + op = op[0]; + } this.op = op; this.right = right; } +op.prototype.valueOf = function(indent) { + return this.left.valueOf(indent) + ' ' + this.op.valueOf(indent) + ' ' + this.right.valueOf(indent); +}; function symbol(name, symbols) { this.name = name; this.symbols = symbols; + this.dirty = false; } symbol.prototype.cleanName = function() { return this.name[0] == ':' ? this.name.substr(1) : this.name; } +symbol.prototype.valueOf = function() { + return this.name; +}; function intlit(val, bits, unsigned) { @@ -27,51 +37,156 @@ this.bits = bits; this.val = val; } +intlit.prototype.valueOf = function() { + var val = '' + this.val; + if (this.bits != 32 || this.unsigned) { + val += this.unsigned ? 'u' : 'i' + val += this.bits; + } + return val; +}; function floatlit(val) { this.val = val; } +floatlit.prototype.valueOf = function() { + return '' + val; +}; function strlit(val) { this.val = val; } +strlit.prototype.valueOf = function() { + return '"'+this.val+'"'; +}; function listlit(val) { this.val = val; } +listlit.prototype.valueOf = function(indent) { + if (indent === undefined) { + indent = ''; + } + var nextindent = indent + '\t'; + var val = '[' + for (var i = 0; i < this.val.length; i++) { + val += '\n' + nextindent + this.val[i].valueOf(nextindent); + } + if (this.val.length) { + val += '\n' + indent; + } + val += ']'; + return val; +}; function arraylit(val) { this.val = val; } +arraylit.prototype.valueOf = function(indent) { + if (indent === undefined) { + indent = ''; + } + var nextindent = indent + '\t'; + var val = '#[' + for (var i = 0; i < this.val.length; i++) { + val += '\n' + nextindent + this.val[i].valueOf(nextindent); + } + if (this.val.length) { + val += '\n' + indent; + } + val += ']'; + return val; +}; function funcall(name, args) { this.name = name; this.args = args; this.receiver = null; + this.dirty = false; } +funcall.prototype.valueOf = function(indent) { + var parts = this.name.split(':'); + var val = ''; + if (this.receiver) { + val += this.receiver.valueOf(indent); + } + var curarg = 0; + for (var i = 0; i < parts.length; i++) { + if (val) { + val += ' '; + } + if (parts[i]) { + val += parts[i] + ': '; + } + if (curarg < this.args.length) { + val += this.args[curarg++].valueOf(indent); + } + } + while (curarg < this.args.length) { + val += ' ' + this.args[curarg++].valueOf(indent); + } + return val; +}; function object(messages) { this.messages = messages; this.name = null; } +object.prototype.valueOf = function(indent) { + if (indent === undefined) { + indent = ''; + } + var nextindent = indent + '\t'; + var val = '#{'; + for (var i = 0; i < this.messages.length; i++) { + val += '\n' + nextindent + this.messages[i].valueOf(nextindent); + } + if (val.length > 2) { + val += '\n' + indent; + } + val += '}'; + return val; +}; function lambda(args, expressions) { this.args = args ? args : []; this.expressions = expressions; } +lambda.prototype.valueOf = function(indent) { + if (indent === undefined) { + indent = ''; + } + var nextindent = indent + '\t'; + var val = ''; + for (var i = 0; i < this.args.length; i++) { + val += this.args[i].valueOf(indent) + ' '; + } + val += '{'; + for (var i = 0; i < this.expressions.length; i++) { + val += '\n' + nextindent + this.expressions[i].valueOf(nextindent); + } + if (this.expressions.length) { + val += '\n' + indent; + } + val += '}'; + return val; +}; function assignment(sym, expr) { this.symbol = sym; this.expression = expr; } +assignment.prototype.valueOf = function(indent) { + return this.symbol.valueOf(indent) + ' <- ' + this.expression.valueOf(indent); +}; function isLambda(node) { @@ -87,7 +202,7 @@ 'compareop = left:maybecons pieces:(hws ("<=" / ">=" / "<" / ">" / "=" / "!=") hws maybecons)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ 'maybecons = consop / addsub;' + 'consop = left:addsub hws "|" hws right:maybecons { return new op(left, "|", right); };'+ -'addsub = left:muldiv pieces:(hws ("+"/"-"/"xor"/"and"/"or"/".") hws muldiv)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ +'addsub = left:muldiv pieces:(hws ((("xor"/"and"/"or") ! [a-zA-Z_!?@0-9])/("+"/"-"/".")) hws muldiv)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ 'muldiv = left:primlitsym pieces:(hws ("*"/"/"/"%") hws primlitsym)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ 'primlitsym = hws val:(float / hex / binary / int / string / symbol / object / array / list / lambda / "(" ws expr:expr hws ")" { return expr; }) { return val; };' + 'symbol = chars:[a-zA-Z_!?@]+ trailing:(":"? [a-zA-Z_!?@0-9])* ! ":" { for (var i = 0; i < trailing.length; i++) { trailing[i] = trailing[i].join(""); } return new symbol(chars.join("") + trailing.join("")); };' +