# HG changeset patch # User Mike Pavone # Date 1342307641 25200 # Node ID 3a169ebb3224d70f4d06a0cbdc48401b5d72ad89 # Parent 42d5660b30b4b211fff539bb906abd31d91a850b Change strategy for handling true and false to avoid some initialization order problems and improve performance. Add support for negative integer literals. Update samples to reflect true/false change. diff -r 42d5660b30b4 -r 3a169ebb3224 cbackend.js --- a/cbackend.js Sat Jul 14 13:31:05 2012 -0700 +++ b/cbackend.js Sat Jul 14 16:14:01 2012 -0700 @@ -96,7 +96,8 @@ throw new Error('symbol ' + name + ' not found'); } if (info.type == 'toplevel') { - return info.def.modulevar; + + return toplevel.moduleVar(name); } return getSymbolPrefix(info, this.symbols) + escapeCName(name); } @@ -104,9 +105,9 @@ var declaredInts = {}; intlit.prototype.toC = function() { - var str = this.val.toString(); + var str = this.val < 0 ? 'neg_' + (0-this.val).toString() : this.val.toString(); if (!(this.val in declaredInts)) { - toplevelcode += 'obj_int32 int32_' + str + ' = {{&obj_int32_meta, NULL}, ' + str + '};\n'; + toplevelcode += 'obj_int32 int32_' + str + ' = {{&obj_int32_meta, NULL}, ' + this.val.toString() + '};\n'; declaredInts[this.val] = true; } return '((object *)&int32_' + str + ')'; @@ -266,6 +267,7 @@ } } +cObject.prototype.populateSymbols = function() {}; cObject.prototype.toEarlyCDef = function() { this.checkInitMsg(); @@ -400,9 +402,9 @@ lines: [ 'argb = va_arg(args, ' + objtype + ' *);', 'if (self->num ' + cop + ' argb->num) {', - ' return mcall(METHOD_ID_TRUE, 1, main_module);', + ' return ' + toplevel.moduleVar('true') + ';', '}', - 'return mcall(METHOD_ID_FALSE, 1, main_module);' + 'return ' + toplevel.moduleVar('false') + ';', ] }); } @@ -449,7 +451,7 @@ 'if (index->num >= 0 && index->num < self->size) {', ' return self->data[index->num];', '}', - 'return mcall(METHOD_ID_FALSE, 1, main_module);' + 'return ' + toplevel.moduleVar('false') + ';' ] }); array.addMessage('set', { @@ -528,9 +530,9 @@ lines: [ 'argb = va_arg(args, string *);', 'if (self->length == argb->length && self->bytes == argb->bytes && !memcmp(self->data, argb->data, self->bytes)) {', - ' return mcall(METHOD_ID_TRUE, 1, main_module);', + ' return ' + toplevel.moduleVar('true') + ';', '}', - 'return mcall(METHOD_ID_FALSE, 1, main_module);' + 'return ' + toplevel.moduleVar('false') + ';', ] }); string.addMessage('NEQ_', { @@ -538,9 +540,9 @@ lines: [ 'argb = va_arg(args, string *);', 'if (self->length != argb->length || self->bytes != argb->bytes || memcmp(self->data, argb->data, self->bytes)) {', - ' return mcall(METHOD_ID_TRUE, 1, main_module);', + ' return ' + toplevel.moduleVar('true') + ';', '}', - 'return mcall(METHOD_ID_FALSE, 1, main_module);' + 'return ' + toplevel.moduleVar('false') + ';', ] }); string.addMessage('print', { @@ -586,12 +588,11 @@ clos.addProperty('env', null, 'void *'); clos.addProperty('func', null, 'closure_func'); clos.addMessage('while:do', { - vars: {action: 'lambda *', valtrue: 'object *', ret: 'object *'}, + vars: {action: 'lambda *', ret: 'object *'}, lines: [ 'action = va_arg(args, lambda *);', - 'valtrue = mcall(METHOD_ID_TRUE, 1, main_module);', - 'ret = valtrue;', - 'while(valtrue == ccall(self, 0)) {', + 'ret = ' + toplevel.moduleVar('true') + ';', + 'while(' + toplevel.moduleVar('true') + ' == ccall(self, 0)) {', ' ccall(action, 0);', '}', 'return ret;' @@ -710,22 +711,55 @@ toplevel.names['os'] = os; } +modulefile.prototype.populateSymbols = function (toplevel) { + if (!this.ast) { + this.ast = parseFile(this.path + '/' + this.file); + this.ast.populateSymbols(toplevel); + } +}; + modulefile.prototype.toC = function(){ - var ast = parseFile(this.path + '/' + this.file); - ast.populateSymbols(toplevel); - return ast.toCModuleInstance(); + this.populateSymbols(toplevel); + return this.ast.toCModuleInstance(); }; function processUsedToplevel(toplevel) -{ +{ + var alwaysused = ['true', 'false']; var ret = ''; var modulenum = 0; - for (var symbol in toplevel.used) { - toplevel.names[symbol].modulevar = 'module_' + (modulenum++); - toplevelcode += 'object * ' + toplevel.names[symbol].modulevar + ';\n'; + var newused = Object.keys(toplevel.used); + var allused = newused; + var visited = {}; + for (var i in alwaysused) { + forwarddec += 'object * ' + toplevel.moduleVar(alwaysused[i]) + ';\n'; + toplevel.names[alwaysused[i]].populateSymbols(toplevel); + visited[alwaysused[i]] = true; } - for (var symbol in toplevel.used) { - ret += '\t' + toplevel.names[symbol].modulevar + ' = ' + toplevel.names[symbol].toC() + ';\n'; + while (newused.length) { + for (var i in newused) { + debugprint('//---module', newused[i], '--- populate symbols'); + forwarddec += 'object * ' + toplevel.moduleVar(newused[i]) + ';\n'; + toplevel.names[newused[i]].populateSymbols(toplevel); + visited[newused[i]] = true; + } + newused = []; + for (var symbol in toplevel.used) { + if (!(symbol in visited)) { + debugprint('//found new usage of module', symbol); + newused.push(symbol); + allused.push(symbol); + } + } + } + for (var i in alwaysused) { + allused.push(alwaysused[i]); + } + + for (var i = allused.length-1; i >= 0; i--) { + var symbol = allused[i]; + debugprint('//---module', symbol, '--- compile'); + ret += '\t' + toplevel.moduleVar(symbol) + ' = ' + toplevel.names[symbol].toC() + ';\n'; } return ret; } @@ -746,8 +780,6 @@ var rest = 'object * mainModule() {\n' + moduleinit + '\tmain_module = ' + obj.toCModuleInstance() + ';\n\treturn main_module;\n}\n'; return '#include "runtime/proghead.inc"\n' + '#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' + - '#define METHOD_ID_TRUE ' + getMethodId('true') + '\n' + - '#define METHOD_ID_FALSE ' + getMethodId('false') + '\n' + forwarddec + toplevelcode + rest + '#include "runtime/progfoot.inc"\n'; } diff -r 42d5660b30b4 -r 3a169ebb3224 compiler.js --- a/compiler.js Sat Jul 14 13:31:05 2012 -0700 +++ b/compiler.js Sat Jul 14 16:14:01 2012 -0700 @@ -16,6 +16,7 @@ { this.names = null; this.used = {}; + this.nextmodulenum = 0; var self = this; if (typeof window === "object") { get('/src/', function(data) { @@ -36,7 +37,7 @@ var results = os.system("ls", [moduledirs[dirnum]]).split('\n'); for (var i in results) { var tpidx = results[i].indexOf('.tp') - if (tpidx > -1) { + if (tpidx > 0 && tpidx == results[i].length - 3) { this.names[results[i].substr(0, tpidx)] = new modulefile(moduledirs[dirnum], results[i]); } } @@ -60,6 +61,18 @@ topsymbols.prototype.getEnvType = function() { return 'void'; } +topsymbols.prototype.moduleVar = function(name) { + if (!(name in this.names)) { + throw new Error('symbol ' + name + ' not found at toplevel'); + } + if (name == 'true' || name == 'false') { + return 'module_' + name; + } + if (!this.names[name].modulevar) { + this.names[name].modulevar = 'module_' + this.nextmodulenum++ + } + return this.names[name].modulevar; +} function osymbols(parent) { diff -r 42d5660b30b4 -r 3a169ebb3224 modules/false.tp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/false.tp Sat Jul 14 16:14:01 2012 -0700 @@ -0,0 +1,6 @@ +#{ + if:else <- :self trueblock :elseblock { + elseblock: + } +} + diff -r 42d5660b30b4 -r 3a169ebb3224 modules/true.tp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/true.tp Sat Jul 14 16:14:01 2012 -0700 @@ -0,0 +1,6 @@ +#{ + if:else <- :self trueblock :elseblock { + trueblock: + } +} + diff -r 42d5660b30b4 -r 3a169ebb3224 parser.js --- a/parser.js Sat Jul 14 13:31:05 2012 -0700 +++ b/parser.js Sat Jul 14 16:14:01 2012 -0700 @@ -82,7 +82,7 @@ 'float = digits:[0-9]+ "." decimals:[0-9]+ { return new floatlit(parseFloat(digits.join("") + "." + decimals.join(""))); };' + 'binary = "0b" digits:[01]+ { return new intlit(parseInt(digits.join(""), 2)); };' + 'hex = "0x" digits:[0-9a-fA-F]+ { return new intlit(parseInt(digits.join(""), 16)); };' + -'int = digits:[0-9]+ { return new intlit(parseInt(digits.join(""), 10)); };' + +'int = sign:"-"? digits:[0-9]+ { return new intlit(parseInt(sign + digits.join(""), 10)); };' + 'string = "\\"" text:(strpart/escape)* "\\"" { return new strlit(text.join("")); };' + 'strpart = text:[^\\"\\\\]+ { return text.join(""); };' + 'escape = "\\\\" char:[nt\\"r\\\\] { if (char == "n") { return "\\n"; } if (char == "r") { return "\\r"; } return char; };' + diff -r 42d5660b30b4 -r 3a169ebb3224 samples/fib.tp --- a/samples/fib.tp Sat Jul 14 13:31:05 2012 -0700 +++ b/samples/fib.tp Sat Jul 14 16:14:01 2012 -0700 @@ -1,16 +1,4 @@ #{ -true <- #{ - if:else <- :self trueblock :elseblock { - trueblock: - } -} - -false <- #{ - if:else <- :self trueblock :elseblock { - elseblock: - } -} - fib <- :n { if: n < 2 { 1 diff -r 42d5660b30b4 -r 3a169ebb3224 samples/iterfib.tp --- a/samples/iterfib.tp Sat Jul 14 13:31:05 2012 -0700 +++ b/samples/iterfib.tp Sat Jul 14 16:14:01 2012 -0700 @@ -1,15 +1,4 @@ #{ -true <- #{ - if:else <- :self trueblock :elseblock { - trueblock: - } -} - -false <- #{ - if:else <- :self trueblock :elseblock { - elseblock: - } -} fib <- :n { last <- 0 diff -r 42d5660b30b4 -r 3a169ebb3224 samples/recursive_closure.tp --- a/samples/recursive_closure.tp Sat Jul 14 13:31:05 2012 -0700 +++ b/samples/recursive_closure.tp Sat Jul 14 16:14:01 2012 -0700 @@ -1,15 +1,4 @@ #{ - true <- #{ - if:else <- :self trueblock :elseblock { - trueblock: - } - } - - false <- #{ - if:else <- :self trueblock :elseblock { - elseblock: - } - } main <- { foo <- :n { if: n < 10 { diff -r 42d5660b30b4 -r 3a169ebb3224 tpc.js --- a/tpc.js Sat Jul 14 13:31:05 2012 -0700 +++ b/tpc.js Sat Jul 14 16:14:01 2012 -0700 @@ -49,12 +49,13 @@ print('usage: d8 tpc.js -- filename'); quit(1); } - +includes.push(basedir + 'modules'); compileFile(file, basedir, includes, debugmode); function parseFile(filename) { + debugprint('//parsing', filename); var text = read(filename); try { var parsed = parser.parse(text);