changeset 45:2a9c6eed0c70

Move closure/lambda object def into compiler rather than runtime code. Add while:do method to lambda
author Mike Pavone <pavone@retrodev.com>
date Fri, 13 Jul 2012 00:23:38 -0700
parents 9dd370530f69
children 55572bb15623
files cbackend.js runtime/object.c runtime/object.h runtime/progfoot.inc runtime/proghead.inc tpc.js
diffstat 6 files changed, 80 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/cbackend.js	Thu Jul 12 22:49:08 2012 -0700
+++ b/cbackend.js	Fri Jul 13 00:23:38 2012 -0700
@@ -365,7 +365,7 @@
 	});
 }
 
-function makeCProg(obj)
+function makeInt32()
 {
 	var int32 = new cObject('obj_int32');
 	int32.addProperty('num', null, 'int32_t');
@@ -389,6 +389,11 @@
 			'return (object *)str;'
 		]
 	});
+	return int32;
+}
+
+function makeArray()
+{
 	var array = new cObject('array');
 	array.addProperty('size', null, 'uint32_t');
 	array.addProperty('storage', null, 'uint32_t');
@@ -414,9 +419,9 @@
 		]
 	});
 	array.addMessage('foreach', {
-		vars: {index: 'obj_int32 *', i: 'int32_t', clos: 'closure *'},
+		vars: {index: 'obj_int32 *', i: 'int32_t', clos: 'lambda *'},
 		lines: [
-			'clos = va_arg(args, closure *);',
+			'clos = va_arg(args, lambda *);',
 			'for (i = 0; i < self->size; i++) {',
 			'	index = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
 			'	index->num = i;',
@@ -441,6 +446,11 @@
 			'return self;'
 		]
 	});
+	return array;
+}
+
+function makeString()
+{
 	var string = new cObject('string');
 	string.addProperty('length', null, 'uint32_t');
 	string.addProperty('bytes', null, 'uint32_t');
@@ -496,9 +506,51 @@
 			'return out;'
 		]
 	});
+	string.addMessage('byte', {
+		vars: {index: 'obj_int32 *', intret: 'obj_int32 *'},
+		lines: [
+			'index = va_arg(args, obj_int32 *);',
+			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret->num = index->num < self->bytes ? self->data[index->num] : 0;',
+			'return intret;'
+		]
+	});
+	return string;
+}
+
+function makelambda()
+{
+	var clos = new cObject('lambda');
+	clos.addProperty('env', null, 'void *');
+	clos.addProperty('func', null, 'closure_func');
+	clos.addMessage('while:do', {
+		vars: {action: 'lambda *', valtrue: 'object *', ret: 'object *'},
+		lines: [
+			'action = va_arg(args, lambda *);',
+			'valtrue = mcall(METHOD_ID_TRUE, 1, main_module);',
+			'ret = valtrue;',
+			'while(valtrue == ccall(self, 0)) {',
+			'	ccall(action, 0);',
+			'}',
+			'return ret;'
+		]
+	});
+	return clos;
+}
+
+function builtinTypes()
+{
+	return [makeInt32(), makeArray(), makeString(), makelambda()];
+}
+
+function makeCProg(obj)
+{
+	var builtins = builtinTypes();
 	forwarddec = toplevelcode = '';
-	forwarddec += int32.toEarlyCDef() + array.toEarlyCDef() + string.toEarlyCDef();
-	toplevelcode += int32.toCDef() + array.toCDef() + string.toCDef();
+	for (var i in builtins) {
+		forwarddec += builtins[i].toEarlyCDef();
+		toplevelcode += builtins[i].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' +
@@ -581,9 +633,9 @@
 			} else {
 				var envvar = 'myenv';
 			}
-			return 'make_closure(' + envvar + ', lambda_' + mynum + ')';
+			return 'make_lambda(' + envvar + ', lambda_' + mynum + ')';
 		} else {	
-			toplevelcode += 'closure lambda_obj_' + mynum + ' = {{&lambda_meta, NULL}, NULL, lambda_' + mynum + '};\n';
+			toplevelcode += 'lambda lambda_obj_' + mynum + ' = {{&lambda_meta, NULL}, NULL, lambda_' + mynum + '};\n';
 			return '((object *)&lambda_obj_' + mynum + ')';
 		}
 	}
--- a/runtime/object.c	Thu Jul 12 22:49:08 2012 -0700
+++ b/runtime/object.c	Fri Jul 13 00:23:38 2012 -0700
@@ -21,16 +21,6 @@
 	return newobj;
 }
 
-object * make_closure(void * env, closure_func func)
-{
-	closure * ret = malloc(sizeof(closure));
-	ret->header.meta = &lambda_meta;
-	ret->header.parent = NULL;
-	ret->env = env;
-	ret->func = func;
-	return (object *) ret;
-}
-
 object * mcall(uint32_t method_id, uint32_t num_args, object * self, ...)
 {
 	va_list args;
--- a/runtime/object.h	Thu Jul 12 22:49:08 2012 -0700
+++ b/runtime/object.h	Fri Jul 13 00:23:38 2012 -0700
@@ -15,14 +15,14 @@
 typedef object * (*method)(uint32_t method_id, uint32_t num_args, object * self, va_list args);
 
 typedef object * (*closure_func)(void *, uint32_t, ...);
-
+/*
 typedef struct closure
 {
 	object header;
 	void * env;
 	closure_func func;
 } closure;
-
+*/
 struct obj_meta
 {
 	uint32_t size;
@@ -32,10 +32,10 @@
 extern obj_meta lambda_meta;
 
 object * mcall(uint32_t method_id, uint32_t num_args, object * self, ...);
-#define ccall(clos, num_args, ...) (((closure *)clos)->func(((closure *)clos)->env, num_args,##__VA_ARGS__))
+#define ccall(clos, num_args, ...) (((lambda *)clos)->func(((lambda *)clos)->env, num_args,##__VA_ARGS__))
 
 object * make_object(obj_meta * meta, void * parent, int num_props, ...);
-object * make_closure(void * env, closure_func func);
+object * make_lambda(void * env, closure_func func);
 object * make_array(uint32_t num_els, ...);
 
 #endif //OBJECT_H_
--- a/runtime/progfoot.inc	Thu Jul 12 22:49:08 2012 -0700
+++ b/runtime/progfoot.inc	Fri Jul 13 00:23:38 2012 -0700
@@ -18,6 +18,16 @@
 	return &(arr->header);
 }
 
+object * make_lambda(void * env, closure_func func)
+{
+	lambda * ret = malloc(sizeof(lambda));
+	ret->header.meta = &lambda_meta;
+	ret->header.parent = NULL;
+	ret->env = env;
+	ret->func = func;
+	return (object *) ret;
+}
+
 int main(int argc, char ** argv)
 {
 	object * ret = mcall(METHOD_ID_MAIN, 1, mainModule());
--- a/runtime/proghead.inc	Thu Jul 12 22:49:08 2012 -0700
+++ b/runtime/proghead.inc	Fri Jul 13 00:23:38 2012 -0700
@@ -12,9 +12,9 @@
 	exit(0);
 	return NULL;
 }
-
+/*
 obj_meta lambda_meta = {
 	sizeof(closure), 
 	{no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, 
 	 no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl}
-};
+};*/
--- a/tpc.js	Thu Jul 12 22:49:08 2012 -0700
+++ b/tpc.js	Fri Jul 13 00:23:38 2012 -0700
@@ -17,10 +17,8 @@
 	load('compiler.js');
 	load('cbackend.js');
 	try {
-		var parsed = parser.parse(text);
-		var c = parsed.toCModule();
-		print(c);
-	} catch(error if error.name == 'SyntaxError') {
+		var parsed = parser.parse(text);	
+	} catch (e) {
 		print('SyntaxError on at', error.line, ',', error.column, ':', error.message);
 		var lines = text.split('\n');
 		print(lines[error.line-1]);
@@ -33,6 +31,8 @@
 			}
 		}
 		print(spacer + '^');
-
+		exit(1);
 	}
+	var c = parsed.toCModule();
+	print(c);
 }