comparison cbackend.js @ 37:a6bf4869fcbe

Small refactor of built-in int32 type and added support for more operators on said type
author Mike Pavone <pavone@retrodev.com>
date Tue, 10 Jul 2012 22:09:21 -0700
parents bf5e88f6419d
children e7be612fd3ae
comparison
equal deleted inserted replaced
36:3b0503a67165 37:a6bf4869fcbe
177 var methodid = getMethodId(msgname); 177 var methodid = getMethodId(msgname);
178 var trunc = methodid & 0xF; 178 var trunc = methodid & 0xF;
179 if (!(trunc in this.slots)) { 179 if (!(trunc in this.slots)) {
180 this.slots[trunc] = []; 180 this.slots[trunc] = [];
181 } 181 }
182 this.slots[trunc].push([methodid, implementation, msgname]); 182 this.slots[trunc].push([methodid, '\t\t' + implementation.lines.join('\n\t\t') + '\n', msgname]);
183 if (!(trunc in this.slotvars)) {
184 this.slotvars[trunc] = {};
185 }
186 for (var varname in implementation.vars) {
187 this.slotvars[trunc][varname] = implementation.vars[varname];
188 }
183 } 189 }
184 190
185 cObject.prototype.addProperty = function(propname, value, type) { 191 cObject.prototype.addProperty = function(propname, value, type) {
186 if (type != undefined) { 192 if (type != undefined) {
187 this.properties.push([propname, type]); 193 this.properties.push([propname, type]);
188 } else { 194 } else {
189 var escaped = escapeCName(propname); 195 var escaped = escapeCName(propname);
190 this.addMessage(propname, 'va_end(args); return self->' + escaped + ';'); 196 this.addMessage(propname, {
191 this.addMessageVar(propname + '!', 'setval', 'object *'); 197 vars: {},
192 this.addMessage(propname + '!', 'setval = va_arg(args, object *); va_end(args); self->' + escaped + ' = setval; return (object *)self;'); 198 lines: [
199 'va_end(args);',
200 'return self->' + escaped + ';'
201 ]});
202 this.addMessage(propname + '!', {
203 vars: {setval: 'object *'},
204 lines: [
205 'setval = va_arg(args, object *);',
206 'va_end(args);',
207 'self->' + escaped + ' = setval;',
208 'return (object *)self;'
209 ]});
193 this.properties.push(escaped); 210 this.properties.push(escaped);
194 this.values.push(value); 211 this.values.push(value);
195 } 212 }
196 }
197
198 cObject.prototype.addMessageVar = function(msgname, varname, type) {
199 var trunc = getMethodId(msgname) & 0xF;
200 if (!(trunc in this.slotvars)) {
201 this.slotvars[trunc] = {};
202 }
203 this.slotvars[trunc][varname] = type;
204 } 213 }
205 214
206 cObject.prototype.toEarlyCDef = function() { 215 cObject.prototype.toEarlyCDef = function() {
207 var objdef = 'typedef struct {\n\tobject header;\n'; 216 var objdef = 'typedef struct {\n\tobject header;\n';
208 for (var i in this.properties) { 217 for (var i in this.properties) {
289 } 298 }
290 299
291 var toplevelcode; 300 var toplevelcode;
292 var forwarddec; 301 var forwarddec;
293 302
303 function addBinaryOp(cobject, opname, cop, objtype)
304 {
305 cobject.addMessage(opname, {
306 vars: {ret: objtype + ' *', argb: objtype +' *'},
307 lines: [
308 'argb = va_arg(args, ' + objtype + ' *);',
309 'ret = (' + objtype + ' *)make_object(&' + objtype + '_meta, NULL, 0);',
310 'ret->num = self->num ' + cop + ' argb->num;',
311 'return ret;'
312 ]
313 });
314 }
315
316 function addCompOp(cobject, opname, cop, objtype)
317 {
318 cobject.addMessage(opname, {
319 vars: {argb: objtype + ' *'},
320 lines: [
321 'argb = va_arg(args, ' + objtype + ' *);',
322 'if (self->num ' + cop + ' argb->num) {',
323 ' return mcall(METHOD_ID_TRUE, 1, main_module);',
324 '}',
325 'return mcall(METHOD_ID_FALSE, 1, main_module);'
326 ]
327 });
328 }
329
294 function makeCProg(obj) 330 function makeCProg(obj)
295 { 331 {
296 var int32 = new cObject('obj_int32'); 332 var int32 = new cObject('obj_int32');
297 int32.addProperty('num', null, 'int32_t'); 333 int32.addProperty('num', null, 'int32_t');
298 int32.addMessageVar('ADD_', 'ret', 'obj_int32 *'); 334 addBinaryOp(int32, 'ADD_', '+', 'obj_int32');
299 int32.addMessageVar('ADD_', 'argb', 'obj_int32 *'); 335 addBinaryOp(int32, 'SUB_', '-', 'obj_int32');
300 int32.addMessage('ADD_', 'argb = va_arg(args, obj_int32 *); ret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0); ret->num = self->num + argb->num; return ret;'); 336 addBinaryOp(int32, 'MUL_', '*', 'obj_int32');
301 int32.addMessageVar('SUB_', 'ret', 'obj_int32 *'); 337 addBinaryOp(int32, 'DIV_', '/', 'obj_int32');
302 int32.addMessageVar('SUB_', 'argb', 'obj_int32 *'); 338 addCompOp(int32, 'LT_', '<', 'obj_int32');
303 int32.addMessage('SUB_', 'argb = va_arg(args, obj_int32 *); ret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0); ret->num = self->num - argb->num; return ret;'); 339 addCompOp(int32, 'GT_', '>', 'obj_int32');
304 int32.addMessageVar('LT_', 'argb', 'obj_int32 *'); 340 addCompOp(int32, 'EQ_', '==', 'obj_int32');
305 int32.addMessage('LT_', 'argb = va_arg(args, obj_int32 *); if (self->num < argb->num) { return mcall(METHOD_ID_TRUE, 1, main_module); } return mcall(METHOD_ID_FALSE, 1, main_module);'); 341 addCompOp(int32, 'NEQ_', '!=', 'obj_int32');
342 addCompOp(int32, 'GEQ_', '>=', 'obj_int32');
343 addCompOp(int32, 'LEQ_', '<=', 'obj_int32');
306 forwarddec = toplevelcode = ''; 344 forwarddec = toplevelcode = '';
307 forwarddec += int32.toEarlyCDef(); 345 forwarddec += int32.toEarlyCDef();
308 toplevelcode += int32.toCDef(); 346 toplevelcode += int32.toCDef();
309 obj.populateSymbols(toplevel); 347 obj.populateSymbols(toplevel);
310 var rest = 'object * mainModule() {\n\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n'; 348 var rest = 'object * mainModule() {\n\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n';
421 return; 459 return;
422 } 460 }
423 if (this.expression instanceof lambda) { 461 if (this.expression instanceof lambda) {
424 var params = ['((object *)self)']; 462 var params = ['((object *)self)'];
425 var paramget = ''; 463 var paramget = '';
464 var messagevars = {};
426 for (var i in this.expression.args) { 465 for (var i in this.expression.args) {
427 var escaped = escapeCName(this.expression.args[i].cleanName()); 466 var escaped = escapeCName(this.expression.args[i].cleanName());
428 if (escaped != 'self') { 467 if (escaped != 'self') {
429 cobj.addMessageVar(this.symbol.name, escaped, 'object *'); 468 messagevars[escaped] = 'object *';
430 params.push(escaped); 469 params.push(escaped);
431 paramget += escaped + ' = va_arg(args, object *); '; 470 paramget += escaped + ' = va_arg(args, object *); ';
432 } 471 }
433 } 472 }
434 cobj.addMessage(this.symbol.name, paramget + 'return ccall(' + val + ', ' + params.length + (params.length ? ', ' : '') + params.join(', ') + ');'); 473 cobj.addMessage(this.symbol.name, {
474 vars: messagevars,
475 lines: [paramget + 'return ccall(' + val + ', ' + params.length + (params.length ? ', ' : '') + params.join(', ') + ');']
476 });
435 } else { 477 } else {
436 cobj.addProperty(this.symbol.name, val); 478 cobj.addProperty(this.symbol.name, val);
437 } 479 }
438 }; 480 };