Mercurial > repos > tabletprog
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 } |