Mercurial > repos > tabletprog
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'; |