annotate cbackend.js @ 40:927fd7911a01

Add append message to array
author Mike Pavone <pavone@retrodev.com>
date Wed, 11 Jul 2012 19:17:24 -0700
parents a997e42b9051
children 0558dad9d061
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
31
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
1 var mainModule;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
2 var modules = {};
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
3
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
4 var nextmethodId = 0;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
5 var methodIds = {};
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
6 function getMethodId(methodName)
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
7 {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
8 if (!(methodName in methodIds)) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
9 methodIds[methodName] = nextmethodId++;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
10
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
11 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
12 return methodIds[methodName];
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
13 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
14
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
15 function importSym(obj, src, key)
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
16 {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
17 if(!(key in src)) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
18 throw new Error(key +' not found in source object for import');
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
19 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
20 if(key in obj) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
21 throw new Error(key +' already exists in target object for import')
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
22 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
23 obj[key] = src[key];
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
24 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
25
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
26 function doImport(obj, src, symlist)
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
27 {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
28 if (symlist === undefined) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
29 each(src, function(key,val) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
30 if (key != 'parent') {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
31 importSym(obj, src, key);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
32 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
33 });
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
34 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
35 for (var i = 0; i < symlist.length; ++i) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
36 importSym(obj, src, symlist[i]);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
37 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
38 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
39 return obj;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
40 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
41
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
42 op.prototype.toC = function(isReceiver) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
43 var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_'};
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
44 var method = optoMeth[this.op];
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() {
40
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
111 var ret = 'make_list(' + this.val.length;
38
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
112 for (var i = 0; i < this.val.length; i++) {
40
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
113 ret += ', ' + this.val[i].toC();
38
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
114 }
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
115 return ret + ')';
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
116 }
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
117
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
118 arraylit.prototype.toC = function() {
40
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
119 var ret = 'make_array(' + this.val.length;
38
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
120 for (var i = 0; i < this.val.length; i++) {
40
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
121 ret += ', ' + this.val[i].toC();
38
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
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
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
352 var array = new cObject('array');
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
353 array.addProperty('size', null, 'uint32_t');
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
354 array.addProperty('storage', null, 'uint32_t');
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
355 array.addProperty('data', null, 'object **');
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
356 array.addMessage('get', {
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
357 vars: {index: 'obj_int32 *'},
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
358 lines: [
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
359 'index = va_arg(args, obj_int32 *);',
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
360 'if (index->num >= 0 && index->num < self->size) {',
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
361 ' return self->data[index->num];',
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
362 '}',
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
363 'return mcall(METHOD_ID_FALSE, 1, main_module);'
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
364 ]
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
365 });
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
366 array.addMessage('set', {
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
367 vars: {index: 'obj_int32 *'},
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
368 lines: [
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
369 'index = va_arg(args, obj_int32 *);',
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
370 'if (index->num >= 0 && index->num < self->size) {',
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
371 ' self->data[index->num] = va_arg(args, object *);',
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
372 '}',
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
373 'return (object *)self;'
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
374 ]
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
375 });
39
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
376 array.addMessage('foreach', {
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
377 vars: {index: 'obj_int32 *', i: 'int32_t', clos: 'closure *'},
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
378 lines: [
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
379 'clos = va_arg(args, closure *);',
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
380 'for (i = 0; i < self->size; i++) {',
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
381 ' index = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
382 ' index->num = i;',
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
383 ' ccall(clos, 2, index, self->data[i]);',
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
384 '}',
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
385 'return (object *)self;'
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
386 ]
a997e42b9051 Add foreach method to array and add fib sample that can work in C environment and array example
Mike Pavone <pavone@retrodev.com>
parents: 38
diff changeset
387 });
40
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
388 array.addMessage('append', {
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
389 vars: {tmp: 'object *'},
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
390 lines: [
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
391 'if (self->storage == self->size) {',
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
392 ' self->storage *= 2;',
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
393 ' tmp = realloc(self->data, self->storage);',
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
394 ' if (!tmp) {',
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
395 ' fputs("Failed to increase array size\\n", stderr);',
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
396 ' exit(1);',
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
397 ' }',
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
398 ' self->data = tmp;',
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
399 '}',
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
400 'self->data[self->size++] = va_arg(args, object *);',
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
401 'return self;'
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
402 ]
927fd7911a01 Add append message to array
Mike Pavone <pavone@retrodev.com>
parents: 39
diff changeset
403 });
31
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
404 forwarddec = toplevelcode = '';
38
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
405 forwarddec += int32.toEarlyCDef() + array.toEarlyCDef();
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
406 toplevelcode += int32.toCDef() + array.toCDef();
31
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
407 obj.populateSymbols(toplevel);
34
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
408 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
409 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
410 '#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
411 '#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
412 '#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
413 forwarddec + toplevelcode + rest + '#include "runtime/progfoot.inc"\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
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
416 object.prototype.toCModule = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
417 return makeCProg(this);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
418 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
419
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
420 var lambdanum = 0;
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 lambda.prototype.toC = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
423 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
424 var exprs = this.expressions;
34
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
425 var mynum = lambdanum++;
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
426 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
427 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
428 }
31
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
429 if (this.selftype) {
34
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
430 this.symbols.defineVar('self', this.selftype);
31
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
431 if (args[0] && args[0].cleanName() == 'self') {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
432 args.splice(0, 1);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
433 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
434 var offset = 1;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
435 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
436 var offset = 0;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
437 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
438 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
439 var argname = args[i].toC();
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
440
35
bf5e88f6419d Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents: 34
diff changeset
441 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
442 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
443 var compiled = []
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
444 for (var i in exprs) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
445 var js = exprs[i].toC();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
446 if (js) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
447 compiled.push(indent(js));
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
448 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
449 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
450 exprs = compiled;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
451 if (exprs.length) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
452 exprs[exprs.length-1] = 'return ' + exprs[exprs.length-1] + ';';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
453 }
34
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
454
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
455 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
456 forwarddec += 'typedef struct {\n';
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
457 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
458 forwarddec += '\tobject * ' + escapeCName(varname) + ';\n';
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
459 }
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
460 forwarddec += '} lambda_' + mynum + '_env;\n'
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
461
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
462 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
463 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
464 } else {
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
465 var myenvinit = '';
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
466 }
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
467
35
bf5e88f6419d Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents: 34
diff changeset
468 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
469 if (this.selftype) {
34
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
470 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
471 if (selfvar == 'self') {
35
bf5e88f6419d Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents: 34
diff changeset
472 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
473 } else {
35
bf5e88f6419d Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents: 34
diff changeset
474 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
475 }
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
476
31
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
477 }
35
bf5e88f6419d Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents: 34
diff changeset
478 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
479
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
480 if (this.symbols.parentEnvType() != 'void') {
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
481 if (this.symbols.passthruenv) {
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
482 var envvar = 'env';
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
483 } else {
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
484 var envvar = 'myenv';
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
485 }
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
486 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
487 } else {
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
488 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
489 return '((object *)&lambda_obj_' + mynum + ')';
a10f1b049193 Working closures, but need to rethink method call strategy
Mike Pavone <pavone@retrodev.com>
parents: 32
diff changeset
490 }
31
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
491 };
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
492 lambda.prototype.toCObject = function(typename) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
493 this.selftype = typename;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
494 return this.toC();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
495 };
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
496 lambda.prototype.toCModule = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
497 return makeCProg(this);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
498 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
499
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
500 assignment.prototype.toC = function() {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
501 var existing = this.symbols.find(this.symbol.name);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
502 var prefix = '';
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
503 var val = this.expression.toC();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
504 if (val === null) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
505 return null;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
506 }
38
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
507 if (existing.type == 'local' && !existing.isdeclared) {
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
508 prefix = 'object *';
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
509 this.symbols.declareVar(this.symbol.name);
e7be612fd3ae Very basic array support
Mike Pavone <pavone@retrodev.com>
parents: 37
diff changeset
510 }
31
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
511 return prefix + this.symbol.toC() + ' = ' + 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 assignment.prototype.toCObject = function(cobj) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
514 if (this.expression.toCObject) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
515 var val = this.expression.toCObject(cobj.name);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
516 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
517 var val = this.expression.toC();
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
518 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
519 if (val === null) {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
520 return;
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
521 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
522 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
523 var params = ['((object *)self)'];
bf5e88f6419d Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents: 34
diff changeset
524 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
525 var messagevars = {};
35
bf5e88f6419d Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents: 34
diff changeset
526 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
527 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
528 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
529 messagevars[escaped] = 'object *';
35
bf5e88f6419d Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents: 34
diff changeset
530 params.push(escaped);
bf5e88f6419d Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents: 34
diff changeset
531 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
532 }
bf5e88f6419d Use a function/method call strategy that actually works
Mike Pavone <pavone@retrodev.com>
parents: 34
diff changeset
533 }
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
534 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
535 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
536 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
537 });
31
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
538 } else {
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
539 cobj.addProperty(this.symbol.name, val);
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
540 }
668f533e5284 Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
541 };