changeset 59:0fd06e077afe

Fix object parent
author Mike Pavone <pavone@retrodev.com>
date Sat, 14 Jul 2012 01:39:43 -0700
parents 7b454d100dc8
children ef3b34c2c0a4
files cbackend.js compiler.js
diffstat 2 files changed, 63 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/cbackend.js	Sat Jul 14 00:35:50 2012 -0700
+++ b/cbackend.js	Sat Jul 14 01:39:43 2012 -0700
@@ -42,7 +42,7 @@
 op.prototype.toC = function(isReceiver) {
 	var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_', '.': 'CAT_'};
 	var method = optoMeth[this.op];
-	return 'mcall(' + getMethodId(method) + ', 2, (object *)' + this.left.toC() + ', ' + this.right.toC() + ')\n';
+	return 'mcall(' + getMethodId(method) + '/* ' + method + ' */, 2, (object *)' + this.left.toC() + ', ' + this.right.toC() + ')\n';
 };
 
 function escapeCName(name)
@@ -188,7 +188,7 @@
 	}
 	var callpart;
 	if (method) {
-		callpart = 'mcall(' + getMethodId(name);
+		callpart = 'mcall(' + getMethodId(name) + '/* ' + name + ' */';
 	} else {
 		callpart = 'ccall(' + (new symbol(name, this.symbols)).toC();
 	}
@@ -202,6 +202,9 @@
 	this.values = [];
 	this.slotvars = {};
 	this.includes = {};
+	this.parent = 'NULL';
+	this.init = [];
+	this.initmsgadded = false;
 }
 
 cObject.prototype.addInclude = function(includefile) {
@@ -234,15 +237,12 @@
 		this.addMessage(propname, {
 			vars: {},
 			lines: [
-				'va_end(args);',
 				'return self->' + escaped + ';'
 		]});
 		this.addMessage(propname + '!', {
-			vars: {setval: 'object *'},
+			vars: {},
 			lines: [
-				'setval = va_arg(args, object *);',
-				'va_end(args);',
-				'self->' + escaped + ' = setval;',
+				'self->' + escaped + ' = va_arg(args, object *);',
 				'return (object *)self;'
 		]});
 		this.properties.push(escaped);
@@ -250,7 +250,25 @@
 	}
 }
 
+cObject.prototype.addInit = function(statement) {
+	this.init.push(statement);
+}
+
+cObject.prototype.checkInitMsg = function() {
+	if (!this.initmsgadded && this.init.length) {
+		var init = this.init.slice(0, this.init.length);
+		init.push('return (object *)self;');
+		this.addMessage('_init', {
+			vars: {},
+			lines: init
+		});		
+		this.initmsgadded = true;
+	}
+}
+
+
 cObject.prototype.toEarlyCDef = function() {
+	this.checkInitMsg();
 	var includes = '';
 	for (var file in this.includes) {
 		includes += '#include ' + file + '\n';
@@ -268,6 +286,7 @@
 }
 
 cObject.prototype.toCDef = function() {
+	this.checkInitMsg();
 	var slotdefs = '';
 	var metadef = 'obj_meta ' + this.name + '_meta = {sizeof(' + this.name +'), {';
 	for (var i = 0; i < 16; i++) {
@@ -305,7 +324,12 @@
 }
 
 cObject.prototype.toCInstance = function() {
-	return 'make_object(&' + this.name + '_meta, NULL, ' + this.values.length + (this.values.length ? ', ' : '') + this.values.join(', ') + ')';
+	this.checkInitMsg();
+	var ret = 'make_object(&' + this.name + '_meta, ' + this.parent + ', ' + this.values.length + (this.values.length ? ', ' : '') + this.values.join(', ') + ')';
+	if (this.initmsgadded) {
+		ret = 'mcall(' + getMethodId('_init') + ', 1, ' + ret + ')'
+	}
+	return ret;
 }
 
 cObject.prototype.toC = function() {
@@ -326,6 +350,9 @@
 		me.addProperty('env', this.symbols.envVar(), 'struct ' + this.symbols.getEnvType() + ' * ');
 		me.hasenv = true;
 	}
+	if (this.symbols.needsparent && !(this.symbols.parent instanceof osymbols)) {
+		me.parent = '(object *)(' + (new symbol('self', this.symbols.parent)).toC() + ')';
+	}
 	for (var i in messages) {
 		if (messages[i] instanceof funcall) {
 			if (messages[i].name == 'import:' && messages[i].args.length == 1) {
@@ -465,9 +492,9 @@
 	array.addMessage('length', {
 		vars: {intret: 'obj_int32 *'},
 		lines: [
-			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
 			'intret->num = self->size;',
-			'return intret;'
+			'return &(intret->header);'
 		]
 	});
 	return array;
@@ -587,9 +614,9 @@
 		lines: [
 			'filedes = va_arg(args, obj_int32 *);',
 			'str = va_arg(args, string *);',
-			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
 			'intret->num = write(filedes->num, str->data, str->bytes);',
-			'return intret;'
+			'return &(intret->header);'
 		]
 	});
 	os.addMessage('read', {
@@ -597,12 +624,12 @@
 		lines: [
 			'filedes = va_arg(args, obj_int32 *);',
 			'size = va_arg(args, obj_int32 *);',
-			'str = make_object(&string_meta, NULL, 0);',
+			'str = (string *)make_object(&string_meta, NULL, 0);',
 			'str->data = malloc(size->num + 1);',
 			'str->length = str->bytes = read(filedes->num, str->data, size->num);',
 			'if (str->bytes < 0) { str->bytes = str->length = 0; }',
 			'str->data[str->bytes] = 0;',
-			'return str;'
+			'return &(str->header);'
 		]
 	});
 	os.addMessage('open', {
@@ -610,7 +637,7 @@
 		lines: [
 			'str = va_arg(args, string *);',
 			'flags = va_arg(args, obj_int32 *);',
-			'filedes = make_object(&obj_int32_meta, NULL, 0);',
+			'filedes = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
 			'if (num_params == 3) {',
 			'	filedes->num = open(str->data, flags->num);',
 			'} else if (num_params == 4) {',
@@ -619,64 +646,64 @@
 			'} else {',
 			'	filedes->num = -1;',
 			'}',
-			'return filedes;'
+			'return &(filedes->header);'
 		]
 	});
 	os.addMessage('close', {
 		vars: {filedes: 'obj_int32 *', intret: 'obj_int32 *'},
 		lines: [
 			'filedes = va_arg(args, obj_int32 *);',
-			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
 			'intret->num = close(filedes->num);',
-			'return intret;'
+			'return &(intret->header);'
 		]
 	});
 	os.addMessage('O_RDONLY', {
 		vars: {intret: 'obj_int32 *'},
 		lines: [
-			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
 			'intret->num = O_RDONLY;',
-			'return intret;'
+			'return &(intret->header);'
 		]
 	});
 	os.addMessage('O_WRONLY', {
 		vars: {intret: 'obj_int32 *'},
 		lines: [
-			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
 			'intret->num = O_WRONLY;',
-			'return intret;'
+			'return &(intret->header);'
 		]
 	});
 	os.addMessage('O_RDWR', {
 		vars: {intret: 'obj_int32 *'},
 		lines: [
-			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
 			'intret->num = O_RDWR;',
-			'return intret;'
+			'return &(intret->header);'
 		]
 	});
 	os.addMessage('O_CREAT', {
 		vars: {intret: 'obj_int32 *'},
 		lines: [
-			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
 			'intret->num = O_CREAT;',
-			'return intret;'
+			'return &(intret->header);'
 		]
 	});
 	os.addMessage('O_APPEND', {
 		vars: {intret: 'obj_int32 *'},
 		lines: [
-			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
 			'intret->num = O_APPEND;',
-			'return intret;'
+			'return &(intret->header);'
 		]
 	});
 	os.addMessage('O_TRUNC', {
 		vars: {intret: 'obj_int32 *'},
 		lines: [
-			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
 			'intret->num = O_TRUNC;',
-			'return intret;'
+			'return &(intret->header);'
 		]
 	});
 	toplevel.names['os'] = os;
@@ -858,5 +885,8 @@
 		});
 	} else {
 		cobj.addProperty(this.symbol.name, val);
+		if (this.expression instanceof object && this.expression.symbols.needsparent) {
+			cobj.addInit('self->' + escapeCName(this.symbol.name) + '->parent = self;');
+		}
 	}
 };
--- a/compiler.js	Sat Jul 14 00:35:50 2012 -0700
+++ b/compiler.js	Sat Jul 14 01:39:43 2012 -0700
@@ -67,6 +67,7 @@
 	this.names = {};
 	this.needsenv = false;
 	this.typename = null;
+	this.needsparent = false;
 }
 osymbols.prototype.find = function(name, nestedcall) {
 	debugprint('//osymbols.find', name + ', exists?:', name in this.names, ', nested?:', nestedcall);
@@ -88,7 +89,9 @@
 			if(ret.type == 'self') {
 				ret.type = 'parent';
 				ret.depth = 1;
+				this.needsparent = true;
 			} else if(ret.type == 'parent') {
+				this.needsparent = true;
 				ret.depth++;
 			} else if(ret.type == 'closedover' || ret.type == 'upvar') {
 				this.needsenv = true;