Mercurial > repos > tabletprog
annotate cbackend.js @ 38:e7be612fd3ae
Very basic array support
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 10 Jul 2012 23:09:44 -0700 |
parents | a6bf4869fcbe |
children | a997e42b9051 |
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]; |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
45 return 'mcall(' + getMethodId(method) + ', 2, ' + this.left.toC() + ', ' + this.right.toC() + ')\n'; |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 }; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
48 function escapeCName(name) |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
49 { |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
50 if (name == 'self') { |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
51 return name; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
52 } |
31
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 var info = this.symbols.find(name); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 if (!info) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 throw new Error('symbol ' + name + ' not found'); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
64 var pre = ''; |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
65 switch(info.type) { |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
66 case 'self': |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
67 pre = 'self->'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
68 break; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
69 case 'parent': |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
70 pre = 'self->'; |
32
64f1d516fbfd
Tiny bit of work on closures
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
71 for (var i = 0; i < info.depth; ++i) { |
64f1d516fbfd
Tiny bit of work on closures
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
72 pre += 'parent->'; |
64f1d516fbfd
Tiny bit of work on closures
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
73 } |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
74 break; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
75 case 'upvar': |
32
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 } |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
80 break; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
81 case 'toplevel': |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 pre = 'modules.'; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
83 modules[name] = false; |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
84 break; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
85 case 'closedover': |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
86 pre = 'myenv->'; |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
87 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 return pre + escapeCName(name); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
89 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
91 var declaredInts = {}; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
92 |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 intlit.prototype.toC = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 var str = this.val.toString(); |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
95 if (!(this.val in declaredInts)) { |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
96 toplevelcode += 'obj_int32 int32_' + str + ' = {{&obj_int32_meta, NULL}, ' + str + '};\n'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
97 declaredInts[this.val] = true; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
98 } |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 return '((object *)&int32_' + str + ')'; |
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 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 floatlit.prototype.toC = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
103 return 'make_float(' + this.val.toString() + ')'; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
104 } |
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 strlit.prototype.toC = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
107 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
|
108 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
109 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
110 listlit.prototype.toC = function() { |
38 | 111 var ret = 'make_list(' + this.val.length + ', '; |
112 for (var i = 0; i < this.val.length; i++) { | |
113 ret += (i ? ', ' : '') + this.val[i].toC(); | |
114 } | |
115 return ret + ')'; | |
116 } | |
117 | |
118 arraylit.prototype.toC = function() { | |
119 var ret = 'make_array(' + this.val.length + ', '; | |
120 for (var i = 0; i < this.val.length; i++) { | |
121 ret += (i ? ', ' : '') + this.val[i].toC(); | |
122 } | |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
123 return ret + ')'; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
124 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
125 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
126 funcall.prototype.toC = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
127 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
|
128 if (name == 'foreign') { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
129 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
|
130 return null; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
131 } else if(this.args[0] instanceof symbol) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
132 return this.args[0].name; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
133 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
134 throw new Error("Unexpected AST type for foreign:"); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
135 } |
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 var args = this.args.slice(0, this.args.length); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
138 if (this.receiver) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
139 args.splice(0, 0, this.receiver); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
140 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
141 var method = false; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
142 var funinfo = this.symbols.find(name); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
143 if (!funinfo || funinfo.def instanceof setter) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
144 method = true; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
145 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
146 switch(funinfo.type) |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
147 { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
148 case 'self': |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
149 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
|
150 args.splice(0, 0, new symbol('self', this.symbols)); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
151 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
152 args.splice(0, 1); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
153 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
154 method = true; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
155 break; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
156 case 'parent': |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
157 ret = 'self'; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
158 for (var i = 0; i < funinfo.depth; ++i) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
159 ret += '->parent'; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
160 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
161 break; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
162 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
163 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
164 for (var i in args) { |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
165 args[i] = ', ' + args[i].toC(); |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
166 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
167 var callpart; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
168 if (method) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
169 callpart = 'mcall(' + getMethodId(name); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
170 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
171 callpart = 'ccall(' + escapeCName(name); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
172 } |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
173 return callpart + ', ' + args.length + args.join('') + ')'; |
31
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 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
176 function cObject(name) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
177 this.name = name; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
178 this.slots = {}; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
179 this.properties = []; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
180 this.values = []; |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
181 this.slotvars = {}; |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
182 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
183 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
184 cObject.prototype.addMessage = function(msgname, implementation) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
185 var methodid = getMethodId(msgname); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
186 var trunc = methodid & 0xF; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
187 if (!(trunc in this.slots)) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
188 this.slots[trunc] = []; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
189 } |
37
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
190 this.slots[trunc].push([methodid, '\t\t' + implementation.lines.join('\n\t\t') + '\n', msgname]); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
191 if (!(trunc in this.slotvars)) { |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
192 this.slotvars[trunc] = {}; |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
193 } |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
194 for (var varname in implementation.vars) { |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
195 this.slotvars[trunc][varname] = implementation.vars[varname]; |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
196 } |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
197 } |
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 cObject.prototype.addProperty = function(propname, value, type) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
200 if (type != undefined) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
201 this.properties.push([propname, type]); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
202 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
203 var escaped = escapeCName(propname); |
37
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
204 this.addMessage(propname, { |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
205 vars: {}, |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
206 lines: [ |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
207 'va_end(args);', |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
208 'return self->' + escaped + ';' |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
209 ]}); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
210 this.addMessage(propname + '!', { |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
211 vars: {setval: 'object *'}, |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
212 lines: [ |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
213 'setval = va_arg(args, object *);', |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
214 'va_end(args);', |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
215 'self->' + escaped + ' = setval;', |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
216 'return (object *)self;' |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
217 ]}); |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
218 this.properties.push(escaped); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
219 this.values.push(value); |
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 } |
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 cObject.prototype.toEarlyCDef = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
224 var objdef = 'typedef struct {\n\tobject header;\n'; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
225 for (var i in this.properties) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
226 if (this.properties[i] instanceof Array) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
227 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
|
228 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
229 objdef += '\tobject * ' + this.properties[i] + ';\n' |
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 objdef += '} ' + this.name + ';\nobj_meta ' + this.name + '_meta;\n'; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
233 return objdef; |
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 cObject.prototype.toCDef = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
237 var slotdefs = ''; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
238 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
|
239 for (var i = 0; i < 16; i++) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
240 if (i) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
241 metadef += ', '; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
242 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
243 if (i in this.slots) { |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
244 slotdefs += 'object * ' + this.name + '_slot_' + i + '(uint32_t method_id, uint32_t num_params, object * oself, va_list args) {\n\t' + |
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
245 this.name + ' *self = (' + this.name + ' *)oself;\n'; |
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
246 for (var varname in this.slotvars[i]) { |
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
247 slotdefs += '\t' + this.slotvars[i][varname] + ' ' + varname + ';\n'; |
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
248 } |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
249 if (this.slots[i].length == 1) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
250 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
|
251 '\t\t' + this.slots[i][0][1] + '\n' + |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
252 '\t}\n' + |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
253 '\treturn no_impl(method_id, num_params, (object *)self, args);\n}\n'; |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
254 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
255 slotdefs += '\tswitch(method_id) {\n'; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
256 for (j in this.slots[i]) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
257 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
|
258 '\t\t\t' + this.slots[i][j][1] + '\n'; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
259 } |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
260 slotdefs += '\t\tdefault:\n' + |
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
261 '\treturn no_impl(method_id, num_params, params, args);\n}\n'; |
31
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 metadef += this.name + '_slot_' + i; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
264 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
265 metadef += 'no_impl'; |
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 metadef += '}};\n'; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
269 return slotdefs + metadef; |
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 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
272 cObject.prototype.toCInstance = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
273 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
|
274 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
275 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
276 var nextobject = 0; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
277 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
278 object.prototype.toC = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
279 var messages = this.messages; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
280 var values = []; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
281 var imports = [] |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
282 var me = new cObject('object_' + nextobject++); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
283 for (var i in messages) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
284 if (messages[i] instanceof funcall) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
285 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
|
286 imports.push({symbols: false, src: messages[i].args[0]}); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
287 } 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
|
288 var importsyms = []; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
289 each(messages[i].args[0].val, function(i, el) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
290 if (!(el instanceof symbol)) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
291 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
|
292 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
293 importsyms.push(new strlit(el.name)); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
294 }); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
295 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
|
296 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
297 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
|
298 } |
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 messages[i].toCObject(me); |
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 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
303 forwarddec += me.toEarlyCDef(); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
304 toplevelcode += me.toCDef(); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
305 return me.toCInstance(); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
306 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
307 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
308 var toplevelcode; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
309 var forwarddec; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
310 |
37
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
311 function addBinaryOp(cobject, opname, cop, objtype) |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
312 { |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
313 cobject.addMessage(opname, { |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
314 vars: {ret: objtype + ' *', argb: objtype +' *'}, |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
315 lines: [ |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
316 'argb = va_arg(args, ' + objtype + ' *);', |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
317 'ret = (' + objtype + ' *)make_object(&' + objtype + '_meta, NULL, 0);', |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
318 'ret->num = self->num ' + cop + ' argb->num;', |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
319 'return ret;' |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
320 ] |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
321 }); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
322 } |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
323 |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
324 function addCompOp(cobject, opname, cop, objtype) |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
325 { |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
326 cobject.addMessage(opname, { |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
327 vars: {argb: objtype + ' *'}, |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
328 lines: [ |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
329 'argb = va_arg(args, ' + objtype + ' *);', |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
330 'if (self->num ' + cop + ' argb->num) {', |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
331 ' return mcall(METHOD_ID_TRUE, 1, main_module);', |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
332 '}', |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
333 'return mcall(METHOD_ID_FALSE, 1, main_module);' |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
334 ] |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
335 }); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
336 } |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
337 |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
338 function makeCProg(obj) |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
339 { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
340 var int32 = new cObject('obj_int32'); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
341 int32.addProperty('num', null, 'int32_t'); |
37
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
342 addBinaryOp(int32, 'ADD_', '+', 'obj_int32'); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
343 addBinaryOp(int32, 'SUB_', '-', 'obj_int32'); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
344 addBinaryOp(int32, 'MUL_', '*', 'obj_int32'); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
345 addBinaryOp(int32, 'DIV_', '/', 'obj_int32'); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
346 addCompOp(int32, 'LT_', '<', 'obj_int32'); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
347 addCompOp(int32, 'GT_', '>', 'obj_int32'); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
348 addCompOp(int32, 'EQ_', '==', 'obj_int32'); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
349 addCompOp(int32, 'NEQ_', '!=', 'obj_int32'); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
350 addCompOp(int32, 'GEQ_', '>=', 'obj_int32'); |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
351 addCompOp(int32, 'LEQ_', '<=', 'obj_int32'); |
38 | 352 var array = new cObject('array'); |
353 array.addProperty('size', null, 'uint32_t'); | |
354 array.addProperty('storage', null, 'uint32_t'); | |
355 array.addProperty('data', null, 'object **'); | |
356 array.addMessage('get', { | |
357 vars: {index: 'obj_int32 *'}, | |
358 lines: [ | |
359 'index = va_arg(args, obj_int32 *);', | |
360 'if (index->num >= 0 && index->num < self->size) {', | |
361 ' return self->data[index->num];', | |
362 '}', | |
363 'return mcall(METHOD_ID_FALSE, 1, main_module);' | |
364 ] | |
365 }); | |
366 array.addMessage('set', { | |
367 vars: {index: 'obj_int32 *'}, | |
368 lines: [ | |
369 'index = va_arg(args, obj_int32 *);', | |
370 'if (index->num >= 0 && index->num < self->size) {', | |
371 ' self->data[index->num] = va_arg(args, object *);', | |
372 '}', | |
373 'return (object *)self;' | |
374 ] | |
375 }); | |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
376 forwarddec = toplevelcode = ''; |
38 | 377 forwarddec += int32.toEarlyCDef() + array.toEarlyCDef(); |
378 toplevelcode += int32.toCDef() + array.toCDef(); | |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
379 obj.populateSymbols(toplevel); |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
380 var rest = 'object * mainModule() {\n\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
381 return '#include "runtime/proghead.inc"\n' + |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
382 '#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' + |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
383 '#define METHOD_ID_TRUE ' + getMethodId('true') + '\n' + |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
384 '#define METHOD_ID_FALSE ' + getMethodId('false') + '\n' + |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
385 forwarddec + toplevelcode + rest + '#include "runtime/progfoot.inc"\n'; |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
386 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
387 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
388 object.prototype.toCModule = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
389 return makeCProg(this); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
390 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
391 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
392 var lambdanum = 0; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
393 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
394 lambda.prototype.toC = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
395 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
|
396 var exprs = this.expressions; |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
397 var mynum = lambdanum++; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
398 if (Object.keys(this.symbols.closedover).length) { |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
399 this.symbols.envtype = 'lambda_' + mynum + '_env'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
400 } |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
401 if (this.selftype) { |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
402 this.symbols.defineVar('self', this.selftype); |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
403 if (args[0] && args[0].cleanName() == 'self') { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
404 args.splice(0, 1); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
405 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
406 var offset = 1; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
407 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
408 var offset = 0; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
409 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
410 for (var i = 0; i < args.length; ++i) { |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
411 var argname = args[i].toC(); |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
412 |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
413 args[i] = (argname.indexOf('->') < 0 ? '\tobject * ' : '\t') + argname + ' = va_arg(args, object *);\n'; |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
414 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
415 var compiled = [] |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
416 for (var i in exprs) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
417 var js = exprs[i].toC(); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
418 if (js) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
419 compiled.push(indent(js)); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
420 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
421 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
422 exprs = compiled; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
423 if (exprs.length) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
424 exprs[exprs.length-1] = 'return ' + exprs[exprs.length-1] + ';'; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
425 } |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
426 |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
427 if (Object.keys(this.symbols.closedover).length) { |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
428 forwarddec += 'typedef struct {\n'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
429 for (var varname in this.symbols.closedover) { |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
430 forwarddec += '\tobject * ' + escapeCName(varname) + ';\n'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
431 } |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
432 forwarddec += '} lambda_' + mynum + '_env;\n' |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
433 |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
434 var myenvinit = '\tlambda_' + mynum + '_env * myenv = malloc(sizeof(lambda_' + mynum + '_env));\n'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
435 this.symbols.envtype = 'lambda_' + mynum + '_env'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
436 } else { |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
437 var myenvinit = ''; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
438 } |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
439 |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
440 toplevelcode += 'object * lambda_' + mynum + ' (' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...) {\n\tva_list args;\n' + myenvinit + '\tva_start(args, num_args);\n'; |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
441 if (this.selftype) { |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
442 var selfvar = (new symbol('self', this.symbols)).toC(); |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
443 if (selfvar == 'self') { |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
444 toplevelcode += '\t' + this.selftype + ' * self = va_arg(args, ' + this.selftype + ' *);\n'; |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
445 } else { |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
446 toplevelcode += '\t' + selfvar + ' = va_arg(args, ' + this.selftype + ' *);\n'; |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
447 } |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
448 |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
449 } |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
450 toplevelcode += args.join('') + '\tva_end(args);\n' + exprs.join(';\n\t') + '\n}\n'; |
34
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
451 |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
452 if (this.symbols.parentEnvType() != 'void') { |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
453 if (this.symbols.passthruenv) { |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
454 var envvar = 'env'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
455 } else { |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
456 var envvar = 'myenv'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
457 } |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
458 return 'make_closure(' + envvar + ', lambda_' + mynum + ')'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
459 } else { |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
460 toplevelcode += 'closure lambda_obj_' + mynum + ' = {{&lambda_meta, NULL}, NULL, lambda_' + mynum + '};\n'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
461 return '((object *)&lambda_obj_' + mynum + ')'; |
a10f1b049193
Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents:
32
diff
changeset
|
462 } |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
463 }; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
464 lambda.prototype.toCObject = function(typename) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
465 this.selftype = typename; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
466 return this.toC(); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
467 }; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
468 lambda.prototype.toCModule = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
469 return makeCProg(this); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
470 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
471 |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
472 assignment.prototype.toC = function() { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
473 var existing = this.symbols.find(this.symbol.name); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
474 var prefix = ''; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
475 var val = this.expression.toC(); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
476 if (val === null) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
477 return null; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
478 } |
38 | 479 if (existing.type == 'local' && !existing.isdeclared) { |
480 prefix = 'object *'; | |
481 this.symbols.declareVar(this.symbol.name); | |
482 } | |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
483 return prefix + this.symbol.toC() + ' = ' + val; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
484 }; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
485 assignment.prototype.toCObject = function(cobj) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
486 if (this.expression.toCObject) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
487 var val = this.expression.toCObject(cobj.name); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
488 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
489 var val = this.expression.toC(); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
490 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
491 if (val === null) { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
492 return; |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
493 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
494 if (this.expression instanceof lambda) { |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
495 var params = ['((object *)self)']; |
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
496 var paramget = ''; |
37
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
497 var messagevars = {}; |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
498 for (var i in this.expression.args) { |
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
499 var escaped = escapeCName(this.expression.args[i].cleanName()); |
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
500 if (escaped != 'self') { |
37
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
501 messagevars[escaped] = 'object *'; |
35
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
502 params.push(escaped); |
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
503 paramget += escaped + ' = va_arg(args, object *); '; |
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
504 } |
bf5e88f6419d
Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents:
34
diff
changeset
|
505 } |
37
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
506 cobj.addMessage(this.symbol.name, { |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
507 vars: messagevars, |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
508 lines: [paramget + 'return ccall(' + val + ', ' + params.length + (params.length ? ', ' : '') + params.join(', ') + ');'] |
a6bf4869fcbe
Small refactor of built-in int32 type and added support for more operators on said type
Mike Pavone <pavone@retrodev.com>
parents:
35
diff
changeset
|
509 }); |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
510 } else { |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
511 cobj.addProperty(this.symbol.name, val); |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
512 } |
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
513 }; |