comparison cbackend.js @ 121:1a4446f573d3

Add isInteger? method to the int32 type in the C backend
author Mike Pavone <pavone@retrodev.com>
date Thu, 01 Aug 2013 19:10:48 -0700
parents 59a94f3ad56f
children 9820ecd4eed4
comparison
equal deleted inserted replaced
120:d5dc9507d612 121:1a4446f573d3
5 var methodIds = {}; 5 var methodIds = {};
6 function getMethodId(methodName) 6 function getMethodId(methodName)
7 { 7 {
8 if (!(methodName in methodIds)) { 8 if (!(methodName in methodIds)) {
9 methodIds[methodName] = nextmethodId++; 9 methodIds[methodName] = nextmethodId++;
10 10
11 } 11 }
12 return methodIds[methodName]; 12 return methodIds[methodName];
13 } 13 }
14 14
15 op.prototype.toC = function(isReceiver) { 15 op.prototype.toC = function(isReceiver) {
39 function getSymbolPrefix(info, symbols) 39 function getSymbolPrefix(info, symbols)
40 { 40 {
41 var pre = ''; 41 var pre = '';
42 switch(info.type) { 42 switch(info.type) {
43 case 'self': 43 case 'self':
44 44
45 pre = (new symbol('self', symbols)).toC() + '->'; 45 pre = (new symbol('self', symbols)).toC() + '->';
46 break; 46 break;
47 case 'parent': 47 case 'parent':
48 pre = (new symbol('self', symbols)).toC() + '->header.'; 48 pre = (new symbol('self', symbols)).toC() + '->header.';
49 for (var i = 0; i < info.depth; ++i) { 49 for (var i = 0; i < info.depth; ++i) {
418 var init = this.init.slice(0, this.init.length); 418 var init = this.init.slice(0, this.init.length);
419 init.push('return (object *)self;'); 419 init.push('return (object *)self;');
420 this.addMessage('_init', { 420 this.addMessage('_init', {
421 vars: {}, 421 vars: {},
422 lines: init 422 lines: init
423 }); 423 });
424 this.initmsgadded = true; 424 this.initmsgadded = true;
425 } 425 }
426 } 426 }
427 427
428 cObject.prototype.populateSymbols = function() {}; 428 cObject.prototype.populateSymbols = function() {};
459 for (var varname in this.slotvars[i]) { 459 for (var varname in this.slotvars[i]) {
460 slotdefs += '\t' + this.slotvars[i][varname] + ' ' + varname + ';\n'; 460 slotdefs += '\t' + this.slotvars[i][varname] + ' ' + varname + ';\n';
461 } 461 }
462 if (this.slots[i].length == 1) { 462 if (this.slots[i].length == 1) {
463 slotdefs += '\tif (method_id == ' + this.slots[i][0][0] + ') { /* ' + this.slots[i][0][2] + '*/\n' + 463 slotdefs += '\tif (method_id == ' + this.slots[i][0][0] + ') { /* ' + this.slots[i][0][2] + '*/\n' +
464 '\t\t' + this.slots[i][0][1] + '\n' + 464 '\t\t' + this.slots[i][0][1] + '\n' +
465 '\t}\n' + 465 '\t}\n' +
466 '\treturn no_impl(method_id, num_params, (object *)self, args);\n}\n'; 466 '\treturn no_impl(method_id, num_params, (object *)self, args);\n}\n';
467 } else { 467 } else {
468 slotdefs += '\tswitch(method_id) {\n'; 468 slotdefs += '\tswitch(method_id) {\n';
469 for (j in this.slots[i]) { 469 for (j in this.slots[i]) {
470 slotdefs += '\t\tcase ' + this.slots[i][j][0] + ': /* ' + this.slots[i][j][2] + '*/\n' + 470 slotdefs += '\t\tcase ' + this.slots[i][j][0] + ': /* ' + this.slots[i][j][2] + '*/\n' +
471 '\t\t\t' + this.slots[i][j][1] + '\n'; 471 '\t\t\t' + this.slots[i][j][1] + '\n';
472 } 472 }
473 slotdefs += '\t\tdefault:\n' + 473 slotdefs += '\t\tdefault:\n' +
474 '\t\t\treturn no_impl(method_id, num_params, (object *)self, args);\n\t}\n}\n'; 474 '\t\t\treturn no_impl(method_id, num_params, (object *)self, args);\n\t}\n}\n';
475 475
476 } 476 }
477 metadef += this.name + '_slot_' + i; 477 metadef += this.name + '_slot_' + i;
478 } else { 478 } else {
479 metadef += 'no_impl'; 479 metadef += 'no_impl';
480 } 480 }
542 me.addMessage(msgname, { 542 me.addMessage(msgname, {
543 vars: vars, 543 vars: vars,
544 lines: messages[i].args[2].toCLines(vars, true) 544 lines: messages[i].args[2].toCLines(vars, true)
545 }); 545 });
546 } else { 546 } else {
547 547
548 throw new Error('Only import and import:from calls allowed in object context. ' + messages[i].name + 'with ' + messages[i].args.length + ' arguments found instead.'); 548 throw new Error('Only import and import:from calls allowed in object context. ' + messages[i].name + 'with ' + messages[i].args.length + ' arguments found instead.');
549 } 549 }
550 } else { 550 } else {
551 messages[i].toCObject(me); 551 messages[i].toCObject(me);
552 } 552 }
613 'sprintf(str->data, "%d", self->num);', 613 'sprintf(str->data, "%d", self->num);',
614 'str->len = str->bytes = strlen(str->data);', 614 'str->len = str->bytes = strlen(str->data);',
615 'return &(str->header);' 615 'return &(str->header);'
616 ] 616 ]
617 }); 617 });
618 int32.addMessage('isInteger?', {
619 vars: {},
620 lines: [
621 'return ' + toplevel.moduleVar('true') + ';'
622 ]
623 });
618 int32.addMessage('hash', { 624 int32.addMessage('hash', {
619 vars: {}, 625 vars: {},
620 lines: [ 626 lines: [
621 'return &(self->header);' 627 'return &(self->header);'
622 ] 628 ]
774 modulefile.prototype.toC = function(){ 780 modulefile.prototype.toC = function(){
775 return this.ast.toCModuleInstance(); 781 return this.ast.toCModuleInstance();
776 }; 782 };
777 783
778 function processUsedToplevel(toplevel) 784 function processUsedToplevel(toplevel)
779 { 785 {
780 var alwaysused = ['true', 'false']; 786 var alwaysused = ['true', 'false'];
781 var ret = ''; 787 var ret = '';
782 var modulenum = 0; 788 var modulenum = 0;
783 var visited = {}; 789 var visited = {};
784 for (var i in alwaysused) { 790 for (var i in alwaysused) {
800 newused.push(symbol); 806 newused.push(symbol);
801 allused.push(symbol); 807 allused.push(symbol);
802 } 808 }
803 } 809 }
804 } 810 }
805 811
806 for (var i = allused.length-1; i >= 0; i--) { 812 for (var i = allused.length-1; i >= 0; i--) {
807 var symbol = allused[i]; 813 var symbol = allused[i];
808 debugprint('//---module', symbol, '(' + i +')--- compile'); 814 debugprint('//---module', symbol, '(' + i +')--- compile');
809 ret += '\t' + toplevel.moduleVar(symbol) + ' = ' + toplevel.names[symbol].toC() + ';\n'; 815 ret += '\t' + toplevel.moduleVar(symbol) + ' = ' + toplevel.names[symbol].toC() + ';\n';
810 } 816 }
855 } else { 861 } else {
856 var offset = 0; 862 var offset = 0;
857 } 863 }
858 for (var i = 0; i < args.length; ++i) { 864 for (var i = 0; i < args.length; ++i) {
859 var argname = args[i].toC(); 865 var argname = args[i].toC();
860 866
861 args[i] = (argname.indexOf('->') < 0 ? '\tobject * ' : '\t') + argname + ' = va_arg(args, object *);\n'; 867 args[i] = (argname.indexOf('->') < 0 ? '\tobject * ' : '\t') + argname + ' = va_arg(args, object *);\n';
862 } 868 }
863 var compiled = [] 869 var compiled = []
864 for (var i in exprs) { 870 for (var i in exprs) {
865 var js = exprs[i].toC(); 871 var js = exprs[i].toC();
869 } 875 }
870 exprs = compiled; 876 exprs = compiled;
871 if (exprs.length) { 877 if (exprs.length) {
872 exprs[exprs.length-1] = 'return (object *)(' + exprs[exprs.length-1] + ');'; 878 exprs[exprs.length-1] = 'return (object *)(' + exprs[exprs.length-1] + ');';
873 } 879 }
874 880
875 if (Object.keys(this.symbols.closedover).length) { 881 if (Object.keys(this.symbols.closedover).length) {
876 forwarddec += 'struct ' + this.name + '_env {\n'; 882 forwarddec += 'struct ' + this.name + '_env {\n';
877 if (this.symbols.needsParentEnv) { 883 if (this.symbols.needsParentEnv) {
878 forwarddec += '\tstruct ' + this.symbols.parentEnvType() + ' * parent;\n'; 884 forwarddec += '\tstruct ' + this.symbols.parentEnvType() + ' * parent;\n';
879 } 885 }
883 } else { 889 } else {
884 forwarddec += '\tobject * ' + escapeCName(varname) + ';\n'; 890 forwarddec += '\tobject * ' + escapeCName(varname) + ';\n';
885 } 891 }
886 } 892 }
887 forwarddec += '};\n' 893 forwarddec += '};\n'
888 894
889 var myenvinit = '\t' + this.name + '_env * myenv = GC_MALLOC(sizeof(' + this.name + '_env));\n'; 895 var myenvinit = '\t' + this.name + '_env * myenv = GC_MALLOC(sizeof(' + this.name + '_env));\n';
890 if (this.symbols.needsParentEnv) { 896 if (this.symbols.needsParentEnv) {
891 myenvinit += '\tmyenv->parent = env;\n'; 897 myenvinit += '\tmyenv->parent = env;\n';
892 } 898 }
893 this.symbols.envtype = this.name + '_env'; 899 this.symbols.envtype = this.name + '_env';
894 } else { 900 } else {
895 var myenvinit = ''; 901 var myenvinit = '';
896 } 902 }
897 forwarddec += 'object *' + this.name + ' (' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...);\n'; 903 forwarddec += 'object *' + this.name + ' (' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...);\n';
898 904
899 toplevelcode += 'object * ' + this.name + ' ( ' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...) {\n\tva_list args;\n' + myenvinit + '\tva_start(args, num_args);\n'; 905 toplevelcode += 'object * ' + this.name + ' ( ' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...) {\n\tva_list args;\n' + myenvinit + '\tva_start(args, num_args);\n';
900 if (this.selftype) { 906 if (this.selftype) {
901 var selfvar = (new symbol('self', this.symbols)).toC(); 907 var selfvar = (new symbol('self', this.symbols)).toC();
902 if (selfvar == 'self') { 908 if (selfvar == 'self') {
903 toplevelcode += '\t' + this.selftype + ' * self = va_arg(args, ' + this.selftype + ' *);\n'; 909 toplevelcode += '\t' + this.selftype + ' * self = va_arg(args, ' + this.selftype + ' *);\n';
904 } else { 910 } else {
905 toplevelcode += '\t' + selfvar + ' = va_arg(args, ' + this.selftype + ' *);\n'; 911 toplevelcode += '\t' + selfvar + ' = va_arg(args, ' + this.selftype + ' *);\n';
906 } 912 }
907 913
908 } 914 }
909 toplevelcode += args.join('') + '\tva_end(args);\n' + exprs.join(';\n\t') + '\n}\n'; 915 toplevelcode += args.join('') + '\tva_end(args);\n' + exprs.join(';\n\t') + '\n}\n';
910 916
911 if (this.selftype) { 917 if (this.selftype) {
912 return this.name; 918 return this.name;
913 } else { 919 } else {
914 if (this.symbols.parentEnvType() != 'void') { 920 if (this.symbols.parentEnvType() != 'void') {
915 if (this.symbols.parent.passthruenv) { 921 if (this.symbols.parent.passthruenv) {
917 } else { 923 } else {
918 var envvar = 'myenv'; 924 var envvar = 'myenv';
919 } 925 }
920 debugprint('//' + this.name, 'has envvar:', envvar, 'num vars closed over:', Object.keys(this.symbols.closedover).length); 926 debugprint('//' + this.name, 'has envvar:', envvar, 'num vars closed over:', Object.keys(this.symbols.closedover).length);
921 return 'make_lambda(' + envvar + ', (closure_func)' + this.name + ')'; 927 return 'make_lambda(' + envvar + ', (closure_func)' + this.name + ')';
922 } else { 928 } else {
923 toplevelcode += 'lambda ' + this.name + '_obj = {{&lambda_meta, NULL}, NULL, lambda_' + mynum + '};\n'; 929 toplevelcode += 'lambda ' + this.name + '_obj = {{&lambda_meta, NULL}, NULL, lambda_' + mynum + '};\n';
924 return '((object *)&' + this.name + '_obj)'; 930 return '((object *)&' + this.name + '_obj)';
925 } 931 }
926 } 932 }
927 }; 933 };