diff cbackend.js @ 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 27a2167663dd
children 18ab96287c3a
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 + ')';
 		}
 	}