changeset 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 cd41f7c22fcd
children f2cda2e6f70e
files cbackend.js compiler.js samples/osmod.tp
diffstat 3 files changed, 163 insertions(+), 13 deletions(-) [+]
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' +
--- a/compiler.js	Fri Jul 13 08:50:10 2012 -0700
+++ b/compiler.js	Fri Jul 13 10:46:27 2012 -0700
@@ -3,10 +3,17 @@
 	return str.split('\n').join('\n\t');
 }
 
+function modulefile(path, file)
+{
+	this.path = path;
+	this.file = file;
+}
+
 var toplevel = new topsymbols();
-function topsymbols()
+function topsymbols(moduledirs)
 {
 	this.names = null;
+	this.used = {};
 	var self = this;
 	if (typeof window === "object") {
 		get('/src/', function(data) {
@@ -23,6 +30,15 @@
 		});
 	} else {
 		this.names = {};
+		for (var dirnum in moduledirs) {
+			var results = os.system("ls", [moduledirs[dirnum]]).split('\n');
+			for (var i in results) {
+				var tpidx = results[i].indexOf('.tp')
+				if (tpidx > -1) {
+					this.names[results[i].substr(0, tpidx)] = new modulefile(moduledirs[dirnum], results[i]);
+				}
+			}
+		}
 	}
 }
 topsymbols.prototype.find = function(name) {
@@ -30,9 +46,10 @@
 		throw new Error('data not ready');
 	}
 	if (name in this.names) {
+		this.used[name] = true;
 		return {
 			type: 'toplevel',
-			def: null
+			def: this.names[name]
 		};
 	}
 	return null;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/osmod.tp	Fri Jul 13 10:46:27 2012 -0700
@@ -0,0 +1,11 @@
+#{
+	main <- {
+		os write: 1 "hello stdout via POSIX write\n"
+		name <- os read: 0 100
+		os write: 2 "hello " . name . " via stderr\n"
+		file <- os open: "output.txt" (os O_WRONLY) + (os O_CREAT) + (os O_TRUNC)
+		os write: file "hello file!\n"
+		os close: file
+		0
+	}
+}