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