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