changeset 38:e7be612fd3ae

Very basic array support
author Mike Pavone <pavone@retrodev.com>
date Tue, 10 Jul 2012 23:09:44 -0700
parents a6bf4869fcbe
children a997e42b9051
files cbackend.js compiler.js parser.js runtime/object.h runtime/progfoot.inc
diffstat 5 files changed, 81 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/cbackend.js	Tue Jul 10 22:09:21 2012 -0700
+++ b/cbackend.js	Tue Jul 10 23:09:44 2012 -0700
@@ -108,10 +108,18 @@
 }
 
 listlit.prototype.toC = function() {
-	var ret = 'make_list(';
-	each(this.val, function(idx, el) {
-		ret += (idx ? ', ' : '') + el.toC();
-	});
+	var ret = 'make_list(' + this.val.length + ', ';
+	for (var i = 0; i < this.val.length; i++) {
+		ret += (i ? ', ' : '') + this.val[i].toC();
+	}
+	return ret + ')';
+}
+
+arraylit.prototype.toC = function() {
+	var ret = 'make_array(' + this.val.length + ', ';
+	for (var i = 0; i < this.val.length; i++) {
+		ret += (i ? ', ' : '') + this.val[i].toC();
+	}
 	return ret + ')';
 }
 
@@ -341,9 +349,33 @@
 	addCompOp(int32, 'NEQ_', '!=', 'obj_int32');
 	addCompOp(int32, 'GEQ_', '>=', 'obj_int32');
 	addCompOp(int32, 'LEQ_', '<=', 'obj_int32');
+	var array = new cObject('array');
+	array.addProperty('size', null, 'uint32_t');
+	array.addProperty('storage', null, 'uint32_t');
+	array.addProperty('data', null, 'object **');
+	array.addMessage('get', {
+		vars: {index: 'obj_int32 *'},
+		lines: [
+			'index = va_arg(args, obj_int32 *);',
+			'if (index->num >= 0 && index->num < self->size) {',
+			'	return self->data[index->num];',
+			'}',
+			'return mcall(METHOD_ID_FALSE, 1, main_module);'
+		]
+	});
+	array.addMessage('set', {
+		vars: {index: 'obj_int32 *'},
+		lines: [
+			'index = va_arg(args, obj_int32 *);',
+			'if (index->num >= 0 && index->num < self->size) {',
+			'	self->data[index->num] = va_arg(args, object *);',
+			'}',
+			'return (object *)self;'
+		]
+	});
 	forwarddec = toplevelcode = '';
-	forwarddec += int32.toEarlyCDef();
-	toplevelcode += int32.toCDef();
+	forwarddec += int32.toEarlyCDef() + array.toEarlyCDef();
+	toplevelcode += int32.toCDef() + array.toCDef();
 	obj.populateSymbols(toplevel);
 	var rest = 'object * mainModule() {\n\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n';
 	return '#include "runtime/proghead.inc"\n' +
@@ -440,13 +472,14 @@
 assignment.prototype.toC = function() {
 	var existing = this.symbols.find(this.symbol.name);
 	var prefix = '';
-	if (!existing) {
-		prefix =  'object * ';
-	}
 	var val = this.expression.toC();
 	if (val === null) {
 		return null;
 	}
+	if (existing.type == 'local' && !existing.isdeclared) {
+		prefix = 'object *';
+		this.symbols.declareVar(this.symbol.name);
+	}
 	return prefix + this.symbol.toC() + ' = ' + val;
 };
 assignment.prototype.toCObject = function(cobj) {
--- a/compiler.js	Tue Jul 10 22:09:21 2012 -0700
+++ b/compiler.js	Tue Jul 10 23:09:44 2012 -0700
@@ -107,6 +107,7 @@
 	this.parent = parent;
 	this.names = {};
 	this.closedover = {};
+	this.declared = {};
 	this.needsSelfVar = false;
 	this.passthruenv = false;
 	this.envtype = 'void';
@@ -130,7 +131,8 @@
 		}
 		return {
 			type: 'local',
-			def: this.names[name]
+			def: this.names[name],
+			isdeclared: (name in this.declared)
 		};
 	} else if(this.parent) {
 		var ret = this.parent.find(name, true);
@@ -153,6 +155,9 @@
 lsymbols.prototype.defineVar = function(name, def) {
 	this.names[name] = def;
 };
+lsymbols.prototype.declareVar = function(name) {
+	this.declared[name] = true;
+}
 lsymbols.prototype.selfVar = function() {
 	if (this.parent && this.parent instanceof lsymbols) {
 		this.parent.needsSelf();
@@ -221,9 +226,15 @@
 }
 
 listlit.prototype.populateSymbols = function(symbols) {
-	each(this.val, function(i,el) {
-		el.populateSymbols(symbols);
-	});
+	for (var i = 0; i < this.val.length; i++) {
+		this.val[i].populateSymbols(symbols);
+	}
+}
+
+arraylit.prototype.populateSymbols = function(symbols) {
+	for (var i = 0; i < this.val.length; i++) {
+		this.val[i].populateSymbols(symbols);
+	}
 }
 
 funcall.prototype.populateSymbols = function(symbols) {
--- a/parser.js	Tue Jul 10 22:09:21 2012 -0700
+++ b/parser.js	Tue Jul 10 23:09:44 2012 -0700
@@ -35,6 +35,11 @@
 	this.val = val;
 }
 
+function arraylit(val)
+{
+	this.val = val;
+}
+
 function funcall(name, args)
 {
 	this.name = name;
@@ -72,12 +77,13 @@
 'opexpr = left:addsub hws opn:("<=" / ">=" / "<" / ">" / "=") hws right:opexpr { return new op(left, opn, right); } / addsub;' +
 'addsub = left:muldiv hws opn:("+"/"-") hws right:addsub { return new op(left, opn, right); } / muldiv;'+
 'muldiv = left:primlitsym hws opn:("*"/"/") hws right:muldiv { return new op(left, opn, right); } / primlitsym;'+
-'primlitsym = hws val:(float / int / string / symbol / object / list / lambda / "(" expr:expr hws ")" { return expr; }) { return val; };' +
+'primlitsym = hws val:(float / int / string / symbol / object / array / list / lambda / "(" expr:expr hws ")" { return expr; }) { return val; };' +
 'symbol = chars:[a-zA-Z_!?@]+ trailing:(":"? [a-zA-Z_!?@0-9])* ! ":" { for (var i in trailing) { 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(""))); };' +
 'int = digits:[0-9]+ { return new intlit(parseInt(digits.join(""), 10)); };' +
 'string = "\\"" text:[^\\"]* "\\"" { return new strlit(text.join("")); };' +
 'object = "#{" ws messages:(assignment / funcall)* "}" { return new object(messages); };' +
+'array = "#[" ws els:opexpr* "]" { return new arraylit(els); };' +
 'list = "[" ws els:opexpr* "]" { return new listlit(els); };' +
 'assignment = ws sym:symbol hws "<-" expr:expr ws { return new assignment(sym, expr); }' +
 'lambda = args:((& ":") argname+  )? "{" ws exprs:(assignment / expr)* "}" { return new lambda(args[1], exprs); };' +
--- a/runtime/object.h	Tue Jul 10 22:09:21 2012 -0700
+++ b/runtime/object.h	Tue Jul 10 23:09:44 2012 -0700
@@ -36,5 +36,6 @@
 
 object * make_object(obj_meta * meta, void * parent, int num_props, ...);
 object * make_closure(void * env, closure_func func);
+object * make_array(uint32_t num_els, ...);
 
 #endif //OBJECT_H_
--- a/runtime/progfoot.inc	Tue Jul 10 22:09:21 2012 -0700
+++ b/runtime/progfoot.inc	Tue Jul 10 23:09:44 2012 -0700
@@ -1,3 +1,19 @@
+
+object * make_array(uint32_t num_els, ...)
+{
+	va_list els;
+	int i;
+	array * arr = malloc(sizeof(array));
+	arr->header.meta = &array_meta;
+	arr->header.parent = NULL;
+	arr->storage = arr->size = num_els;
+	arr->data = malloc(sizeof(object *) * num_els);
+	va_start(els, num_els);
+	for (i = 0; i < num_els; i++)
+		arr->data[i] = va_arg(els, object *);
+	va_end(els);
+	return &(arr->header);
+}
 
 int main(int argc, char ** argv)
 {