comparison 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
comparison
equal deleted inserted replaced
47:cd41f7c22fcd 48:18ab96287c3a
79 pre = 'self->env->'; 79 pre = 'self->env->';
80 } else { 80 } else {
81 //TODO: fill this case in if necessary 81 //TODO: fill this case in if necessary
82 } 82 }
83 pre += getSymbolPrefix(info.parent); 83 pre += getSymbolPrefix(info.parent);
84 case 'toplevel':
85 pre = 'modules.';
86 modules[name] = false;
87 break;
88 case 'closedover': 84 case 'closedover':
89 pre = 'myenv->'; 85 pre = 'myenv->';
90 } 86 }
91 return pre; 87 return pre;
92 } 88 }
95 var name = this.cleanName(); 91 var name = this.cleanName();
96 var info = this.symbols.find(name); 92 var info = this.symbols.find(name);
97 if (!info) { 93 if (!info) {
98 throw new Error('symbol ' + name + ' not found'); 94 throw new Error('symbol ' + name + ' not found');
99 } 95 }
100 96 if (info.type == 'toplevel') {
97 return info.def.modulevar;
98 }
101 return getSymbolPrefix(info) + escapeCName(name); 99 return getSymbolPrefix(info) + escapeCName(name);
102 } 100 }
103 101
104 var declaredInts = {}; 102 var declaredInts = {};
105 103
199 this.name = name; 197 this.name = name;
200 this.slots = {}; 198 this.slots = {};
201 this.properties = []; 199 this.properties = [];
202 this.values = []; 200 this.values = [];
203 this.slotvars = {}; 201 this.slotvars = {};
202 this.includes = {};
203 }
204
205 cObject.prototype.addInclude = function(includefile) {
206 this.includes[includefile] = true;
204 } 207 }
205 208
206 cObject.prototype.addMessage = function(msgname, implementation) { 209 cObject.prototype.addMessage = function(msgname, implementation) {
207 var methodid = getMethodId(msgname); 210 var methodid = getMethodId(msgname);
208 var trunc = methodid & 0xF; 211 var trunc = methodid & 0xF;
244 this.values.push(value); 247 this.values.push(value);
245 } 248 }
246 } 249 }
247 250
248 cObject.prototype.toEarlyCDef = function() { 251 cObject.prototype.toEarlyCDef = function() {
252 var includes = '';
253 for (var file in this.includes) {
254 includes += '#include ' + file + '\n';
255 }
249 var objdef = 'typedef struct {\n\tobject header;\n'; 256 var objdef = 'typedef struct {\n\tobject header;\n';
250 for (var i in this.properties) { 257 for (var i in this.properties) {
251 if (this.properties[i] instanceof Array) { 258 if (this.properties[i] instanceof Array) {
252 objdef += '\t' + this.properties[i][1] + ' ' + this.properties[i][0] + ';\n'; 259 objdef += '\t' + this.properties[i][1] + ' ' + this.properties[i][0] + ';\n';
253 } else { 260 } else {
254 objdef += '\tobject * ' + this.properties[i] + ';\n' 261 objdef += '\tobject * ' + this.properties[i] + ';\n'
255 } 262 }
256 } 263 }
257 objdef += '} ' + this.name + ';\nobj_meta ' + this.name + '_meta;\n'; 264 objdef += '} ' + this.name + ';\nobj_meta ' + this.name + '_meta;\n';
258 return objdef; 265 return includes + objdef;
259 } 266 }
260 267
261 cObject.prototype.toCDef = function() { 268 cObject.prototype.toCDef = function() {
262 var slotdefs = ''; 269 var slotdefs = '';
263 var metadef = 'obj_meta ' + this.name + '_meta = {sizeof(' + this.name +'), {'; 270 var metadef = 'obj_meta ' + this.name + '_meta = {sizeof(' + this.name +'), {';
296 303
297 cObject.prototype.toCInstance = function() { 304 cObject.prototype.toCInstance = function() {
298 return 'make_object(&' + this.name + '_meta, NULL, ' + this.values.length + (this.values.length ? ', ' : '') + this.values.join(', ') + ')'; 305 return 'make_object(&' + this.name + '_meta, NULL, ' + this.values.length + (this.values.length ? ', ' : '') + this.values.join(', ') + ')';
299 } 306 }
300 307
308 cObject.prototype.toC = function() {
309 forwarddec += this.toEarlyCDef();
310 toplevelcode += this.toCDef();
311 return this.toCInstance();
312 }
313
301 var nextobject = 0; 314 var nextobject = 0;
302 315
303 object.prototype.toC = function() { 316 object.prototype.toC = function() {
304 var messages = this.messages; 317 var messages = this.messages;
305 var values = []; 318 var values = [];
327 } 340 }
328 } else { 341 } else {
329 messages[i].toCObject(me); 342 messages[i].toCObject(me);
330 } 343 }
331 } 344 }
332 345
333 forwarddec += me.toEarlyCDef(); 346 return me.toC();
334 toplevelcode += me.toCDef();
335 return me.toCInstance();
336 } 347 }
337 348
338 var toplevelcode; 349 var toplevelcode;
339 var forwarddec; 350 var forwarddec;
340 351
541 function builtinTypes() 552 function builtinTypes()
542 { 553 {
543 return [makeInt32(), makeArray(), makeString(), makelambda()]; 554 return [makeInt32(), makeArray(), makeString(), makelambda()];
544 } 555 }
545 556
557 function addBuiltinModules(toplevel)
558 {
559 var os = new cObject('mod_obj_os');
560 os.addInclude('<sys/stat.h>');
561 os.addInclude('<fcntl.h>');
562 os.addMessage('write', {
563 vars: {str: 'string *', intret: 'obj_int32 *', filedes: 'obj_int32 *'},
564 lines: [
565 'filedes = va_arg(args, obj_int32 *);',
566 'str = va_arg(args, string *);',
567 'intret = make_object(&obj_int32_meta, NULL, 0);',
568 'intret->num = write(filedes->num, str->data, str->bytes);',
569 'return intret;'
570 ]
571 });
572 os.addMessage('read', {
573 vars: {str: 'string *', size: 'obj_int32 *', filedes: 'obj_int32 *'},
574 lines: [
575 'filedes = va_arg(args, obj_int32 *);',
576 'size = va_arg(args, obj_int32 *);',
577 'str = make_object(&string_meta, NULL, 0);',
578 'str->data = malloc(size->num + 1);',
579 'str->length = str->bytes = read(filedes->num, str->data, size->num);',
580 'str->data[str->bytes+1] = 0;',
581 'return str;'
582 ]
583 });
584 os.addMessage('open', {
585 vars: {str: 'string *', flags: 'obj_int32 *', filedes: 'obj_int32 *'},
586 lines: [
587 'str = va_arg(args, string *);',
588 'flags = va_arg(args, obj_int32 *);',
589 'filedes = make_object(&obj_int32_meta, NULL, 0);',
590 'filedes->num = open(str->data, flags->num);',
591 'return filedes;'
592 ]
593 });
594 os.addMessage('close', {
595 vars: {filedes: 'obj_int32 *', intret: 'obj_int32 *'},
596 lines: [
597 'filedes = va_arg(args, obj_int32 *);',
598 'intret = make_object(&obj_int32_meta, NULL, 0);',
599 'intret->num = close(filedes->num);',
600 'return intret;'
601 ]
602 });
603 os.addMessage('O_RDONLY', {
604 vars: {intret: 'obj_int32 *'},
605 lines: [
606 'intret = make_object(&obj_int32_meta, NULL, 0);',
607 'intret->num = O_RDONLY;',
608 'return intret;'
609 ]
610 });
611 os.addMessage('O_WRONLY', {
612 vars: {intret: 'obj_int32 *'},
613 lines: [
614 'intret = make_object(&obj_int32_meta, NULL, 0);',
615 'intret->num = O_WRONLY;',
616 'return intret;'
617 ]
618 });
619 os.addMessage('O_RDWR', {
620 vars: {intret: 'obj_int32 *'},
621 lines: [
622 'intret = make_object(&obj_int32_meta, NULL, 0);',
623 'intret->num = O_RDWR;',
624 'return intret;'
625 ]
626 });
627 os.addMessage('O_CREAT', {
628 vars: {intret: 'obj_int32 *'},
629 lines: [
630 'intret = make_object(&obj_int32_meta, NULL, 0);',
631 'intret->num = O_CREAT;',
632 'return intret;'
633 ]
634 });
635 os.addMessage('O_APPEND', {
636 vars: {intret: 'obj_int32 *'},
637 lines: [
638 'intret = make_object(&obj_int32_meta, NULL, 0);',
639 'intret->num = O_APPEND;',
640 'return intret;'
641 ]
642 });
643 os.addMessage('O_TRUNC', {
644 vars: {intret: 'obj_int32 *'},
645 lines: [
646 'intret = make_object(&obj_int32_meta, NULL, 0);',
647 'intret->num = O_TRUNC;',
648 'return intret;'
649 ]
650 });
651 toplevel.names['os'] = os;
652 }
653
654 function processUsedToplevel(toplevel)
655 {
656 var ret = '';
657 var modulenum = 0;
658 for (var symbol in toplevel.used) {
659 ret += '\tmodule_' + (modulenum) + ' = ' + toplevel.names[symbol].toC() + ';\n';
660 toplevelcode += 'object * module_' + modulenum + ';\n';
661 toplevel.names[symbol].modulevar = 'module_' + (modulenum++);
662 }
663 return ret;
664 }
665
546 function makeCProg(obj) 666 function makeCProg(obj)
547 { 667 {
548 var builtins = builtinTypes(); 668 var builtins = builtinTypes();
549 forwarddec = toplevelcode = ''; 669 forwarddec = toplevelcode = '';
550 for (var i in builtins) { 670 for (var i in builtins) {
551 forwarddec += builtins[i].toEarlyCDef(); 671 forwarddec += builtins[i].toEarlyCDef();
552 toplevelcode += builtins[i].toCDef(); 672 toplevelcode += builtins[i].toCDef();
553 } 673 }
674 addBuiltinModules(toplevel);
554 obj.populateSymbols(toplevel); 675 obj.populateSymbols(toplevel);
555 var rest = 'object * mainModule() {\n\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n'; 676 var moduleinit = processUsedToplevel(toplevel);
677 var rest = 'object * mainModule() {\n' + moduleinit + '\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n';
556 return '#include "runtime/proghead.inc"\n' + 678 return '#include "runtime/proghead.inc"\n' +
557 '#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' + 679 '#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' +
558 '#define METHOD_ID_TRUE ' + getMethodId('true') + '\n' + 680 '#define METHOD_ID_TRUE ' + getMethodId('true') + '\n' +
559 '#define METHOD_ID_FALSE ' + getMethodId('false') + '\n' + 681 '#define METHOD_ID_FALSE ' + getMethodId('false') + '\n' +
560 forwarddec + toplevelcode + rest + '#include "runtime/progfoot.inc"\n'; 682 forwarddec + toplevelcode + rest + '#include "runtime/progfoot.inc"\n';