changeset 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 3b0503a67165
children e7be612fd3ae
files cbackend.js
diffstat 1 files changed, 64 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- 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);
 	}