# HG changeset patch # User Mike Pavone # Date 1342232559 25200 # Node ID 976a0924e1d45e7cedd0958450da9b2631f53eda # Parent 9482a0afe07c3e05408b58a58b4db1d72f7ac3ba Fix closure over self var diff -r 9482a0afe07c -r 976a0924e1d4 cbackend.js --- a/cbackend.js Fri Jul 13 18:31:32 2012 -0700 +++ b/cbackend.js Fri Jul 13 19:22:39 2012 -0700 @@ -55,12 +55,13 @@ return name; } -function getSymbolPrefix(info) +function getSymbolPrefix(info, symbols) { var pre = ''; switch(info.type) { case 'self': - pre = 'self->'; + + pre = (new symbol('self', symbols)).toC() + '->'; break; case 'parent': pre = 'self->'; @@ -96,7 +97,7 @@ if (info.type == 'toplevel') { return info.def.modulevar; } - return getSymbolPrefix(info) + escapeCName(name); + return getSymbolPrefix(info, this.symbols) + escapeCName(name); } var declaredInts = {}; @@ -253,7 +254,7 @@ for (var file in this.includes) { includes += '#include ' + file + '\n'; } - var objdef = 'typedef struct {\n\tobject header;\n'; + var objdef = 'typedef struct ' + this.name + ' {\n\tobject header;\n'; for (var i in this.properties) { if (this.properties[i] instanceof Array) { objdef += '\t' + this.properties[i][1] + ' ' + this.properties[i][0] + ';\n'; @@ -680,8 +681,10 @@ toplevelcode += builtins[i].toCDef(); } addBuiltinModules(toplevel); + debugprint('//------POPULATING SYMBOLS-----'); obj.populateSymbols(toplevel); var moduleinit = processUsedToplevel(toplevel); + debugprint('//------COMPILING AST-----'); var rest = 'object * mainModule() {\n' + moduleinit + '\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n'; return '#include "runtime/proghead.inc"\n' + '#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' + @@ -732,7 +735,11 @@ if (Object.keys(this.symbols.closedover).length) { forwarddec += 'typedef struct lambda_' + mynum + '_env {\n'; for (var varname in this.symbols.closedover) { - forwarddec += '\tobject * ' + escapeCName(varname) + ';\n'; + if (varname == 'self' && this.selftype) { + forwarddec += '\tstruct ' + this.selftype + ' * self;\n'; + } else { + forwarddec += '\tobject * ' + escapeCName(varname) + ';\n'; + } } forwarddec += '} lambda_' + mynum + '_env;\n' @@ -779,6 +786,7 @@ } assignment.prototype.toC = function() { + debugprint('//assignment', this.symbol.name); var existing = this.symbols.find(this.symbol.name); var prefix = ''; var val = this.expression.toC(); @@ -788,10 +796,12 @@ if (existing.type == 'local' && !existing.isdeclared) { prefix = 'object *'; this.symbols.declareVar(this.symbol.name); + debugprint('//declared var', this.symbol.name); } return prefix + this.symbol.toC() + ' = ' + val; }; assignment.prototype.toCObject = function(cobj) { + debugprint('//message definition', this.symbol.name); if (this.expression.toCObject) { var val = this.expression.toCObject(cobj.name); } else { diff -r 9482a0afe07c -r 976a0924e1d4 compiler.js --- a/compiler.js Fri Jul 13 18:31:32 2012 -0700 +++ b/compiler.js Fri Jul 13 19:22:39 2012 -0700 @@ -1,3 +1,5 @@ +var debugprint = function() {}; + function indent(str) { return str.split('\n').join('\n\t'); @@ -42,6 +44,7 @@ } } topsymbols.prototype.find = function(name) { + debugprint('//topsymbols.find', name, name in this.names); if (!this.names) { throw new Error('data not ready'); } @@ -65,6 +68,7 @@ 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 { @@ -72,7 +76,7 @@ def: this.names[name] }; } - return { + var ret = { type: 'self', def: this.names[name], }; @@ -88,9 +92,11 @@ this.needsenv = true; } } - return ret; + } else { + return null; } - return null; + debugprint('\t//symbol type:', ret ? ret.type : 'null'); + return ret; }; osymbols.prototype.defineMsg = function(name, def) { this.names[name] = def; @@ -136,27 +142,30 @@ 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:') { - return { + var ret = { type: 'foreign', def: this.names[name] }; + } else { + if (nestedcall) { + this.closedover[name] = true; + } + 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) + }; + } } - if (nestedcall) { - this.closedover[name] = true; - } - if (name in this.closedover) { - return { - type: 'closedover', - def: this.names[name] - }; - } - return { - type: 'local', - def: this.names[name], - isdeclared: (name in this.declared) - }; } else if(this.parent) { var ret = this.parent.find(name, true); if (ret) { @@ -171,9 +180,11 @@ } } } - return ret; + } else { + return null; } - return null; + debugprint('\t//symbol type:', ret ? ret.type : 'null'); + return ret; }; lsymbols.prototype.defineVar = function(name, def) { this.names[name] = def; @@ -244,7 +255,10 @@ symbol.prototype.populateSymbols = function(symbols) { this.symbols = symbols; - symbols.find(this.cleanName()); + var ret = symbols.find(this.cleanName()); + if (ret.type == 'self') { + symbols.find('self'); + } } intlit.prototype.populateSymbols = function(symbols) { @@ -297,17 +311,17 @@ this.symbols = symbols; } -lambda.prototype.populateSymbols = function(symbols) { +lambda.prototype.populateSymbols = function(symbols, isobject) { 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); + 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); } @@ -331,7 +345,7 @@ symbols.defineMsg(this.symbol.name + '!', new setter(null)); } this.symbol.populateSymbols(symbols); - this.expression.populateSymbols(symbols); + this.expression.populateSymbols(symbols, true); this.symbols = symbols; }; diff -r 9482a0afe07c -r 976a0924e1d4 tpc.js --- a/tpc.js Fri Jul 13 18:31:32 2012 -0700 +++ b/tpc.js Fri Jul 13 19:22:39 2012 -0700 @@ -5,6 +5,7 @@ var argtype = 'normal'; var includes = []; var basedir = ''; +var debugmode = false; for (var i = 0; i < arguments.length; i++) { switch (argtype) { case 'normal': @@ -13,6 +14,9 @@ case '-i': argtype = arguments[i]; break; + case '-compilerdebug': + debugmode = true; + break; default: if (arguments[i].charAt(0) == '-') { print("unrecognized switch", arguments[i]); @@ -46,10 +50,10 @@ quit(1); } -compileFile(file, basedir, includes); +compileFile(file, basedir, includes, debugmode); -function compileFile(filename, basedir, includes) +function compileFile(filename, basedir, includes, debugmode) { var text = read(filename); load(basedir + 'peg.js'); @@ -74,6 +78,9 @@ print(spacer + '^'); quit(1); } + if (debugmode) { + debugprint = print; + } var c = parsed.toCModule(); print(c); }