diff cbackend.js @ 43:27a2167663dd

Improve compiler error reporting. Fix operator associativity. Add some more string operations and a string ops sample
author Mike Pavone <pavone@retrodev.com>
date Thu, 12 Jul 2012 22:10:58 -0700
parents 4e983fe32047
children 2a9c6eed0c70
line wrap: on
line diff
--- a/cbackend.js	Thu Jul 12 20:14:15 2012 -0700
+++ b/cbackend.js	Thu Jul 12 22:10:58 2012 -0700
@@ -40,7 +40,7 @@
 }
 
 op.prototype.toC = function(isReceiver) {
-	var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_'};
+	var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_', '.': 'CAT_'};
 	var method = optoMeth[this.op];
 	return 'mcall(' + getMethodId(method) + ', 2, ' + this.left.toC() + ', ' + this.right.toC() + ')\n';
 };
@@ -122,7 +122,7 @@
 strlit.prototype.toC = function() {
 	if (!(this.val in declaredStrings)) {
 		//TODO: get the proper byte length
-		toplevelcode += 'string str_' + nextStringId + ' = {{&string_meta, NULL}, ' + this.val.length + ', ' + this.val.length + ', ' + this.val.length + ', "' + this.val.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r') + '"};\n';
+		toplevelcode += 'string str_' + nextStringId + ' = {{&string_meta, NULL}, ' + this.val.length + ', ' + this.val.length + ', "' + this.val.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r') + '"};\n';
 		declaredStrings[this.val] = nextStringId++;
 	}
 	return '((object *)&str_' + declaredStrings[this.val] + ')';
@@ -379,6 +379,16 @@
 	addCompOp(int32, 'NEQ_', '!=', 'obj_int32');
 	addCompOp(int32, 'GEQ_', '>=', 'obj_int32');
 	addCompOp(int32, 'LEQ_', '<=', 'obj_int32');
+	int32.addMessage('string', {
+		vars: {str: 'string *'},
+		lines: [
+			'str = (string *)make_object(&string_meta, NULL, 0);',
+			'str->data = malloc(12);',
+			'sprintf(str->data, "%d", self->num);',
+			'str->length = str->bytes = strlen(str->data);',
+			'return (object *)str;'
+		]
+	});
 	var array = new cObject('array');
 	array.addProperty('size', null, 'uint32_t');
 	array.addProperty('storage', null, 'uint32_t');
@@ -434,7 +444,6 @@
 	var string = new cObject('string');
 	string.addProperty('length', null, 'uint32_t');
 	string.addProperty('bytes', null, 'uint32_t');
-	string.addProperty('storage', null, 'uint32_t');
 	string.addProperty('data', null, 'char *');
 	string.addMessage('length', {
 		vars: {intret: 'obj_int32 *'},
@@ -444,6 +453,14 @@
 			'return &(intret->header);'
 		]
 	});
+	string.addMessage('byte_length', {
+		vars: {intret: 'obj_int32 *'},
+		lines: [
+			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
+			'intret->num = self->bytes;',
+			'return &(intret->header);'
+		]
+	});
 	string.addMessage('EQ_', {
 		vars: {argb: 'string *'},
 		lines: [
@@ -461,6 +478,24 @@
 			'return self;'
 		]
 	});
+	string.addMessage('string', {
+		vars: {},
+		lines: [ 'return self;' ]
+	});
+	string.addMessage('CAT_', {
+		vars: {argbo: 'object *', argb: 'string *', out: 'string *'},
+		lines: [
+			'argbo = va_arg(args, object *);',
+			'argb = mcall(' + getMethodId('string') + ', 1, argbo);',
+			'out = (string *)make_object(&string_meta, NULL, 0);',
+			'out->bytes = self->bytes + argb->bytes;',
+			'out->length = self->length + argb->length;',
+			'out->data = malloc(out->bytes+1);',
+			'memcpy(out->data, self->data, self->bytes);',
+			'memcpy(out->data + self->bytes, argb->data, argb->bytes + 1);',
+			'return out;'
+		]
+	});
 	forwarddec = toplevelcode = '';
 	forwarddec += int32.toEarlyCDef() + array.toEarlyCDef() + string.toEarlyCDef();
 	toplevelcode += int32.toCDef() + array.toCDef() + string.toCDef();