annotate cbackend.js @ 32:64f1d516fbfd

Tiny bit of work on closures
author Mike Pavone <pavone@retrodev.com>
date Sat, 07 Jul 2012 17:03:01 -0700
parents 668f533e5284
children a10f1b049193
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
31
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
1 var mainModule;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
2 var modules = {};
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
3
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
4 var nextmethodId = 0;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
5 var methodIds = {};
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
6 function getMethodId(methodName)
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
7 {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
8 if (!(methodName in methodIds)) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
9 methodIds[methodName] = nextmethodId++;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
10
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
11 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
12 return methodIds[methodName];
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
13 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
14
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
15 function importSym(obj, src, key)
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
16 {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
17 if(!(key in src)) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
18 throw new Error(key +' not found in source object for import');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
19 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
20 if(key in obj) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
21 throw new Error(key +' already exists in target object for import')
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
22 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
23 obj[key] = src[key];
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
24 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
25
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
26 function doImport(obj, src, symlist)
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
27 {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
28 if (symlist === undefined) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
29 each(src, function(key,val) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
30 if (key != 'parent') {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
31 importSym(obj, src, key);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
32 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
33 });
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
34 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
35 for (var i = 0; i < symlist.length; ++i) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
36 importSym(obj, src, symlist[i]);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
37 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
38 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
39 return obj;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
40 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
41
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
42 op.prototype.toC = function(isReceiver) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
43 var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_'};
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
44 var method = optoMeth[this.op];
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
45 var ret = '(params[0] = ' + this.left.toC() + ',\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
46 ret += 'params[1] = ' + this.right.toC() + ',\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
47 ret += 'mcall(' + getMethodId(method) + ', 2, params))\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
48 return ret;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
49 };
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
50
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
51 function escapeCName(name)
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
52 {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
53 name = name.replace("_", "UN_").replace(":", "CN_").replace("!", "EX_").replace('?', 'QS_').replace('@', 'AT_');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
54 name = 'tp_' + name;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
55 return name;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
56 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
57
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
58 symbol.prototype.toC = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
59 var name = this.cleanName();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
60 if (name == 'self') {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
61 return name;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
62 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
63 var info = this.symbols.find(name);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
64 if (!info) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
65 throw new Error('symbol ' + name + ' not found');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
66 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
67 var pre = '';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
68 if (info.type == 'self') {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
69 pre = this.symbols.selfVar() + '->';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
70 } else if(info.type == 'parent') {
32
64f1d516fbfd Tiny bit of work on closures
Mike Pavone <pavone@retrodev.com>
parents: 31
diff changeset
71 pre = this.symbols.selfVar() + '->';
64f1d516fbfd Tiny bit of work on closures
Mike Pavone <pavone@retrodev.com>
parents: 31
diff changeset
72 for (var i = 0; i < info.depth; ++i) {
64f1d516fbfd Tiny bit of work on closures
Mike Pavone <pavone@retrodev.com>
parents: 31
diff changeset
73 pre += 'parent->';
64f1d516fbfd Tiny bit of work on closures
Mike Pavone <pavone@retrodev.com>
parents: 31
diff changeset
74 }
64f1d516fbfd Tiny bit of work on closures
Mike Pavone <pavone@retrodev.com>
parents: 31
diff changeset
75 } else if(info.type == 'upvar') {
64f1d516fbfd Tiny bit of work on closures
Mike Pavone <pavone@retrodev.com>
parents: 31
diff changeset
76 pre = 'env->';
64f1d516fbfd Tiny bit of work on closures
Mike Pavone <pavone@retrodev.com>
parents: 31
diff changeset
77 for (var i = 1; i < info.depth; ++i) {
64f1d516fbfd Tiny bit of work on closures
Mike Pavone <pavone@retrodev.com>
parents: 31
diff changeset
78 pre += 'parent->';
31
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
79 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
80 } else if (info.type == 'toplevel') {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
81 pre = 'modules.';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
82 modules[name] = false;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
83 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
84 return pre + escapeCName(name);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
85 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
86
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
87 intlit.prototype.toC = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
88 var str = this.val.toString();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
89 toplevelcode += 'obj_int32 int32_' + str + ' = {{&obj_int32_meta, NULL}, ' + str + '};\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
90 return '((object *)&int32_' + str + ')';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
91 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
92
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
93 floatlit.prototype.toC = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
94 return 'make_float(' + this.val.toString() + ')';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
95 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
96
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
97 strlit.prototype.toC = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
98 return 'make_str("' + this.val.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r') + '")';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
99 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
100
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
101 listlit.prototype.toC = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
102 var ret = 'make_list(';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
103 each(this.val, function(idx, el) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
104 ret += (idx ? ', ' : '') + el.toC();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
105 });
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
106 return ret + ')';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
107 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
108
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
109 funcall.prototype.toC = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
110 var name = this.name[this.name.length-1] == ':' ? this.name.substr(0, this.name.length-1) : this.name;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
111 if (name == 'foreign') {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
112 if ((this.args[0] instanceof lambda) || (this.args[0] instanceof object)) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
113 return null;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
114 } else if(this.args[0] instanceof symbol) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
115 return this.args[0].name;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
116 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
117 throw new Error("Unexpected AST type for foreign:");
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
118 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
119 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
120 var args = this.args.slice(0, this.args.length);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
121 if (this.receiver) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
122 args.splice(0, 0, this.receiver);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
123 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
124 var method = false;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
125 var funinfo = this.symbols.find(name);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
126 if (!funinfo || funinfo.def instanceof setter) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
127 method = true;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
128 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
129 switch(funinfo.type)
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
130 {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
131 case 'self':
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
132 if (args.length < funinfo.def.args.length || funinfo.def.args[0].name != 'self') {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
133 args.splice(0, 0, new symbol('self', this.symbols));
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
134 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
135 args.splice(0, 1);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
136 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
137 method = true;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
138 break;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
139 case 'parent':
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
140 ret = 'self';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
141 for (var i = 0; i < funinfo.depth; ++i) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
142 ret += '->parent';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
143 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
144 break;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
145 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
146 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
147 for (var i in args) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
148 args[i] = 'params[' + i + '] = ' + args[i].toC() + ',\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
149 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
150 var callpart;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
151 if (method) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
152 callpart = 'mcall(' + getMethodId(name);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
153 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
154 callpart = 'ccall(' + escapeCName(name);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
155 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
156 return '(' + args.join('') + callpart + ', ' + args.length + ', ' + 'params))';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
157 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
158
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
159 function cObject(name) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
160 this.name = name;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
161 this.slots = {};
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
162 this.properties = [];
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
163 this.values = [];
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
164 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
165
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
166 cObject.prototype.addMessage = function(msgname, implementation) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
167 var methodid = getMethodId(msgname);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
168 var trunc = methodid & 0xF;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
169 if (!(trunc in this.slots)) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
170 this.slots[trunc] = [];
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
171 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
172 this.slots[trunc].push([methodid, implementation, msgname]);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
173 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
174
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
175 cObject.prototype.addProperty = function(propname, value, type) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
176 if (type != undefined) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
177 this.properties.push([propname, type]);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
178 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
179 var escaped = escapeCName(propname);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
180 this.addMessage(propname, 'return self->' + escaped + ';');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
181 this.addMessage(propname + '!', 'self->' + escaped + ' = params[1]; return params[0];');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
182 this.properties.push(escaped);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
183 this.values.push(value);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
184 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
185 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
186
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
187 cObject.prototype.toEarlyCDef = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
188 var objdef = 'typedef struct {\n\tobject header;\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
189 for (var i in this.properties) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
190 if (this.properties[i] instanceof Array) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
191 objdef += '\t' + this.properties[i][1] + ' ' + this.properties[i][0] + ';\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
192 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
193 objdef += '\tobject * ' + this.properties[i] + ';\n'
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
194 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
195 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
196 objdef += '} ' + this.name + ';\nobj_meta ' + this.name + '_meta;\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
197 return objdef;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
198 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
199
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
200 cObject.prototype.toCDef = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
201 var slotdefs = '';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
202 var metadef = 'obj_meta ' + this.name + '_meta = {sizeof(' + this.name +'), {';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
203 for (var i = 0; i < 16; i++) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
204 if (i) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
205 metadef += ', ';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
206 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
207 if (i in this.slots) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
208 slotdefs += 'object * ' + this.name + '_slot_' + i + '(uint32_t method_id, uint32_t num_params, object ** params) {\n\t' +
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
209 this.name + ' *self = (' + this.name + ' *)params[0];';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
210 if (this.slots[i].length == 1) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
211 slotdefs += '\tif (method_id == ' + this.slots[i][0][0] + ') { /* ' + this.slots[i][0][2] + '*/\n' +
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
212 '\t\t' + this.slots[i][0][1] + '\n' +
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
213 '\t}\n' +
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
214 '\treturn no_impl(method_id, num_params, params);\n}\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
215 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
216 slotdefs += '\tswitch(method_id) {\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
217 for (j in this.slots[i]) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
218 slotdefs += '\t\tcase ' + this.slots[i][j][0] + ': /* ' + this.slots[i][j][2] + '*/\n' +
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
219 '\t\t\t' + this.slots[i][j][1] + '\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
220 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
221 slotdefs += '\t\tdefault:\n\treturn no_impl(method_id, num_params, params);\n}\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
222 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
223 metadef += this.name + '_slot_' + i;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
224 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
225 metadef += 'no_impl';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
226 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
227 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
228 metadef += '}};\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
229 return slotdefs + metadef;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
230 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
231
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
232 cObject.prototype.toCInstance = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
233 return 'make_object(&' + this.name + '_meta, NULL, ' + this.values.length + (this.values.length ? ', ' : '') + this.values.join(', ') + ')';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
234 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
235
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
236 var nextobject = 0;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
237
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
238 object.prototype.toC = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
239 var messages = this.messages;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
240 var values = [];
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
241 var imports = []
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
242 var me = new cObject('object_' + nextobject++);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
243 for (var i in messages) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
244 if (messages[i] instanceof funcall) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
245 if (messages[i].name == 'import:' && messages[i].args.length == 1) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
246 imports.push({symbols: false, src: messages[i].args[0]});
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
247 } else if(messages[i].name == 'import:from:' && messages[i].args.length == 2) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
248 var importsyms = [];
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
249 each(messages[i].args[0].val, function(i, el) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
250 if (!(el instanceof symbol)) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
251 throw new Error('Names in import:from statement must be symbols');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
252 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
253 importsyms.push(new strlit(el.name));
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
254 });
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
255 imports.push({symbols: new listlit(importsyms), src: messages[i].args[1]});
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
256 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
257 throw new Error('Only import and import:from calls allowed in object context');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
258 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
259 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
260 messages[i].toCObject(me);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
261 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
262 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
263 forwarddec += me.toEarlyCDef();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
264 toplevelcode += me.toCDef();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
265 return me.toCInstance();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
266 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
267
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
268 var toplevelcode;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
269 var forwarddec;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
270
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
271 function makeCProg(obj)
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
272 {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
273 var int32 = new cObject('obj_int32');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
274 int32.addProperty('num', null, 'int32_t');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
275 int32.addMessage('ADD_', 'params[0] = make_object(&obj_int32_meta, NULL, 0); ((obj_int32 *)params[0])->num = self->num + ((obj_int32 *)params[1])->num; return params[0];');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
276 int32.addMessage('SUB_', 'params[0] = make_object(&obj_int32_meta, NULL, 0); ((obj_int32 *)params[0])->num = self->num - ((obj_int32 *)params[1])->num; return params[0];');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
277 forwarddec = toplevelcode = '';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
278 forwarddec += int32.toEarlyCDef();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
279 toplevelcode += int32.toCDef();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
280 obj.populateSymbols(toplevel);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
281 var rest = 'object * mainModule() {\n\treturn ' + obj.toC() + ';\n}\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
282 return '#include "runtime/proghead.inc"\n#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' + forwarddec + toplevelcode + rest + '#include "runtime/progfoot.inc"\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
283 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
284
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
285 object.prototype.toCModule = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
286 return makeCProg(this);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
287 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
288
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
289 var lambdanum = 0;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
290
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
291 lambda.prototype.toC = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
292 var args = this.args ? this.args.slice(0, this.args.length) : [];
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
293 var exprs = this.expressions;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
294 if (this.selftype) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
295 if (args[0] && args[0].cleanName() == 'self') {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
296 args.splice(0, 1);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
297 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
298 var offset = 1;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
299 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
300 var offset = 0;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
301 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
302 for (var i = 0; i < args.length; ++i) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
303 args[i] = '\tobject * ' + args[i].toC() + ' = params[' + (offset + i) + '];\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
304 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
305 var compiled = []
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
306 for (var i in exprs) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
307 var js = exprs[i].toC();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
308 if (js) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
309 compiled.push(indent(js));
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
310 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
311 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
312 exprs = compiled;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
313 if (exprs.length) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
314 exprs[exprs.length-1] = 'return ' + exprs[exprs.length-1] + ';';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
315 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
316 var mynum = lambdanum++;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
317 toplevelcode += 'object * lambda_' + mynum + ' (void * env, uint32_t num_args, object ** params) {\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
318 if (this.selftype) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
319 toplevelcode += '\t' + this.selftype + ' * self = (' + this.selftype + ' *)params[0];\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
320 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
321 toplevelcode += args.join('') + exprs.join(';\n\t') + '\n}\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
322
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
323 toplevelcode += 'closure lambda_obj_' + mynum + ' = {{&lambda_meta, NULL}, NULL, lambda_' + mynum + '};\n';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
324 return '((object *)&lambda_obj_' + mynum + ')';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
325 };
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
326 lambda.prototype.toCObject = function(typename) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
327 this.selftype = typename;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
328 return this.toC();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
329 };
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
330 lambda.prototype.toCModule = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
331 return makeCProg(this);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
332 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
333
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
334 assignment.prototype.toC = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
335 var existing = this.symbols.find(this.symbol.name);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
336 var prefix = '';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
337 if (!existing) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
338 prefix = 'object * ';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
339 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
340 switch (existing.type)
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
341 {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
342 case 'self':
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
343 prefix = 'self->';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
344 break;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
345 case 'parent':
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
346 prefix = 'self->header.';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
347 for (var i = 0; i < existing.depth; ++i) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
348 prefix += 'parent->';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
349 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
350 break;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
351 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
352 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
353 var val = this.expression.toC();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
354 if (val === null) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
355 return null;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
356 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
357 return prefix + this.symbol.toC() + ' = ' + val;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
358 };
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
359 assignment.prototype.toCObject = function(cobj) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
360 if (this.expression.toCObject) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
361 var val = this.expression.toCObject(cobj.name);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
362 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
363 var val = this.expression.toC();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
364 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
365 if (val === null) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
366 return;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
367 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
368 if (this.expression instanceof lambda) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
369 cobj.addMessage(this.symbol.name, 'return ccall(' + val + ', num_params, params);');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
370 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
371 cobj.addProperty(this.symbol.name, val);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
372 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
373 };