Mercurial > repos > tabletprog
view jsbackend.js @ 15:a5ef5af3df0f
Add toHTML methods to the rest of the AST nodes. Cleanup the formatting a bit
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 23 Mar 2012 18:06:53 -0700 |
parents | 6e4851a204a5 |
children | 132c7756860e |
line wrap: on
line source
var mainModule; function toobj(val) { switch(typeof val) { case 'boolean': if(val) { return mainModule.strue; } else { return mainModule.sfalse; } case 'number': return mainModule.snumber(val); } throw new Error("can't make val into object"); } function setP(o, p, val) { o[p] = val; return o; } function getP(o, p) { return o[p]; } op.prototype.toJS = function(symbols, isReceiver) { var ret = '(' + this.left.toJS(symbols) +' '+ (this.op == '=' ? '==' : this.op) +' '+ this.right.toJS(symbols) + ')'; if (isReceiver) { ret = 'toobj' + ret; } return ret; }; symbol.prototype.toJS = function(symbols) { var name = this.cleanName(); if (name == 'self') { return symbols.selfVar(); } name = name.replace("_", "UN_").replace(":", "CN_").replace("!", "EX_").replace('?', 'QS_').replace('@', 'AT_'); var reserved = {'true': true, 'false': true, 'this': true, 'if': true, 'else': true, 'NaN': true}; if (name in reserved) { name = 's' + name; } return name; } intlit.prototype.toJS = function(symbols) { return this.val.toString(); } floatlit.prototype.toJS = function(symbols) { return this.val.toString(); } strlit.prototype.toJS = function(symbols) { return '"' + this.val.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r') + '"'; } funcall.prototype.toJS = function(symbols) { var name = this.name[this.name.length-1] == ':' ? this.name.substr(0, this.name.length-1) : this.name; if (name == 'foreign') { if ((this.args[0] instanceof lambda) || (this.args[0] instanceof object)) { return null; } else if(this.args[0] instanceof symbol) { return this.args[0].name; } else { throw new Error("Unexpected AST type for foreign:"); } } var args = this.args.slice(0, this.args.length); if (this.receiver) { args.splice(0, 0, this.receiver); } var funinfo = symbols.find(name); if (!funinfo) { var receiver = args[0]; args.splice(0, 1); for (var i in args) { args[i] = args[i].toJS(symbols); } return receiver.toJS(symbols, true) + '.' + (new symbol(name)).toJS(symbols) + '(' + args.join(', ') + ')'; } switch(funinfo.type) { case 'self': if (args.length < funinfo.def.args.length || funinfo.def.args[0].name != 'self') { var receiver = new symbol('self'); } else { var receiver = args[0]; args.splice(0, 1); } for (var i in args) { args[i] = args[i].toJS(symbols); } return receiver.toJS(symbols, true) + '.' + (new symbol(name)).toJS(symbols) + '(' + args.join(', ') + ')'; case 'parent': var ret = 'this'; for (var i = 0; i < funinfo.depth; ++i) { ret += '.parent'; } for (var i in args) { args[i] = args[i].toJS(symbols); } ret += (new symbol(name)).toJS(symbols) + '(' + args.join(', ') + ')'; return ret; case 'local': case 'upvar': case 'foreign': for (var i in args) { args[i] = args[i].toJS(symbols); } return (new symbol(name)).toJS(symbols) + '(' + args.join(', ') + ')'; } } object.prototype.toJS = function(symbols) { var messages = this.messages; symbols = new osymbols(symbols); var compiled = [] for (var i in messages) { var js = messages[i].toJSObject(symbols); if (js) { compiled.push(indent(js)); } } return '{\n\tparent: ' + symbols.parentObject() + ',\n\t' + compiled.join(',\n\t') + '\n}'; } object.prototype.toJSModule = function() { return '(function () {\n\tvar module = ' + indent(this.toJS(null)) + ';\n\treturn module;\n})' } lambda.prototype.toJS = function(symbols) { var args = this.args ? this.args.slice(0, this.args.length) : []; if (args.length && args[0].cleanName() == 'self') { args.splice(0, 1); } var exprs = this.expressions; symbols = new lsymbols(symbols); for (var i in args) { symbols.defineVar(args[i].cleanName(), null); args[i] = args[i].toJS(symbols); } var compiled = [] for (var i in exprs) { var js = exprs[i].toJS(symbols); if (js) { compiled.push(indent(js)); } } exprs = compiled; if (exprs.length) { exprs[exprs.length-1] = 'return ' + exprs[exprs.length-1] + ';'; } return 'function (' + args.join(', ') + ') {\n\t' + (symbols.needsSelfVar ? 'var self = this;\n\t' : '') + exprs.join(';\n\t') + '\n}' }; lambda.prototype.toJSModule = lambda.prototype.toJS assignment.prototype.toJS = function(symbols) { var existing = symbols.find(this.symbol.name); var prefix = ''; if (!existing) { symbols.defineVar(this.symbol.name, this.expression); prefix = 'var '; } else { switch (existing.type) { case 'self': prefix = 'this.'; break; case 'parent': prefix = 'this.'; for (var i = 0; i < existing.depth; ++i) { prefix += 'parent.'; } break; } } var val = this.expression.toJS(symbols); if (val === null) { return null; } return prefix + this.symbol.toJS(symbols) + ' = ' + val; }; assignment.prototype.toJSObject = function(symbols) { symbols.defineMsg(this.symbol.name, this.expression); var val = this.expression.toJS(symbols); if (val === null) { return null; } return this.symbol.toJS(symbols) + ': ' + val; };