diff cbackend.js @ 48:18ab96287c3a

Add builtin module os containing some baisc POSIX file IO
author Mike Pavone <pavone@retrodev.com>
date Fri, 13 Jul 2012 10:46:27 -0700
parents 2a9c6eed0c70
children f2cda2e6f70e
line wrap: on
line diff
--- a/cbackend.js	Fri Jul 13 08:50:10 2012 -0700
+++ b/cbackend.js	Fri Jul 13 10:46:27 2012 -0700
@@ -81,10 +81,6 @@
 			//TODO: fill this case in if necessary
 		}
 		pre += getSymbolPrefix(info.parent);
-	case 'toplevel':
-		pre = 'modules.';
-		modules[name] = false;
-		break;
 	case 'closedover':
 		pre = 'myenv->';
 	}
@@ -97,7 +93,9 @@
 	if (!info) {
 		throw new Error('symbol ' + name + ' not found');
 	}
-	
+	if (info.type == 'toplevel') {
+		return info.def.modulevar;
+	}
 	return getSymbolPrefix(info) + escapeCName(name);
 }
 
@@ -201,6 +199,11 @@
 	this.properties = [];
 	this.values = [];
 	this.slotvars = {};
+	this.includes = {};
+}
+
+cObject.prototype.addInclude = function(includefile) {
+	this.includes[includefile] = true;
 }
 
 cObject.prototype.addMessage = function(msgname, implementation) {
@@ -246,6 +249,10 @@
 }
 
 cObject.prototype.toEarlyCDef = function() {
+	var includes = '';
+	for (var file in this.includes) {
+		includes += '#include ' + file + '\n';
+	}
 	var objdef =  'typedef struct {\n\tobject header;\n';
 	for (var i in this.properties) {
 		if (this.properties[i] instanceof Array) {
@@ -255,7 +262,7 @@
 		}
 	}
 	objdef += '} ' + this.name + ';\nobj_meta ' + this.name + '_meta;\n';
-	return objdef;
+	return includes + objdef;
 }
 
 cObject.prototype.toCDef = function() {
@@ -298,6 +305,12 @@
 	return 'make_object(&' + this.name + '_meta, NULL, ' + this.values.length + (this.values.length ? ', ' : '') + this.values.join(', ') + ')';
 }
 
+cObject.prototype.toC = function() {
+	forwarddec += this.toEarlyCDef();
+	toplevelcode += this.toCDef();
+	return this.toCInstance();
+}
+
 var nextobject = 0;
 
 object.prototype.toC = function() {
@@ -329,10 +342,8 @@
 			messages[i].toCObject(me);
 		}
 	}
-	
-	forwarddec += me.toEarlyCDef();
-	toplevelcode += me.toCDef();
-	return me.toCInstance();
+
+	return me.toC();
 }
 
 var toplevelcode;
@@ -543,6 +554,115 @@
 	return [makeInt32(), makeArray(), makeString(), makelambda()];
 }
 
+function addBuiltinModules(toplevel)
+{
+	var os = new cObject('mod_obj_os');
+	os.addInclude('<sys/stat.h>');
+	os.addInclude('<fcntl.h>');
+	os.addMessage('write', {
+		vars: {str: 'string *', intret: 'obj_int32 *', filedes: 'obj_int32 *'},
+		lines: [
+			'filedes = va_arg(args, obj_int32 *);',
+			'str = va_arg(args, string *);',
+			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret->num = write(filedes->num, str->data, str->bytes);',
+			'return intret;'
+		]
+	});
+	os.addMessage('read', {
+		vars: {str: 'string *', size: 'obj_int32 *', filedes: 'obj_int32 *'},
+		lines: [
+			'filedes = va_arg(args, obj_int32 *);',
+			'size = va_arg(args, obj_int32 *);',
+			'str = make_object(&string_meta, NULL, 0);',
+			'str->data = malloc(size->num + 1);',
+			'str->length = str->bytes = read(filedes->num, str->data, size->num);',
+			'str->data[str->bytes+1] = 0;',
+			'return str;'
+		]
+	});
+	os.addMessage('open', {
+		vars: {str: 'string *', flags: 'obj_int32 *', filedes: 'obj_int32 *'},
+		lines: [
+			'str = va_arg(args, string *);',
+			'flags = va_arg(args, obj_int32 *);',
+			'filedes = make_object(&obj_int32_meta, NULL, 0);',
+			'filedes->num = open(str->data, flags->num);',
+			'return filedes;'
+		]
+	});
+	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->num = close(filedes->num);',
+			'return intret;'
+		]
+	});
+	os.addMessage('O_RDONLY', {
+		vars: {intret: 'obj_int32 *'},
+		lines: [
+			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret->num = O_RDONLY;',
+			'return intret;'
+		]
+	});
+	os.addMessage('O_WRONLY', {
+		vars: {intret: 'obj_int32 *'},
+		lines: [
+			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret->num = O_WRONLY;',
+			'return intret;'
+		]
+	});
+	os.addMessage('O_RDWR', {
+		vars: {intret: 'obj_int32 *'},
+		lines: [
+			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret->num = O_RDWR;',
+			'return intret;'
+		]
+	});
+	os.addMessage('O_CREAT', {
+		vars: {intret: 'obj_int32 *'},
+		lines: [
+			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret->num = O_CREAT;',
+			'return intret;'
+		]
+	});
+	os.addMessage('O_APPEND', {
+		vars: {intret: 'obj_int32 *'},
+		lines: [
+			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret->num = O_APPEND;',
+			'return intret;'
+		]
+	});
+	os.addMessage('O_TRUNC', {
+		vars: {intret: 'obj_int32 *'},
+		lines: [
+			'intret = make_object(&obj_int32_meta, NULL, 0);',
+			'intret->num = O_TRUNC;',
+			'return intret;'
+		]
+	});
+	toplevel.names['os'] = os;
+}
+
+function processUsedToplevel(toplevel)
+{
+	var ret = '';
+	var modulenum = 0;
+	for (var symbol in toplevel.used) {
+		ret += '\tmodule_' + (modulenum) + ' = ' + toplevel.names[symbol].toC() + ';\n';
+		toplevelcode += 'object * module_' + modulenum + ';\n';
+		toplevel.names[symbol].modulevar = 'module_' + (modulenum++);
+	}
+	return ret;
+}
+
 function makeCProg(obj)
 {
 	var builtins = builtinTypes();
@@ -551,8 +671,10 @@
 		forwarddec += builtins[i].toEarlyCDef();
 		toplevelcode += builtins[i].toCDef();
 	}
+	addBuiltinModules(toplevel);
 	obj.populateSymbols(toplevel);
-	var rest = 'object * mainModule() {\n\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n';
+	var moduleinit = processUsedToplevel(toplevel);
+	var rest = 'object * mainModule() {\n' + moduleinit + '\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n';
 	return '#include "runtime/proghead.inc"\n' +
 		'#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' +
 		'#define METHOD_ID_TRUE ' + getMethodId('true') + '\n' +