diff cbackend.js @ 286:ddf38b66b2e2

Finish support for floating point numbers in C backend
author Michael Pavone <pavone@retrodev.com>
date Tue, 22 Jul 2014 18:31:31 -0700
parents bb1539decd62
children a4c2b31acba7
line wrap: on
line diff
--- a/cbackend.js	Tue Jul 22 08:35:30 2014 -0700
+++ b/cbackend.js	Tue Jul 22 18:31:31 2014 -0700
@@ -164,7 +164,13 @@
 };
 
 floatlit.prototype.toC = function() {
-	return 'make_float(' + this.val.toString() + ')';
+	var floatType = this.bits == 32 ? 'float' : 'double';
+	var str =  floatType + '_' + (this.val < 0 ? 'neg_' + (0-this.val).toString() : this.val.toString()).replace('.', '_');
+	if (!(str in declaredInts)) {
+		toplevelcode += 'obj_float' + this.bits + ' ' + str + ' = {{&obj_float' + this.bits + '_meta, NULL}, ' + this.val.toString() + '};\n';
+		declaredInts[str] = true;
+	}
+	return '((object *)&' + str + ')';
 }
 floatlit.prototype.toCLLExpr = function(vars) {
 	return this.val.toString();
@@ -707,27 +713,40 @@
 	});
 }
 
+function addNumberOps(obj, typename)
+{
+	addBinaryOp(obj, '+', '+', typename);
+	addBinaryOp(obj, '-', '-', typename);
+	addBinaryOp(obj, '*', '*', typename);
+	addBinaryOp(obj, '/', '/', typename);
+	addCompOp(obj, '<', '<', typename);
+	addCompOp(obj, '>', '>', typename);
+	addCompOp(obj, '=', '==', typename);
+	addCompOp(obj, '!=', '!=', typename);
+	addCompOp(obj, '>=', '>=', typename);
+	addCompOp(obj, '<=', '<=', typename);
+
+	obj.addMessage('jsonEncode', {
+		vars: {},
+		lines: [
+			'return mcall(' + getMethodId('string') + ', 1, &self->header);'
+		]
+	});
+}
+
 function makeInt(bits, unsigned)
 {
 	var typename = 'obj_' + (unsigned ? 'u' : '') + 'int' + bits;
 	var intObj = new cObject(typename);
 	intObj.addProperty('num', null, (unsigned ? 'u' : '') + 'int' + bits +'_t');
-	addBinaryOp(intObj, '+', '+', typename);
-	addBinaryOp(intObj, '-', '-', typename);
-	addBinaryOp(intObj, '*', '*', typename);
-	addBinaryOp(intObj, '/', '/', typename);
+	addNumberOps(intObj, typename);
 	addBinaryOp(intObj, '%', '%', typename);
 	addBinaryOp(intObj, 'or', '|', typename);
 	addBinaryOp(intObj, 'xor', '^', typename);
 	addBinaryOp(intObj, 'and', '&', typename);
 	addBinaryOp(intObj, 'lshift:by', '<<', typename);
 	addBinaryOp(intObj, 'rshift:by', '>>', typename);
-	addCompOp(intObj, '<', '<', typename);
-	addCompOp(intObj, '>', '>', typename);
-	addCompOp(intObj, '=', '==', typename);
-	addCompOp(intObj, '!=', '!=', typename);
-	addCompOp(intObj, '>=', '>=', typename);
-	addCompOp(intObj, '<=', '<=', typename);
+
 	intObj.addInclude('<string.h>');
 	//-9223372036854775808
 	//01234567890123456789
@@ -741,12 +760,6 @@
 			'return &(str->header);'
 		]
 	});
-	intObj.addMessage('jsonEncode', {
-		vars: {},
-		lines: [
-			'return mcall(' + getMethodId('string') + ', 1, &self->header);'
-		]
-	});
 	//7FFFFFFFFFFFFFFF
 	//01234567890123456789
 	intObj.addMessage('hex', {
@@ -811,6 +824,43 @@
 	return intObj;
 }
 
+function makeFloat(bits)
+{
+	var typename = 'obj_float' + bits;
+	var floatObj = new cObject(typename);
+	floatObj.addProperty('num', null, bits == 32 ? 'float' : 'double');
+	addNumberOps(floatObj, typename);
+
+	floatObj.addInclude('<string.h>');
+	floatObj.addMessage('string', {
+		vars: {str: 'string *'},
+		lines: [
+			'str = (string *)make_object(&string_meta, NULL, 0);',
+			//probably overkill, but lets play it safe for now
+			'str->data = GC_MALLOC(128);',
+			'sprintf(str->data, "%f", self->num);',
+			'str->len = str->bytes = strlen(str->data);',
+			'return &(str->header);'
+		]
+	});
+	floatObj.addMessage('f' + bits, {
+		vars: {},
+		lines: [
+			'return &(self->header);'
+		]
+	});
+
+	floatObj.addMessage('f' + (bits == 32 ? 64 : 32), {
+		vars: {trans: 'obj_float' + (bits == 32 ? 64 : 32) + ' *'},
+		lines: [
+			'trans = make_object(&obj_float' + (bits == 32 ? 64 : 32) + '_meta, NULL, 0);',
+			'trans->num = self->num;',
+			'return &(trans->header);'
+		]
+	});
+	return floatObj;
+}
+
 function makeCPointer()
 {
 	var cptr = new cObject('cpointer');
@@ -875,7 +925,7 @@
 {
 	return [makeInt(64, false), makeInt(32, false), makeInt(16, false), makeInt(8, false),
 	        makeInt(64, true) , makeInt(32, true),  makeInt(16, true),  makeInt(8, true),
-	        makeArray(), makeString(), makelambda(), makeCPointer()];
+	        makeFloat(32), makeFloat(64), makeArray(), makeString(), makelambda(), makeCPointer()];
 }
 
 function addBuiltinModules(toplevel)