# HG changeset patch # User Mike Pavone # Date 1341983361 25200 # Node ID a6bf4869fcbed10bd980f2bb7011d4cb235b2104 # Parent 3b0503a67165fff3552dda3f0f23fa36986e0faf Small refactor of built-in int32 type and added support for more operators on said type diff -r 3b0503a67165 -r a6bf4869fcbe cbackend.js --- a/cbackend.js Tue Jul 10 19:22:19 2012 -0700 +++ b/cbackend.js Tue Jul 10 22:09:21 2012 -0700 @@ -179,7 +179,13 @@ if (!(trunc in this.slots)) { this.slots[trunc] = []; } - this.slots[trunc].push([methodid, implementation, msgname]); + this.slots[trunc].push([methodid, '\t\t' + implementation.lines.join('\n\t\t') + '\n', msgname]); + if (!(trunc in this.slotvars)) { + this.slotvars[trunc] = {}; + } + for (var varname in implementation.vars) { + this.slotvars[trunc][varname] = implementation.vars[varname]; + } } cObject.prototype.addProperty = function(propname, value, type) { @@ -187,22 +193,25 @@ this.properties.push([propname, type]); } else { var escaped = escapeCName(propname); - this.addMessage(propname, 'va_end(args); return self->' + escaped + ';'); - this.addMessageVar(propname + '!', 'setval', 'object *'); - this.addMessage(propname + '!', 'setval = va_arg(args, object *); va_end(args); self->' + escaped + ' = setval; return (object *)self;'); + this.addMessage(propname, { + vars: {}, + lines: [ + 'va_end(args);', + 'return self->' + escaped + ';' + ]}); + this.addMessage(propname + '!', { + vars: {setval: 'object *'}, + lines: [ + 'setval = va_arg(args, object *);', + 'va_end(args);', + 'self->' + escaped + ' = setval;', + 'return (object *)self;' + ]}); this.properties.push(escaped); this.values.push(value); } } -cObject.prototype.addMessageVar = function(msgname, varname, type) { - var trunc = getMethodId(msgname) & 0xF; - if (!(trunc in this.slotvars)) { - this.slotvars[trunc] = {}; - } - this.slotvars[trunc][varname] = type; -} - cObject.prototype.toEarlyCDef = function() { var objdef = 'typedef struct {\n\tobject header;\n'; for (var i in this.properties) { @@ -291,18 +300,47 @@ var toplevelcode; var forwarddec; +function addBinaryOp(cobject, opname, cop, objtype) +{ + cobject.addMessage(opname, { + vars: {ret: objtype + ' *', argb: objtype +' *'}, + lines: [ + 'argb = va_arg(args, ' + objtype + ' *);', + 'ret = (' + objtype + ' *)make_object(&' + objtype + '_meta, NULL, 0);', + 'ret->num = self->num ' + cop + ' argb->num;', + 'return ret;' + ] + }); +} + +function addCompOp(cobject, opname, cop, objtype) +{ + cobject.addMessage(opname, { + vars: {argb: objtype + ' *'}, + lines: [ + 'argb = va_arg(args, ' + objtype + ' *);', + 'if (self->num ' + cop + ' argb->num) {', + ' return mcall(METHOD_ID_TRUE, 1, main_module);', + '}', + 'return mcall(METHOD_ID_FALSE, 1, main_module);' + ] + }); +} + function makeCProg(obj) { var int32 = new cObject('obj_int32'); int32.addProperty('num', null, 'int32_t'); - int32.addMessageVar('ADD_', 'ret', 'obj_int32 *'); - int32.addMessageVar('ADD_', 'argb', 'obj_int32 *'); - 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;'); - int32.addMessageVar('SUB_', 'ret', 'obj_int32 *'); - int32.addMessageVar('SUB_', 'argb', 'obj_int32 *'); - 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;'); - int32.addMessageVar('LT_', 'argb', 'obj_int32 *'); - 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);'); + addBinaryOp(int32, 'ADD_', '+', 'obj_int32'); + addBinaryOp(int32, 'SUB_', '-', 'obj_int32'); + addBinaryOp(int32, 'MUL_', '*', 'obj_int32'); + addBinaryOp(int32, 'DIV_', '/', 'obj_int32'); + addCompOp(int32, 'LT_', '<', 'obj_int32'); + addCompOp(int32, 'GT_', '>', 'obj_int32'); + addCompOp(int32, 'EQ_', '==', 'obj_int32'); + addCompOp(int32, 'NEQ_', '!=', 'obj_int32'); + addCompOp(int32, 'GEQ_', '>=', 'obj_int32'); + addCompOp(int32, 'LEQ_', '<=', 'obj_int32'); forwarddec = toplevelcode = ''; forwarddec += int32.toEarlyCDef(); toplevelcode += int32.toCDef(); @@ -423,15 +461,19 @@ if (this.expression instanceof lambda) { var params = ['((object *)self)']; var paramget = ''; + var messagevars = {}; for (var i in this.expression.args) { var escaped = escapeCName(this.expression.args[i].cleanName()); if (escaped != 'self') { - cobj.addMessageVar(this.symbol.name, escaped, 'object *'); + messagevars[escaped] = 'object *'; params.push(escaped); paramget += escaped + ' = va_arg(args, object *); '; } } - cobj.addMessage(this.symbol.name, paramget + 'return ccall(' + val + ', ' + params.length + (params.length ? ', ' : '') + params.join(', ') + ');'); + cobj.addMessage(this.symbol.name, { + vars: messagevars, + lines: [paramget + 'return ccall(' + val + ', ' + params.length + (params.length ? ', ' : '') + params.join(', ') + ');'] + }); } else { cobj.addProperty(this.symbol.name, val); }