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