# HG changeset patch # User Mike Pavone # Date 1342201587 25200 # Node ID 18ab96287c3a59b5f9eb3d685a6eb76104ccc7fd # Parent cd41f7c22fcdeab8e8a80a103e87383ce3201536 Add builtin module os containing some baisc POSIX file IO diff -r cd41f7c22fcd -r 18ab96287c3a cbackend.js --- 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(''); + os.addInclude(''); + 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' + diff -r cd41f7c22fcd -r 18ab96287c3a compiler.js --- 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; diff -r cd41f7c22fcd -r 18ab96287c3a samples/osmod.tp --- /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 + } +}