Mercurial > repos > tabletprog
view compiler.js @ 56:a9bf3ffb6379
Fix escape for backslash
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 13 Jul 2012 21:28:37 -0700 |
parents | 93ddb4ad6fcb |
children | 08ae75d90dc2 |
line wrap: on
line source
var debugprint = function() {}; function indent(str) { return str.split('\n').join('\n\t'); } function modulefile(path, file) { this.path = path; this.file = file; } var toplevel = new topsymbols(); function topsymbols(moduledirs) { this.names = null; this.used = {}; var self = this; if (typeof window === "object") { get('/src/', function(data) { self.names = {}; var fakeEl = newEl("div", { innerHTML: data.response }); each(qall('a', fakeEl), function(idx, a) { var tpidx = a.textContent.indexOf('.tp'); if (tpidx > -1) { self.names[a.textContent.substr(0, tpidx)] = true; } }); }); } else { this.names = {}; for (var dirnum in moduledirs) { var results = os.system("ls", [moduledirs[dirnum]]).split('\n'); for (var i in results) { var tpidx = results[i].indexOf('.tp') if (tpidx > -1) { this.names[results[i].substr(0, tpidx)] = new modulefile(moduledirs[dirnum], results[i]); } } } } } topsymbols.prototype.find = function(name) { debugprint('//topsymbols.find', name, name in this.names); if (!this.names) { throw new Error('data not ready'); } if (name in this.names) { this.used[name] = true; return { type: 'toplevel', def: this.names[name] }; } return null; } topsymbols.prototype.getEnvType = function() { return 'void'; } function osymbols(parent) { this.parent = parent; this.names = {}; this.needsenv = false; } osymbols.prototype.find = function(name, nestedcall) { debugprint('//osymbols.find', name + ', exists?:', name in this.names, ', nested?:', nestedcall); if (name in this.names) { if (this.names[name] instanceof funcall && this.names[name].name == 'foreign:') { return { type: 'foreign', def: this.names[name] }; } var ret = { type: 'self', def: this.names[name], }; } else if(this.parent) { var ret = this.parent.find(name, nestedcall); if (ret) { if(ret.type == 'self') { ret.type = 'parent'; ret.depth = 1; } else if(ret.type == 'parent') { ret.depth++; } else if(ret.type == 'closedover' || ret.type == 'upvar') { this.needsenv = true; } } } else { return null; } debugprint('\t//symbol type:', ret ? ret.type : 'null'); return ret; }; osymbols.prototype.defineMsg = function(name, def) { this.names[name] = def; } osymbols.prototype.parentObject = function() { if (!this.parent) { return 'null'; } return 'this'; } osymbols.prototype.allSymbols = function(curlist, cursyms) { if (curlist === undefined) { curlist = []; cursyms = {}; } var keys = Object.keys(this.names).sort(); for (var i in keys) { if (!(keys[i] in cursyms)) { curlist.push(keys[i]); cursyms[keys[i]] = true; } } if (this.parent) { return this.parent.allSymbols(curlist, cursyms); } return curlist; } osymbols.prototype.getEnvType = function() { return this.parent.getEnvType(); } osymbols.prototype.envVar = function() { return this.parent.envVar(); } function lsymbols(parent) { this.parent = parent; this.names = {}; this.closedover = {}; this.declared = {}; this.needsSelfVar = false; this.passthruenv = false; this.envtype = 'void'; } lsymbols.prototype.find = function(name, nestedcall) { debugprint('//lsymbols.find', name + ', exists?:', name in this.names, ', nested?:', nestedcall); if (name in this.names) { if (this.names[name] instanceof funcall && this.names[name].name == 'foreign:') { var ret = { type: 'foreign', def: this.names[name] }; } else { if (nestedcall) { this.closedover[name] = true; this.passthruenv = false; } if (name in this.closedover) { var ret = { type: 'closedover', def: this.names[name] }; } else { var ret = { type: 'local', def: this.names[name], isdeclared: (name in this.declared) }; } } } else if(this.parent) { var ret = this.parent.find(name, true); if (ret) { if (ret.type == 'closedover') { ret.type = 'upvar'; ret.depth = 0; } if (ret.type == 'upvar') { if (Object.keys(this.closedover).length) { ret.depth++; } else { this.passthruenv = true; if (ret.depth == 0) { ret.depth = 1; } } } } } else { return null; } debugprint('\t//symbol type:', ret ? ret.type : 'null'); return ret; }; lsymbols.prototype.defineVar = function(name, def) { this.names[name] = def; }; lsymbols.prototype.declareVar = function(name) { this.declared[name] = true; } lsymbols.prototype.selfVar = function() { if (this.parent && this.parent instanceof lsymbols) { this.parent.needsSelf(); return 'self'; } else { return 'this'; } }; lsymbols.prototype.needsSelf = function() { if (this.parent && this.parent instanceof lsymbols) { this.parent.needsSelf(); } else { this.needsSelfVar = true; } }; lsymbols.prototype.allSymbols = osymbols.prototype.allSymbols; lsymbols.prototype.parentEnvType = function() { if (!this.parent) { return 'void'; } return this.parent.getEnvType(); }; lsymbols.prototype.getEnvType = function() { if (this.passthruenv) { return this.parent.getEnvType(); } else { return this.envtype; } } lsymbols.prototype.envVar = function() { if (Object.keys(this.closedover).length) { return 'myenv'; } else if(this.passthruenv) { return 'env'; } return null; } 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.populateSymbols = function(symbols, isReceiver) { this.left.populateSymbols(symbols); this.right.populateSymbols(symbols); }; symbol.prototype.populateSymbols = function(symbols) { this.symbols = symbols; var ret = symbols.find(this.cleanName()); if (ret.type == 'self') { symbols.find('self'); } } intlit.prototype.populateSymbols = function(symbols) { } floatlit.prototype.populateSymbols = function(symbols) { } strlit.prototype.populateSymbols = function(symbols) { } listlit.prototype.populateSymbols = function(symbols) { for (var i = 0; i < this.val.length; i++) { this.val[i].populateSymbols(symbols); } } arraylit.prototype.populateSymbols = function(symbols) { for (var i = 0; i < this.val.length; i++) { this.val[i].populateSymbols(symbols); } } funcall.prototype.populateSymbols = function(symbols) { if (this.name == 'foreign:') { if ((this.args[0] instanceof lambda) || (this.args[0] instanceof object) || (this.args[0] instanceof symbol)) { return; } else { throw new Error("Unexpected AST type for foreign:"); } } this.symbols = symbols; for (var i in this.args) { this.args[i].populateSymbols(symbols); } if (this.receiver) { this.receiver.populateSymbols(symbols); } } funcall.prototype.populateSymbolsObject = function(symbols) { this.populateSymbols(symbols.parent); } object.prototype.populateSymbols = function(symbols) { symbols = new osymbols(symbols); for (var i in this.messages) { this.messages[i].populateSymbolsObject(symbols); } this.symbols = symbols; } lambda.prototype.populateSymbols = function(symbols, isobject) { var args = this.args ? this.args.slice(0, this.args.length) : []; var exprs = this.expressions; var symbols = new lsymbols(symbols); for (var i in args) { symbols.defineVar(args[i].cleanName(), null); args[i].populateSymbols(symbols); } if (isobject && (!args.length || args[0].cleanName() != 'self')) { symbols.defineVar('self', null); } for (var i in exprs) { exprs[i].populateSymbols(symbols); } this.symbols = symbols; }; assignment.prototype.populateSymbols = function(symbols) { var existing = symbols.find(this.symbol.name); if (!existing) { symbols.defineVar(this.symbol.name, this.expression); } this.symbol.populateSymbols(symbols); this.expression.populateSymbols(symbols); this.symbols = symbols; }; assignment.prototype.populateSymbolsObject = function(symbols) { if (this.expression instanceof lambda || (this.expression instanceof funcall & this.expression.name == 'foreign:')) { symbols.defineMsg(this.symbol.name, this.expression); } else { symbols.defineMsg(this.symbol.name, new getter(null)); symbols.defineMsg(this.symbol.name + '!', new setter(null)); } this.symbol.populateSymbols(symbols); this.expression.populateSymbols(symbols, true); this.symbols = symbols; }; function setter(fun) { this.fun = fun; } setter.prototype.args = [new symbol('self'), new symbol('newval')]; function getter(fun) { this.fun = fun; } getter.prototype.args = [new symbol('self')];