Mercurial > repos > tabletprog
comparison cbackend.js @ 59:0fd06e077afe
Fix object parent
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 14 Jul 2012 01:39:43 -0700 |
parents | 7b454d100dc8 |
children | ef3b34c2c0a4 |
comparison
equal
deleted
inserted
replaced
58:7b454d100dc8 | 59:0fd06e077afe |
---|---|
40 } | 40 } |
41 | 41 |
42 op.prototype.toC = function(isReceiver) { | 42 op.prototype.toC = function(isReceiver) { |
43 var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_', '.': 'CAT_'}; | 43 var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_', '.': 'CAT_'}; |
44 var method = optoMeth[this.op]; | 44 var method = optoMeth[this.op]; |
45 return 'mcall(' + getMethodId(method) + ', 2, (object *)' + this.left.toC() + ', ' + this.right.toC() + ')\n'; | 45 return 'mcall(' + getMethodId(method) + '/* ' + method + ' */, 2, (object *)' + this.left.toC() + ', ' + this.right.toC() + ')\n'; |
46 }; | 46 }; |
47 | 47 |
48 function escapeCName(name) | 48 function escapeCName(name) |
49 { | 49 { |
50 if (name == 'self') { | 50 if (name == 'self') { |
186 for (var i in args) { | 186 for (var i in args) { |
187 args[i] = ', ' + args[i].toC(); | 187 args[i] = ', ' + args[i].toC(); |
188 } | 188 } |
189 var callpart; | 189 var callpart; |
190 if (method) { | 190 if (method) { |
191 callpart = 'mcall(' + getMethodId(name); | 191 callpart = 'mcall(' + getMethodId(name) + '/* ' + name + ' */'; |
192 } else { | 192 } else { |
193 callpart = 'ccall(' + (new symbol(name, this.symbols)).toC(); | 193 callpart = 'ccall(' + (new symbol(name, this.symbols)).toC(); |
194 } | 194 } |
195 return callpart + ', ' + args.length + args.join('') + ')'; | 195 return callpart + ', ' + args.length + args.join('') + ')'; |
196 } | 196 } |
200 this.slots = {}; | 200 this.slots = {}; |
201 this.properties = []; | 201 this.properties = []; |
202 this.values = []; | 202 this.values = []; |
203 this.slotvars = {}; | 203 this.slotvars = {}; |
204 this.includes = {}; | 204 this.includes = {}; |
205 this.parent = 'NULL'; | |
206 this.init = []; | |
207 this.initmsgadded = false; | |
205 } | 208 } |
206 | 209 |
207 cObject.prototype.addInclude = function(includefile) { | 210 cObject.prototype.addInclude = function(includefile) { |
208 this.includes[includefile] = true; | 211 this.includes[includefile] = true; |
209 } | 212 } |
232 } else { | 235 } else { |
233 var escaped = escapeCName(propname); | 236 var escaped = escapeCName(propname); |
234 this.addMessage(propname, { | 237 this.addMessage(propname, { |
235 vars: {}, | 238 vars: {}, |
236 lines: [ | 239 lines: [ |
237 'va_end(args);', | |
238 'return self->' + escaped + ';' | 240 'return self->' + escaped + ';' |
239 ]}); | 241 ]}); |
240 this.addMessage(propname + '!', { | 242 this.addMessage(propname + '!', { |
241 vars: {setval: 'object *'}, | 243 vars: {}, |
242 lines: [ | 244 lines: [ |
243 'setval = va_arg(args, object *);', | 245 'self->' + escaped + ' = va_arg(args, object *);', |
244 'va_end(args);', | |
245 'self->' + escaped + ' = setval;', | |
246 'return (object *)self;' | 246 'return (object *)self;' |
247 ]}); | 247 ]}); |
248 this.properties.push(escaped); | 248 this.properties.push(escaped); |
249 this.values.push(value); | 249 this.values.push(value); |
250 } | 250 } |
251 } | 251 } |
252 | 252 |
253 cObject.prototype.addInit = function(statement) { | |
254 this.init.push(statement); | |
255 } | |
256 | |
257 cObject.prototype.checkInitMsg = function() { | |
258 if (!this.initmsgadded && this.init.length) { | |
259 var init = this.init.slice(0, this.init.length); | |
260 init.push('return (object *)self;'); | |
261 this.addMessage('_init', { | |
262 vars: {}, | |
263 lines: init | |
264 }); | |
265 this.initmsgadded = true; | |
266 } | |
267 } | |
268 | |
269 | |
253 cObject.prototype.toEarlyCDef = function() { | 270 cObject.prototype.toEarlyCDef = function() { |
271 this.checkInitMsg(); | |
254 var includes = ''; | 272 var includes = ''; |
255 for (var file in this.includes) { | 273 for (var file in this.includes) { |
256 includes += '#include ' + file + '\n'; | 274 includes += '#include ' + file + '\n'; |
257 } | 275 } |
258 var objdef = 'typedef struct ' + this.name + ' {\n\tobject header;\n'; | 276 var objdef = 'typedef struct ' + this.name + ' {\n\tobject header;\n'; |
266 objdef += '} ' + this.name + ';\nobj_meta ' + this.name + '_meta;\n'; | 284 objdef += '} ' + this.name + ';\nobj_meta ' + this.name + '_meta;\n'; |
267 return includes + objdef; | 285 return includes + objdef; |
268 } | 286 } |
269 | 287 |
270 cObject.prototype.toCDef = function() { | 288 cObject.prototype.toCDef = function() { |
289 this.checkInitMsg(); | |
271 var slotdefs = ''; | 290 var slotdefs = ''; |
272 var metadef = 'obj_meta ' + this.name + '_meta = {sizeof(' + this.name +'), {'; | 291 var metadef = 'obj_meta ' + this.name + '_meta = {sizeof(' + this.name +'), {'; |
273 for (var i = 0; i < 16; i++) { | 292 for (var i = 0; i < 16; i++) { |
274 if (i) { | 293 if (i) { |
275 metadef += ', '; | 294 metadef += ', '; |
303 metadef += '}};\n'; | 322 metadef += '}};\n'; |
304 return slotdefs + metadef; | 323 return slotdefs + metadef; |
305 } | 324 } |
306 | 325 |
307 cObject.prototype.toCInstance = function() { | 326 cObject.prototype.toCInstance = function() { |
308 return 'make_object(&' + this.name + '_meta, NULL, ' + this.values.length + (this.values.length ? ', ' : '') + this.values.join(', ') + ')'; | 327 this.checkInitMsg(); |
328 var ret = 'make_object(&' + this.name + '_meta, ' + this.parent + ', ' + this.values.length + (this.values.length ? ', ' : '') + this.values.join(', ') + ')'; | |
329 if (this.initmsgadded) { | |
330 ret = 'mcall(' + getMethodId('_init') + ', 1, ' + ret + ')' | |
331 } | |
332 return ret; | |
309 } | 333 } |
310 | 334 |
311 cObject.prototype.toC = function() { | 335 cObject.prototype.toC = function() { |
312 forwarddec += this.toEarlyCDef(); | 336 forwarddec += this.toEarlyCDef(); |
313 toplevelcode += this.toCDef(); | 337 toplevelcode += this.toCDef(); |
323 var me = new cObject('object_' + nextobject++); | 347 var me = new cObject('object_' + nextobject++); |
324 this.symbols.typename = me.name; | 348 this.symbols.typename = me.name; |
325 if (this.symbols.needsenv) { | 349 if (this.symbols.needsenv) { |
326 me.addProperty('env', this.symbols.envVar(), 'struct ' + this.symbols.getEnvType() + ' * '); | 350 me.addProperty('env', this.symbols.envVar(), 'struct ' + this.symbols.getEnvType() + ' * '); |
327 me.hasenv = true; | 351 me.hasenv = true; |
352 } | |
353 if (this.symbols.needsparent && !(this.symbols.parent instanceof osymbols)) { | |
354 me.parent = '(object *)(' + (new symbol('self', this.symbols.parent)).toC() + ')'; | |
328 } | 355 } |
329 for (var i in messages) { | 356 for (var i in messages) { |
330 if (messages[i] instanceof funcall) { | 357 if (messages[i] instanceof funcall) { |
331 if (messages[i].name == 'import:' && messages[i].args.length == 1) { | 358 if (messages[i].name == 'import:' && messages[i].args.length == 1) { |
332 imports.push({symbols: false, src: messages[i].args[0]}); | 359 imports.push({symbols: false, src: messages[i].args[0]}); |
463 ] | 490 ] |
464 }); | 491 }); |
465 array.addMessage('length', { | 492 array.addMessage('length', { |
466 vars: {intret: 'obj_int32 *'}, | 493 vars: {intret: 'obj_int32 *'}, |
467 lines: [ | 494 lines: [ |
468 'intret = make_object(&obj_int32_meta, NULL, 0);', | 495 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', |
469 'intret->num = self->size;', | 496 'intret->num = self->size;', |
470 'return intret;' | 497 'return &(intret->header);' |
471 ] | 498 ] |
472 }); | 499 }); |
473 return array; | 500 return array; |
474 } | 501 } |
475 | 502 |
585 os.addMessage('write', { | 612 os.addMessage('write', { |
586 vars: {str: 'string *', intret: 'obj_int32 *', filedes: 'obj_int32 *'}, | 613 vars: {str: 'string *', intret: 'obj_int32 *', filedes: 'obj_int32 *'}, |
587 lines: [ | 614 lines: [ |
588 'filedes = va_arg(args, obj_int32 *);', | 615 'filedes = va_arg(args, obj_int32 *);', |
589 'str = va_arg(args, string *);', | 616 'str = va_arg(args, string *);', |
590 'intret = make_object(&obj_int32_meta, NULL, 0);', | 617 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', |
591 'intret->num = write(filedes->num, str->data, str->bytes);', | 618 'intret->num = write(filedes->num, str->data, str->bytes);', |
592 'return intret;' | 619 'return &(intret->header);' |
593 ] | 620 ] |
594 }); | 621 }); |
595 os.addMessage('read', { | 622 os.addMessage('read', { |
596 vars: {str: 'string *', size: 'obj_int32 *', filedes: 'obj_int32 *'}, | 623 vars: {str: 'string *', size: 'obj_int32 *', filedes: 'obj_int32 *'}, |
597 lines: [ | 624 lines: [ |
598 'filedes = va_arg(args, obj_int32 *);', | 625 'filedes = va_arg(args, obj_int32 *);', |
599 'size = va_arg(args, obj_int32 *);', | 626 'size = va_arg(args, obj_int32 *);', |
600 'str = make_object(&string_meta, NULL, 0);', | 627 'str = (string *)make_object(&string_meta, NULL, 0);', |
601 'str->data = malloc(size->num + 1);', | 628 'str->data = malloc(size->num + 1);', |
602 'str->length = str->bytes = read(filedes->num, str->data, size->num);', | 629 'str->length = str->bytes = read(filedes->num, str->data, size->num);', |
603 'if (str->bytes < 0) { str->bytes = str->length = 0; }', | 630 'if (str->bytes < 0) { str->bytes = str->length = 0; }', |
604 'str->data[str->bytes] = 0;', | 631 'str->data[str->bytes] = 0;', |
605 'return str;' | 632 'return &(str->header);' |
606 ] | 633 ] |
607 }); | 634 }); |
608 os.addMessage('open', { | 635 os.addMessage('open', { |
609 vars: {str: 'string *', flags: 'obj_int32 *', filedes: 'obj_int32 *', perm: 'obj_int32 *'}, | 636 vars: {str: 'string *', flags: 'obj_int32 *', filedes: 'obj_int32 *', perm: 'obj_int32 *'}, |
610 lines: [ | 637 lines: [ |
611 'str = va_arg(args, string *);', | 638 'str = va_arg(args, string *);', |
612 'flags = va_arg(args, obj_int32 *);', | 639 'flags = va_arg(args, obj_int32 *);', |
613 'filedes = make_object(&obj_int32_meta, NULL, 0);', | 640 'filedes = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', |
614 'if (num_params == 3) {', | 641 'if (num_params == 3) {', |
615 ' filedes->num = open(str->data, flags->num);', | 642 ' filedes->num = open(str->data, flags->num);', |
616 '} else if (num_params == 4) {', | 643 '} else if (num_params == 4) {', |
617 ' perm = va_arg(args, obj_int32 *);', | 644 ' perm = va_arg(args, obj_int32 *);', |
618 ' filedes->num = open(str->data, flags->num, perm->num);', | 645 ' filedes->num = open(str->data, flags->num, perm->num);', |
619 '} else {', | 646 '} else {', |
620 ' filedes->num = -1;', | 647 ' filedes->num = -1;', |
621 '}', | 648 '}', |
622 'return filedes;' | 649 'return &(filedes->header);' |
623 ] | 650 ] |
624 }); | 651 }); |
625 os.addMessage('close', { | 652 os.addMessage('close', { |
626 vars: {filedes: 'obj_int32 *', intret: 'obj_int32 *'}, | 653 vars: {filedes: 'obj_int32 *', intret: 'obj_int32 *'}, |
627 lines: [ | 654 lines: [ |
628 'filedes = va_arg(args, obj_int32 *);', | 655 'filedes = va_arg(args, obj_int32 *);', |
629 'intret = make_object(&obj_int32_meta, NULL, 0);', | 656 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', |
630 'intret->num = close(filedes->num);', | 657 'intret->num = close(filedes->num);', |
631 'return intret;' | 658 'return &(intret->header);' |
632 ] | 659 ] |
633 }); | 660 }); |
634 os.addMessage('O_RDONLY', { | 661 os.addMessage('O_RDONLY', { |
635 vars: {intret: 'obj_int32 *'}, | 662 vars: {intret: 'obj_int32 *'}, |
636 lines: [ | 663 lines: [ |
637 'intret = make_object(&obj_int32_meta, NULL, 0);', | 664 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', |
638 'intret->num = O_RDONLY;', | 665 'intret->num = O_RDONLY;', |
639 'return intret;' | 666 'return &(intret->header);' |
640 ] | 667 ] |
641 }); | 668 }); |
642 os.addMessage('O_WRONLY', { | 669 os.addMessage('O_WRONLY', { |
643 vars: {intret: 'obj_int32 *'}, | 670 vars: {intret: 'obj_int32 *'}, |
644 lines: [ | 671 lines: [ |
645 'intret = make_object(&obj_int32_meta, NULL, 0);', | 672 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', |
646 'intret->num = O_WRONLY;', | 673 'intret->num = O_WRONLY;', |
647 'return intret;' | 674 'return &(intret->header);' |
648 ] | 675 ] |
649 }); | 676 }); |
650 os.addMessage('O_RDWR', { | 677 os.addMessage('O_RDWR', { |
651 vars: {intret: 'obj_int32 *'}, | 678 vars: {intret: 'obj_int32 *'}, |
652 lines: [ | 679 lines: [ |
653 'intret = make_object(&obj_int32_meta, NULL, 0);', | 680 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', |
654 'intret->num = O_RDWR;', | 681 'intret->num = O_RDWR;', |
655 'return intret;' | 682 'return &(intret->header);' |
656 ] | 683 ] |
657 }); | 684 }); |
658 os.addMessage('O_CREAT', { | 685 os.addMessage('O_CREAT', { |
659 vars: {intret: 'obj_int32 *'}, | 686 vars: {intret: 'obj_int32 *'}, |
660 lines: [ | 687 lines: [ |
661 'intret = make_object(&obj_int32_meta, NULL, 0);', | 688 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', |
662 'intret->num = O_CREAT;', | 689 'intret->num = O_CREAT;', |
663 'return intret;' | 690 'return &(intret->header);' |
664 ] | 691 ] |
665 }); | 692 }); |
666 os.addMessage('O_APPEND', { | 693 os.addMessage('O_APPEND', { |
667 vars: {intret: 'obj_int32 *'}, | 694 vars: {intret: 'obj_int32 *'}, |
668 lines: [ | 695 lines: [ |
669 'intret = make_object(&obj_int32_meta, NULL, 0);', | 696 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', |
670 'intret->num = O_APPEND;', | 697 'intret->num = O_APPEND;', |
671 'return intret;' | 698 'return &(intret->header);' |
672 ] | 699 ] |
673 }); | 700 }); |
674 os.addMessage('O_TRUNC', { | 701 os.addMessage('O_TRUNC', { |
675 vars: {intret: 'obj_int32 *'}, | 702 vars: {intret: 'obj_int32 *'}, |
676 lines: [ | 703 lines: [ |
677 'intret = make_object(&obj_int32_meta, NULL, 0);', | 704 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', |
678 'intret->num = O_TRUNC;', | 705 'intret->num = O_TRUNC;', |
679 'return intret;' | 706 'return &(intret->header);' |
680 ] | 707 ] |
681 }); | 708 }); |
682 toplevel.names['os'] = os; | 709 toplevel.names['os'] = os; |
683 } | 710 } |
684 | 711 |
856 vars: messagevars, | 883 vars: messagevars, |
857 lines: [paramget + 'return ' + val + '(' + (cobj.hasenv ? 'self->env' : 'NULL') + ', ' + params.length + (params.length ? ', ' : '') + params.join(', ') + ');'] | 884 lines: [paramget + 'return ' + val + '(' + (cobj.hasenv ? 'self->env' : 'NULL') + ', ' + params.length + (params.length ? ', ' : '') + params.join(', ') + ');'] |
858 }); | 885 }); |
859 } else { | 886 } else { |
860 cobj.addProperty(this.symbol.name, val); | 887 cobj.addProperty(this.symbol.name, val); |
888 if (this.expression instanceof object && this.expression.symbols.needsparent) { | |
889 cobj.addInit('self->' + escapeCName(this.symbol.name) + '->parent = self;'); | |
890 } | |
861 } | 891 } |
862 }; | 892 }; |