Mercurial > repos > tabletprog
view compiler.js @ 16:59e83296e331
Add populateSymbols method to AST
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 25 Mar 2012 14:25:33 -0700 |
parents | 04ae32e91598 |
children | bf03c9f0dd55 |
line wrap: on
line source
function indent(str) { return str.split('\n').join('\n\t'); } function osymbols(parent) { this.parent = parent; this.names = {}; this.lastname = null; } osymbols.prototype.find = function(name) { if (name in this.names) { if (this.names[name] instanceof funcall && this.names[name].name == 'foreign:') { return { type: 'foreign', def: this.names[name] }; } return { type: 'self', def: this.names[name], }; } else if(this.parent) { var ret = this.parent.find(name); if (ret) { if(ret.type == 'self') { ret.type = 'parent'; ret.depth = 1; } else if(ret.type == 'parent') { ret.depth++; } } return ret; } return null; }; osymbols.prototype.defineMsg = function(name, def) { this.lastname = name; this.names[name] = def; } osymbols.prototype.parentObject = function() { if (!this.parent) { return 'null'; } return 'this'; } function lsymbols(parent) { this.parent = parent; this.names = {}; this.lastname = null; this.needsSelfVar = false; } lsymbols.prototype.find = function(name) { if (name in this.names) { if (this.names[name] instanceof funcall && this.names[name].name == 'foreign:') { return { type: 'foreign', def: this.names[name] }; } return { type: 'local', def: this.names[name] }; } else if(this.parent) { var ret = this.parent.find(name); if (ret && ret.type == 'local') { ret.type = 'upvar'; } return ret; } return null; }; lsymbols.prototype.defineVar = function(name, def) { this.lastname = name; this.names[name] = def; }; 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; } }; 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.populateSymbols = function(symbols, isReceiver) { this.left.populateSymbols(symbols); this.right.populateSymbols(symbols); }; symbol.prototype.populateSymbols = function(symbols) { this.symbols = symbols; } intlit.prototype.populateSymbols = function(symbols) { } floatlit.prototype.populateSymbols = function(symbols) { } strlit.prototype.populateSymbols = function(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:"); } } for (var i in this.args) { this.args[i].populateSymbols(symbols); } } 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) { 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].populateSymbols(symbols); } 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); }; assignment.prototype.populateSymbolsObject = function(symbols) { symbols.defineMsg(this.symbol.name, this.expression); this.symbol.populateSymbols(symbols); this.expression.populateSymbols(symbols); };