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 };