comparison cbackend.js @ 54:976a0924e1d4

Fix closure over self var
author Mike Pavone <pavone@retrodev.com>
date Fri, 13 Jul 2012 19:22:39 -0700
parents ab6217b8ae4c
children 93ddb4ad6fcb
comparison
equal deleted inserted replaced
53:9482a0afe07c 54:976a0924e1d4
53 name = name.replace("_", "UN_").replace(":", "CN_").replace("!", "EX_").replace('?', 'QS_').replace('@', 'AT_'); 53 name = name.replace("_", "UN_").replace(":", "CN_").replace("!", "EX_").replace('?', 'QS_').replace('@', 'AT_');
54 name = 'tp_' + name; 54 name = 'tp_' + name;
55 return name; 55 return name;
56 } 56 }
57 57
58 function getSymbolPrefix(info) 58 function getSymbolPrefix(info, symbols)
59 { 59 {
60 var pre = ''; 60 var pre = '';
61 switch(info.type) { 61 switch(info.type) {
62 case 'self': 62 case 'self':
63 pre = 'self->'; 63
64 pre = (new symbol('self', symbols)).toC() + '->';
64 break; 65 break;
65 case 'parent': 66 case 'parent':
66 pre = 'self->'; 67 pre = 'self->';
67 for (var i = 0; i < info.depth; ++i) { 68 for (var i = 0; i < info.depth; ++i) {
68 pre += 'parent->'; 69 pre += 'parent->';
94 throw new Error('symbol ' + name + ' not found'); 95 throw new Error('symbol ' + name + ' not found');
95 } 96 }
96 if (info.type == 'toplevel') { 97 if (info.type == 'toplevel') {
97 return info.def.modulevar; 98 return info.def.modulevar;
98 } 99 }
99 return getSymbolPrefix(info) + escapeCName(name); 100 return getSymbolPrefix(info, this.symbols) + escapeCName(name);
100 } 101 }
101 102
102 var declaredInts = {}; 103 var declaredInts = {};
103 104
104 intlit.prototype.toC = function() { 105 intlit.prototype.toC = function() {
251 cObject.prototype.toEarlyCDef = function() { 252 cObject.prototype.toEarlyCDef = function() {
252 var includes = ''; 253 var includes = '';
253 for (var file in this.includes) { 254 for (var file in this.includes) {
254 includes += '#include ' + file + '\n'; 255 includes += '#include ' + file + '\n';
255 } 256 }
256 var objdef = 'typedef struct {\n\tobject header;\n'; 257 var objdef = 'typedef struct ' + this.name + ' {\n\tobject header;\n';
257 for (var i in this.properties) { 258 for (var i in this.properties) {
258 if (this.properties[i] instanceof Array) { 259 if (this.properties[i] instanceof Array) {
259 objdef += '\t' + this.properties[i][1] + ' ' + this.properties[i][0] + ';\n'; 260 objdef += '\t' + this.properties[i][1] + ' ' + this.properties[i][0] + ';\n';
260 } else { 261 } else {
261 objdef += '\tobject * ' + this.properties[i] + ';\n' 262 objdef += '\tobject * ' + this.properties[i] + ';\n'
678 for (var i in builtins) { 679 for (var i in builtins) {
679 forwarddec += builtins[i].toEarlyCDef(); 680 forwarddec += builtins[i].toEarlyCDef();
680 toplevelcode += builtins[i].toCDef(); 681 toplevelcode += builtins[i].toCDef();
681 } 682 }
682 addBuiltinModules(toplevel); 683 addBuiltinModules(toplevel);
684 debugprint('//------POPULATING SYMBOLS-----');
683 obj.populateSymbols(toplevel); 685 obj.populateSymbols(toplevel);
684 var moduleinit = processUsedToplevel(toplevel); 686 var moduleinit = processUsedToplevel(toplevel);
687 debugprint('//------COMPILING AST-----');
685 var rest = 'object * mainModule() {\n' + moduleinit + '\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n'; 688 var rest = 'object * mainModule() {\n' + moduleinit + '\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n';
686 return '#include "runtime/proghead.inc"\n' + 689 return '#include "runtime/proghead.inc"\n' +
687 '#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' + 690 '#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' +
688 '#define METHOD_ID_TRUE ' + getMethodId('true') + '\n' + 691 '#define METHOD_ID_TRUE ' + getMethodId('true') + '\n' +
689 '#define METHOD_ID_FALSE ' + getMethodId('false') + '\n' + 692 '#define METHOD_ID_FALSE ' + getMethodId('false') + '\n' +
730 } 733 }
731 734
732 if (Object.keys(this.symbols.closedover).length) { 735 if (Object.keys(this.symbols.closedover).length) {
733 forwarddec += 'typedef struct lambda_' + mynum + '_env {\n'; 736 forwarddec += 'typedef struct lambda_' + mynum + '_env {\n';
734 for (var varname in this.symbols.closedover) { 737 for (var varname in this.symbols.closedover) {
735 forwarddec += '\tobject * ' + escapeCName(varname) + ';\n'; 738 if (varname == 'self' && this.selftype) {
739 forwarddec += '\tstruct ' + this.selftype + ' * self;\n';
740 } else {
741 forwarddec += '\tobject * ' + escapeCName(varname) + ';\n';
742 }
736 } 743 }
737 forwarddec += '} lambda_' + mynum + '_env;\n' 744 forwarddec += '} lambda_' + mynum + '_env;\n'
738 745
739 var myenvinit = '\tlambda_' + mynum + '_env * myenv = malloc(sizeof(lambda_' + mynum + '_env));\n'; 746 var myenvinit = '\tlambda_' + mynum + '_env * myenv = malloc(sizeof(lambda_' + mynum + '_env));\n';
740 this.symbols.envtype = 'lambda_' + mynum + '_env'; 747 this.symbols.envtype = 'lambda_' + mynum + '_env';
777 lambda.prototype.toCModule = function() { 784 lambda.prototype.toCModule = function() {
778 return makeCProg(this); 785 return makeCProg(this);
779 } 786 }
780 787
781 assignment.prototype.toC = function() { 788 assignment.prototype.toC = function() {
789 debugprint('//assignment', this.symbol.name);
782 var existing = this.symbols.find(this.symbol.name); 790 var existing = this.symbols.find(this.symbol.name);
783 var prefix = ''; 791 var prefix = '';
784 var val = this.expression.toC(); 792 var val = this.expression.toC();
785 if (val === null) { 793 if (val === null) {
786 return null; 794 return null;
787 } 795 }
788 if (existing.type == 'local' && !existing.isdeclared) { 796 if (existing.type == 'local' && !existing.isdeclared) {
789 prefix = 'object *'; 797 prefix = 'object *';
790 this.symbols.declareVar(this.symbol.name); 798 this.symbols.declareVar(this.symbol.name);
799 debugprint('//declared var', this.symbol.name);
791 } 800 }
792 return prefix + this.symbol.toC() + ' = ' + val; 801 return prefix + this.symbol.toC() + ' = ' + val;
793 }; 802 };
794 assignment.prototype.toCObject = function(cobj) { 803 assignment.prototype.toCObject = function(cobj) {
804 debugprint('//message definition', this.symbol.name);
795 if (this.expression.toCObject) { 805 if (this.expression.toCObject) {
796 var val = this.expression.toCObject(cobj.name); 806 var val = this.expression.toCObject(cobj.name);
797 } else { 807 } else {
798 var val = this.expression.toC(); 808 var val = this.expression.toC();
799 } 809 }