changeset 155:9de2572a34a7

Added some stuff for compiler debugging. Added unsigned integer types. Added integer size conversion methods to integer objects.
author Mike Pavone <pavone@retrodev.com>
date Sat, 10 Aug 2013 14:19:38 -0700
parents 6e579a75a0a9
children d6e79885bd3b
files cbackend.js parser.js samples/intsize.tp
diffstat 3 files changed, 66 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/cbackend.js	Sat Aug 10 11:51:47 2013 -0700
+++ b/cbackend.js	Sat Aug 10 14:19:38 2013 -0700
@@ -3,6 +3,7 @@
 
 var nextmethodId = 0;
 var methodIds = {};
+var assignNames;
 function getMethodId(methodName)
 {
 	if (!(methodName in methodIds)) {
@@ -136,7 +137,7 @@
 var declaredInts = {};
 
 intlit.prototype.toC = function() {
-	var intType = 'int' + this.bits;
+	var intType = (this.unsigned ? 'u' : '') + 'int' + this.bits;
 	var str =  intType + '_' + (this.val < 0 ? 'neg_' + (0-this.val).toString() : this.val.toString());
 	if (!(str in declaredInts)) {
 		toplevelcode += 'obj_' + intType + ' ' + str + ' = {{&obj_' + intType + '_meta, NULL}, ' + this.val.toString() + '};\n';
@@ -631,11 +632,11 @@
 	});
 }
 
-function makeInt(bits)
+function makeInt(bits, unsigned)
 {
-	var typename = 'obj_int' + bits;
+	var typename = 'obj_' + (unsigned ? 'u' : '') + 'int' + bits;
 	var intObj = new cObject(typename);
-	intObj.addProperty('num', null, 'int' + bits +'_t');
+	intObj.addProperty('num', null, (unsigned ? 'u' : '') + 'int' + bits +'_t');
 	addBinaryOp(intObj, 'ADD_', '+', typename);
 	addBinaryOp(intObj, 'SUB_', '-', typename);
 	addBinaryOp(intObj, 'MUL_', '*', typename);
@@ -660,7 +661,7 @@
 		lines: [
 			'str = (string *)make_object(&string_meta, NULL, 0);',
 			'str->data = GC_MALLOC(' + (bits == 64 ? 21 : 12) + ');',
-			'sprintf(str->data, "%' + (bits == 64 ? 'l' : '') +'d", self->num);',
+			'sprintf(str->data, "%' + (bits == 64 ? 'l' : '') + (unsigned ? 'u' : 'd') + '", self->num);',
 			'str->len = str->bytes = strlen(str->data);',
 			'return &(str->header);'
 		]
@@ -689,6 +690,34 @@
 			'return &(self->header);'
 		]
 	});
+	var sizes = [8, 16, 32, 64];
+	var destunsigned = [false, true];
+	for (var i = 0; i < sizes.length; i++) {
+		size = sizes[i];
+		for (var j = 0; j < destunsigned.length; j++) {
+			uns = destunsigned[j];
+			if (uns == unsigned && size == bits) {
+				intObj.addMessage((uns ? 'u' : '') + 'int' + size, {
+					vars: {},
+					lines: [
+						'return &(self->header);'
+					]
+				});
+			} else {
+				var retType = 'obj_' + (uns ? 'u' : '') + 'int' + size;
+				intObj.addMessage((uns ? 'u' : '') + 'int' + size, {
+
+					vars: {ret: retType + ' *'},
+					lines: [
+						'ret = ('+retType+' *)make_object(&' + retType +'_meta, NULL, 0);',
+						'ret->num = self->num;',
+						'return &(ret->header);'
+					]
+				});
+			}
+		}
+	}
+
 	return intObj;
 }
 
@@ -731,7 +760,9 @@
 
 function builtinTypes()
 {
-	return [makeInt(64), makeInt(32), makeInt(16), makeInt(8), makeArray(), makeString(), makelambda()];
+	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()];
 }
 
 function addBuiltinModules(toplevel)
@@ -874,7 +905,9 @@
 	for (var i = allused.length-1; i >= 0; i--) {
 		var symbol = allused[i];
 		debugprint('//---module', symbol, '(' + i +')--- compile');
+		assignNames.push(symbol);
 		ret += '\t' + toplevel.moduleVar(symbol) + ' = ' + toplevel.names[symbol].toC() + ';\n';
+		assignNames.pop();
 	}
 	return ret;
 }
@@ -882,6 +915,7 @@
 function makeCProg(obj)
 {
 	forwarddec = toplevelcode = '';
+	assignNames = [];
 	var builtins = builtinTypes();
 	for (var i in builtins) {
 		forwarddec += builtins[i].toEarlyCDef();
@@ -909,10 +943,13 @@
 lambda.prototype.toC = function() {
 	var args = this.args ? this.args.slice(0, this.args.length) : [];
 	var exprs = this.expressions;
-	debugprint('//', this.name);
+	var assignPath = assignNames.join('<-');
+	debugprint('//', this.name, assignPath);
+	var addedTypeDef = false;
 	if (Object.keys(this.symbols.closedover).length) {
 		this.symbols.envtype = this.name + '_env';
 		forwarddec += 'typedef struct ' + this.symbols.envtype + '  ' + this.symbols.envtype + ';\n'
+		var addedTypeDef = true;
 	}
 	if (this.selftype) {
 		this.symbols.defineVar('self', this.selftype);
@@ -941,6 +978,12 @@
 	}
 
 	if (Object.keys(this.symbols.closedover).length) {
+		if (!addedTypeDef) {
+			for (var key in this.symbols.closedover) {
+				print(key, ": ", this.symbols.closedover[key]);
+			}
+			throw new Error('this.symbols.closedover is not empty, but it was when compilation of "' + assignPaths + '" started');
+		}
 		forwarddec += 'struct ' + this.name + '_env {\n';
 		if (this.symbols.needsParentEnv) {
 			forwarddec += '\tstruct ' + this.symbols.parentEnvType() + ' * parent;\n';
@@ -964,6 +1007,7 @@
 	}
 	forwarddec += 'object *' + this.name + ' (' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...);\n';
 
+	toplevelcode += '//' + assignPath + "\n";
 	toplevelcode +=  'object * ' + this.name + ' ( ' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...) {\n\tva_list args;\n' + myenvinit + '\tva_start(args, num_args);\n';
 	if (this.selftype) {
 		var selfvar = (new symbol('self', this.symbols)).toC();
@@ -1034,7 +1078,9 @@
 	debugprint('//assignment', this.symbol.name);
 	var existing = this.symbols.find(this.symbol.name);
 	var prefix = '';
+	assignNames.push(this.symbol.name);
 	var val = this.expression.toC();
+	assignNames.pop(this.symbol.name);
 	if (val === null) {
 		return null;
 	}
--- a/parser.js	Sat Aug 10 11:51:47 2013 -0700
+++ b/parser.js	Sat Aug 10 14:19:38 2013 -0700
@@ -15,11 +15,15 @@
 	return this.name[0] == ':' ? this.name.substr(1) : this.name;
 }
 
-function intlit(val, bits)
+function intlit(val, bits, unsigned)
 {
 	if (!bits) {
 		bits = 32;
 	}
+	if (unsigned === undefined) {
+		unsigned = false;
+	}
+	this.unsigned = unsigned;
 	this.bits = bits;
 	this.val = val;
 }
@@ -87,8 +91,8 @@
 'symbol = chars:[a-zA-Z_!?@]+ trailing:(":"? [a-zA-Z_!?@0-9])* ! ":" { for (var i = 0; i < trailing.length; i++) { trailing[i] = trailing[i].join(""); } return new symbol(chars.join("") + trailing.join("")); };' +
 'float = digits:[0-9]+ "." decimals:[0-9]+ { return new floatlit(parseFloat(digits.join("") + "." + decimals.join(""))); };' +
 'binary = "0b" digits:[01]+ { return new intlit(parseInt(digits.join(""), 2)); };' +
-'hex = "0x" digits:[0-9a-fA-F]+ size:("i" ("8" / "16" / "32" / "64"))? { var bits = size ? parseInt(size[1], 10) : 0; return new intlit(parseInt(digits.join(""), 16), bits); };' +
-'int = sign:"-"? digits:[0-9]+ size:("i" ("8" / "16" / "32" / "64"))? { var bits = size ? parseInt(size[1], 10) : 0; return new intlit(parseInt(sign + digits.join(""), 10), bits); };' +
+'hex = "0x" digits:[0-9a-fA-F]+ size:([iu] ("8" / "16" / "32" / "64"))? { var bits = size ? parseInt(size[1], 10) : 0; return new intlit(parseInt(digits.join(""), 16), bits, size[0] == "u"); };' +
+'int = sign:"-"? digits:[0-9]+ size:([iu] ("8" / "16" / "32" / "64"))? { var bits = size ? parseInt(size[1], 10) : 0; return new intlit(parseInt(sign + digits.join(""), 10), bits, size[0] == "u"); };' +
 'string = "\\"" text:(strpart/escape)* "\\"" { return new strlit(text.join("")); };' +
 'strpart = text:[^\\"\\\\]+ { return text.join(""); };' +
 'escape = "\\\\" char:[nt\\"r\\\\] { if (char == "n") { return "\\n"; } if (char == "r") { return "\\r"; } return char; };' +
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/intsize.tp	Sat Aug 10 14:19:38 2013 -0700
@@ -0,0 +1,6 @@
+#{
+	main <- {
+		print: (string: (int8: 255)) . "\n"
+		print: (string: 255u8) . "\n"
+	}
+}