Mercurial > repos > tabletprog
view jsbackend.js @ 8:04ae32e91598
Move compiler and test page related code out of parser.js
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 21 Mar 2012 20:33:39 -0700 |
parents | |
children | 37d7f60a8ea1 |
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"); } 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) { console.log('string:', this.val); 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; 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; } } if (this.expression instanceof funcall && this.expression.name == 'foreign:') { return null; } return prefix + this.symbol.toJS(symbols) + ' = ' + this.expression.toJS(symbols); }; assignment.prototype.toJSObject = function(symbols) { symbols.defineMsg(this.symbol.name, this.expression); if (this.expression instanceof funcall && this.expression.name == 'foreign:') { return null; } return this.symbol.toJS(symbols) + ': ' + this.expression.toJS(symbols); };