comparison cbackend.js @ 155:9de2572a34a7

Added some stuff for compiler debugging. Added unsigned integer types. Added integer size conversion methods to integer objects.
author Mike Pavone <pavone@retrodev.com>
date Sat, 10 Aug 2013 14:19:38 -0700
parents d8f92ebf1ff6
children d6e79885bd3b
comparison
equal deleted inserted replaced
154:6e579a75a0a9 155:9de2572a34a7
1 var mainModule; 1 var mainModule;
2 var modules = {}; 2 var modules = {};
3 3
4 var nextmethodId = 0; 4 var nextmethodId = 0;
5 var methodIds = {}; 5 var methodIds = {};
6 var assignNames;
6 function getMethodId(methodName) 7 function getMethodId(methodName)
7 { 8 {
8 if (!(methodName in methodIds)) { 9 if (!(methodName in methodIds)) {
9 methodIds[methodName] = nextmethodId++; 10 methodIds[methodName] = nextmethodId++;
10 11
134 }; 135 };
135 136
136 var declaredInts = {}; 137 var declaredInts = {};
137 138
138 intlit.prototype.toC = function() { 139 intlit.prototype.toC = function() {
139 var intType = 'int' + this.bits; 140 var intType = (this.unsigned ? 'u' : '') + 'int' + this.bits;
140 var str = intType + '_' + (this.val < 0 ? 'neg_' + (0-this.val).toString() : this.val.toString()); 141 var str = intType + '_' + (this.val < 0 ? 'neg_' + (0-this.val).toString() : this.val.toString());
141 if (!(str in declaredInts)) { 142 if (!(str in declaredInts)) {
142 toplevelcode += 'obj_' + intType + ' ' + str + ' = {{&obj_' + intType + '_meta, NULL}, ' + this.val.toString() + '};\n'; 143 toplevelcode += 'obj_' + intType + ' ' + str + ' = {{&obj_' + intType + '_meta, NULL}, ' + this.val.toString() + '};\n';
143 declaredInts[str] = true; 144 declaredInts[str] = true;
144 } 145 }
629 'return ' + toplevel.moduleVar('false') + ';', 630 'return ' + toplevel.moduleVar('false') + ';',
630 ] 631 ]
631 }); 632 });
632 } 633 }
633 634
634 function makeInt(bits) 635 function makeInt(bits, unsigned)
635 { 636 {
636 var typename = 'obj_int' + bits; 637 var typename = 'obj_' + (unsigned ? 'u' : '') + 'int' + bits;
637 var intObj = new cObject(typename); 638 var intObj = new cObject(typename);
638 intObj.addProperty('num', null, 'int' + bits +'_t'); 639 intObj.addProperty('num', null, (unsigned ? 'u' : '') + 'int' + bits +'_t');
639 addBinaryOp(intObj, 'ADD_', '+', typename); 640 addBinaryOp(intObj, 'ADD_', '+', typename);
640 addBinaryOp(intObj, 'SUB_', '-', typename); 641 addBinaryOp(intObj, 'SUB_', '-', typename);
641 addBinaryOp(intObj, 'MUL_', '*', typename); 642 addBinaryOp(intObj, 'MUL_', '*', typename);
642 addBinaryOp(intObj, 'DIV_', '/', typename); 643 addBinaryOp(intObj, 'DIV_', '/', typename);
643 addBinaryOp(intObj, 'MOD_', '%', typename); 644 addBinaryOp(intObj, 'MOD_', '%', typename);
658 intObj.addMessage('string', { 659 intObj.addMessage('string', {
659 vars: {str: 'string *'}, 660 vars: {str: 'string *'},
660 lines: [ 661 lines: [
661 'str = (string *)make_object(&string_meta, NULL, 0);', 662 'str = (string *)make_object(&string_meta, NULL, 0);',
662 'str->data = GC_MALLOC(' + (bits == 64 ? 21 : 12) + ');', 663 'str->data = GC_MALLOC(' + (bits == 64 ? 21 : 12) + ');',
663 'sprintf(str->data, "%' + (bits == 64 ? 'l' : '') +'d", self->num);', 664 'sprintf(str->data, "%' + (bits == 64 ? 'l' : '') + (unsigned ? 'u' : 'd') + '", self->num);',
664 'str->len = str->bytes = strlen(str->data);', 665 'str->len = str->bytes = strlen(str->data);',
665 'return &(str->header);' 666 'return &(str->header);'
666 ] 667 ]
667 }); 668 });
668 //7FFFFFFFFFFFFFFF 669 //7FFFFFFFFFFFFFFF
687 vars: {}, 688 vars: {},
688 lines: [ 689 lines: [
689 'return &(self->header);' 690 'return &(self->header);'
690 ] 691 ]
691 }); 692 });
693 var sizes = [8, 16, 32, 64];
694 var destunsigned = [false, true];
695 for (var i = 0; i < sizes.length; i++) {
696 size = sizes[i];
697 for (var j = 0; j < destunsigned.length; j++) {
698 uns = destunsigned[j];
699 if (uns == unsigned && size == bits) {
700 intObj.addMessage((uns ? 'u' : '') + 'int' + size, {
701 vars: {},
702 lines: [
703 'return &(self->header);'
704 ]
705 });
706 } else {
707 var retType = 'obj_' + (uns ? 'u' : '') + 'int' + size;
708 intObj.addMessage((uns ? 'u' : '') + 'int' + size, {
709
710 vars: {ret: retType + ' *'},
711 lines: [
712 'ret = ('+retType+' *)make_object(&' + retType +'_meta, NULL, 0);',
713 'ret->num = self->num;',
714 'return &(ret->header);'
715 ]
716 });
717 }
718 }
719 }
720
692 return intObj; 721 return intObj;
693 } 722 }
694 723
695 function makeArray() 724 function makeArray()
696 { 725 {
729 return clos; 758 return clos;
730 } 759 }
731 760
732 function builtinTypes() 761 function builtinTypes()
733 { 762 {
734 return [makeInt(64), makeInt(32), makeInt(16), makeInt(8), makeArray(), makeString(), makelambda()]; 763 return [makeInt(64, false), makeInt(32, false), makeInt(16, false), makeInt(8, false),
764 makeInt(64, true) , makeInt(32, true), makeInt(16, true), makeInt(8, true),
765 makeArray(), makeString(), makelambda()];
735 } 766 }
736 767
737 function addBuiltinModules(toplevel) 768 function addBuiltinModules(toplevel)
738 { 769 {
739 var os = new cObject('mod_obj_os'); 770 var os = new cObject('mod_obj_os');
872 } 903 }
873 904
874 for (var i = allused.length-1; i >= 0; i--) { 905 for (var i = allused.length-1; i >= 0; i--) {
875 var symbol = allused[i]; 906 var symbol = allused[i];
876 debugprint('//---module', symbol, '(' + i +')--- compile'); 907 debugprint('//---module', symbol, '(' + i +')--- compile');
908 assignNames.push(symbol);
877 ret += '\t' + toplevel.moduleVar(symbol) + ' = ' + toplevel.names[symbol].toC() + ';\n'; 909 ret += '\t' + toplevel.moduleVar(symbol) + ' = ' + toplevel.names[symbol].toC() + ';\n';
910 assignNames.pop();
878 } 911 }
879 return ret; 912 return ret;
880 } 913 }
881 914
882 function makeCProg(obj) 915 function makeCProg(obj)
883 { 916 {
884 forwarddec = toplevelcode = ''; 917 forwarddec = toplevelcode = '';
918 assignNames = [];
885 var builtins = builtinTypes(); 919 var builtins = builtinTypes();
886 for (var i in builtins) { 920 for (var i in builtins) {
887 forwarddec += builtins[i].toEarlyCDef(); 921 forwarddec += builtins[i].toEarlyCDef();
888 toplevelcode += builtins[i].toCDef(); 922 toplevelcode += builtins[i].toCDef();
889 } 923 }
907 } 941 }
908 942
909 lambda.prototype.toC = function() { 943 lambda.prototype.toC = function() {
910 var args = this.args ? this.args.slice(0, this.args.length) : []; 944 var args = this.args ? this.args.slice(0, this.args.length) : [];
911 var exprs = this.expressions; 945 var exprs = this.expressions;
912 debugprint('//', this.name); 946 var assignPath = assignNames.join('<-');
947 debugprint('//', this.name, assignPath);
948 var addedTypeDef = false;
913 if (Object.keys(this.symbols.closedover).length) { 949 if (Object.keys(this.symbols.closedover).length) {
914 this.symbols.envtype = this.name + '_env'; 950 this.symbols.envtype = this.name + '_env';
915 forwarddec += 'typedef struct ' + this.symbols.envtype + ' ' + this.symbols.envtype + ';\n' 951 forwarddec += 'typedef struct ' + this.symbols.envtype + ' ' + this.symbols.envtype + ';\n'
952 var addedTypeDef = true;
916 } 953 }
917 if (this.selftype) { 954 if (this.selftype) {
918 this.symbols.defineVar('self', this.selftype); 955 this.symbols.defineVar('self', this.selftype);
919 if (args[0] && args[0].cleanName() == 'self') { 956 if (args[0] && args[0].cleanName() == 'self') {
920 args.splice(0, 1); 957 args.splice(0, 1);
939 if (exprs.length) { 976 if (exprs.length) {
940 exprs[exprs.length-1] = 'return (object *)(' + exprs[exprs.length-1] + ');'; 977 exprs[exprs.length-1] = 'return (object *)(' + exprs[exprs.length-1] + ');';
941 } 978 }
942 979
943 if (Object.keys(this.symbols.closedover).length) { 980 if (Object.keys(this.symbols.closedover).length) {
981 if (!addedTypeDef) {
982 for (var key in this.symbols.closedover) {
983 print(key, ": ", this.symbols.closedover[key]);
984 }
985 throw new Error('this.symbols.closedover is not empty, but it was when compilation of "' + assignPaths + '" started');
986 }
944 forwarddec += 'struct ' + this.name + '_env {\n'; 987 forwarddec += 'struct ' + this.name + '_env {\n';
945 if (this.symbols.needsParentEnv) { 988 if (this.symbols.needsParentEnv) {
946 forwarddec += '\tstruct ' + this.symbols.parentEnvType() + ' * parent;\n'; 989 forwarddec += '\tstruct ' + this.symbols.parentEnvType() + ' * parent;\n';
947 } 990 }
948 for (var varname in this.symbols.closedover) { 991 for (var varname in this.symbols.closedover) {
962 } else { 1005 } else {
963 var myenvinit = ''; 1006 var myenvinit = '';
964 } 1007 }
965 forwarddec += 'object *' + this.name + ' (' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...);\n'; 1008 forwarddec += 'object *' + this.name + ' (' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...);\n';
966 1009
1010 toplevelcode += '//' + assignPath + "\n";
967 toplevelcode += 'object * ' + this.name + ' ( ' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...) {\n\tva_list args;\n' + myenvinit + '\tva_start(args, num_args);\n'; 1011 toplevelcode += 'object * ' + this.name + ' ( ' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...) {\n\tva_list args;\n' + myenvinit + '\tva_start(args, num_args);\n';
968 if (this.selftype) { 1012 if (this.selftype) {
969 var selfvar = (new symbol('self', this.symbols)).toC(); 1013 var selfvar = (new symbol('self', this.symbols)).toC();
970 if (selfvar == 'self') { 1014 if (selfvar == 'self') {
971 toplevelcode += '\t' + this.selftype + ' * self = va_arg(args, ' + this.selftype + ' *);\n'; 1015 toplevelcode += '\t' + this.selftype + ' * self = va_arg(args, ' + this.selftype + ' *);\n';
1032 1076
1033 assignment.prototype.toC = function() { 1077 assignment.prototype.toC = function() {
1034 debugprint('//assignment', this.symbol.name); 1078 debugprint('//assignment', this.symbol.name);
1035 var existing = this.symbols.find(this.symbol.name); 1079 var existing = this.symbols.find(this.symbol.name);
1036 var prefix = ''; 1080 var prefix = '';
1081 assignNames.push(this.symbol.name);
1037 var val = this.expression.toC(); 1082 var val = this.expression.toC();
1083 assignNames.pop(this.symbol.name);
1038 if (val === null) { 1084 if (val === null) {
1039 return null; 1085 return null;
1040 } 1086 }
1041 if (existing.type == 'local' && !existing.isdeclared) { 1087 if (existing.type == 'local' && !existing.isdeclared) {
1042 prefix = 'object *'; 1088 prefix = 'object *';