Mercurial > repos > tabletprog
comparison cbackend.js @ 286:ddf38b66b2e2
Finish support for floating point numbers in C backend
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 22 Jul 2014 18:31:31 -0700 |
parents | bb1539decd62 |
children | a4c2b31acba7 |
comparison
equal
deleted
inserted
replaced
285:bb1539decd62 | 286:ddf38b66b2e2 |
---|---|
162 intlit.prototype.toCLines = function(vars, needsreturn) { | 162 intlit.prototype.toCLines = function(vars, needsreturn) { |
163 return [ (needsreturn ? 'return (object *)' : '' ) + this.toCLLExpr(vars) + ';' ]; | 163 return [ (needsreturn ? 'return (object *)' : '' ) + this.toCLLExpr(vars) + ';' ]; |
164 }; | 164 }; |
165 | 165 |
166 floatlit.prototype.toC = function() { | 166 floatlit.prototype.toC = function() { |
167 return 'make_float(' + this.val.toString() + ')'; | 167 var floatType = this.bits == 32 ? 'float' : 'double'; |
168 var str = floatType + '_' + (this.val < 0 ? 'neg_' + (0-this.val).toString() : this.val.toString()).replace('.', '_'); | |
169 if (!(str in declaredInts)) { | |
170 toplevelcode += 'obj_float' + this.bits + ' ' + str + ' = {{&obj_float' + this.bits + '_meta, NULL}, ' + this.val.toString() + '};\n'; | |
171 declaredInts[str] = true; | |
172 } | |
173 return '((object *)&' + str + ')'; | |
168 } | 174 } |
169 floatlit.prototype.toCLLExpr = function(vars) { | 175 floatlit.prototype.toCLLExpr = function(vars) { |
170 return this.val.toString(); | 176 return this.val.toString(); |
171 }; | 177 }; |
172 floatlit.prototype.toCLines = function(vars, needsreturn) { | 178 floatlit.prototype.toCLines = function(vars, needsreturn) { |
705 'return ' + toplevel.moduleVar('false') + ';', | 711 'return ' + toplevel.moduleVar('false') + ';', |
706 ] | 712 ] |
707 }); | 713 }); |
708 } | 714 } |
709 | 715 |
716 function addNumberOps(obj, typename) | |
717 { | |
718 addBinaryOp(obj, '+', '+', typename); | |
719 addBinaryOp(obj, '-', '-', typename); | |
720 addBinaryOp(obj, '*', '*', typename); | |
721 addBinaryOp(obj, '/', '/', typename); | |
722 addCompOp(obj, '<', '<', typename); | |
723 addCompOp(obj, '>', '>', typename); | |
724 addCompOp(obj, '=', '==', typename); | |
725 addCompOp(obj, '!=', '!=', typename); | |
726 addCompOp(obj, '>=', '>=', typename); | |
727 addCompOp(obj, '<=', '<=', typename); | |
728 | |
729 obj.addMessage('jsonEncode', { | |
730 vars: {}, | |
731 lines: [ | |
732 'return mcall(' + getMethodId('string') + ', 1, &self->header);' | |
733 ] | |
734 }); | |
735 } | |
736 | |
710 function makeInt(bits, unsigned) | 737 function makeInt(bits, unsigned) |
711 { | 738 { |
712 var typename = 'obj_' + (unsigned ? 'u' : '') + 'int' + bits; | 739 var typename = 'obj_' + (unsigned ? 'u' : '') + 'int' + bits; |
713 var intObj = new cObject(typename); | 740 var intObj = new cObject(typename); |
714 intObj.addProperty('num', null, (unsigned ? 'u' : '') + 'int' + bits +'_t'); | 741 intObj.addProperty('num', null, (unsigned ? 'u' : '') + 'int' + bits +'_t'); |
715 addBinaryOp(intObj, '+', '+', typename); | 742 addNumberOps(intObj, typename); |
716 addBinaryOp(intObj, '-', '-', typename); | |
717 addBinaryOp(intObj, '*', '*', typename); | |
718 addBinaryOp(intObj, '/', '/', typename); | |
719 addBinaryOp(intObj, '%', '%', typename); | 743 addBinaryOp(intObj, '%', '%', typename); |
720 addBinaryOp(intObj, 'or', '|', typename); | 744 addBinaryOp(intObj, 'or', '|', typename); |
721 addBinaryOp(intObj, 'xor', '^', typename); | 745 addBinaryOp(intObj, 'xor', '^', typename); |
722 addBinaryOp(intObj, 'and', '&', typename); | 746 addBinaryOp(intObj, 'and', '&', typename); |
723 addBinaryOp(intObj, 'lshift:by', '<<', typename); | 747 addBinaryOp(intObj, 'lshift:by', '<<', typename); |
724 addBinaryOp(intObj, 'rshift:by', '>>', typename); | 748 addBinaryOp(intObj, 'rshift:by', '>>', typename); |
725 addCompOp(intObj, '<', '<', typename); | 749 |
726 addCompOp(intObj, '>', '>', typename); | |
727 addCompOp(intObj, '=', '==', typename); | |
728 addCompOp(intObj, '!=', '!=', typename); | |
729 addCompOp(intObj, '>=', '>=', typename); | |
730 addCompOp(intObj, '<=', '<=', typename); | |
731 intObj.addInclude('<string.h>'); | 750 intObj.addInclude('<string.h>'); |
732 //-9223372036854775808 | 751 //-9223372036854775808 |
733 //01234567890123456789 | 752 //01234567890123456789 |
734 intObj.addMessage('string', { | 753 intObj.addMessage('string', { |
735 vars: {str: 'string *'}, | 754 vars: {str: 'string *'}, |
737 'str = (string *)make_object(&string_meta, NULL, 0);', | 756 'str = (string *)make_object(&string_meta, NULL, 0);', |
738 'str->data = GC_MALLOC(' + (bits == 64 ? 21 : 12) + ');', | 757 'str->data = GC_MALLOC(' + (bits == 64 ? 21 : 12) + ');', |
739 'sprintf(str->data, "%' + (bits == 64 ? 'l' : '') + (unsigned ? 'u' : 'd') + '", self->num);', | 758 'sprintf(str->data, "%' + (bits == 64 ? 'l' : '') + (unsigned ? 'u' : 'd') + '", self->num);', |
740 'str->len = str->bytes = strlen(str->data);', | 759 'str->len = str->bytes = strlen(str->data);', |
741 'return &(str->header);' | 760 'return &(str->header);' |
742 ] | |
743 }); | |
744 intObj.addMessage('jsonEncode', { | |
745 vars: {}, | |
746 lines: [ | |
747 'return mcall(' + getMethodId('string') + ', 1, &self->header);' | |
748 ] | 761 ] |
749 }); | 762 }); |
750 //7FFFFFFFFFFFFFFF | 763 //7FFFFFFFFFFFFFFF |
751 //01234567890123456789 | 764 //01234567890123456789 |
752 intObj.addMessage('hex', { | 765 intObj.addMessage('hex', { |
809 } | 822 } |
810 | 823 |
811 return intObj; | 824 return intObj; |
812 } | 825 } |
813 | 826 |
827 function makeFloat(bits) | |
828 { | |
829 var typename = 'obj_float' + bits; | |
830 var floatObj = new cObject(typename); | |
831 floatObj.addProperty('num', null, bits == 32 ? 'float' : 'double'); | |
832 addNumberOps(floatObj, typename); | |
833 | |
834 floatObj.addInclude('<string.h>'); | |
835 floatObj.addMessage('string', { | |
836 vars: {str: 'string *'}, | |
837 lines: [ | |
838 'str = (string *)make_object(&string_meta, NULL, 0);', | |
839 //probably overkill, but lets play it safe for now | |
840 'str->data = GC_MALLOC(128);', | |
841 'sprintf(str->data, "%f", self->num);', | |
842 'str->len = str->bytes = strlen(str->data);', | |
843 'return &(str->header);' | |
844 ] | |
845 }); | |
846 floatObj.addMessage('f' + bits, { | |
847 vars: {}, | |
848 lines: [ | |
849 'return &(self->header);' | |
850 ] | |
851 }); | |
852 | |
853 floatObj.addMessage('f' + (bits == 32 ? 64 : 32), { | |
854 vars: {trans: 'obj_float' + (bits == 32 ? 64 : 32) + ' *'}, | |
855 lines: [ | |
856 'trans = make_object(&obj_float' + (bits == 32 ? 64 : 32) + '_meta, NULL, 0);', | |
857 'trans->num = self->num;', | |
858 'return &(trans->header);' | |
859 ] | |
860 }); | |
861 return floatObj; | |
862 } | |
863 | |
814 function makeCPointer() | 864 function makeCPointer() |
815 { | 865 { |
816 var cptr = new cObject('cpointer'); | 866 var cptr = new cObject('cpointer'); |
817 cptr.addProperty('val', null, 'void *'); | 867 cptr.addProperty('val', null, 'void *'); |
818 //cpointer: | 868 //cpointer: |
873 | 923 |
874 function builtinTypes() | 924 function builtinTypes() |
875 { | 925 { |
876 return [makeInt(64, false), makeInt(32, false), makeInt(16, false), makeInt(8, false), | 926 return [makeInt(64, false), makeInt(32, false), makeInt(16, false), makeInt(8, false), |
877 makeInt(64, true) , makeInt(32, true), makeInt(16, true), makeInt(8, true), | 927 makeInt(64, true) , makeInt(32, true), makeInt(16, true), makeInt(8, true), |
878 makeArray(), makeString(), makelambda(), makeCPointer()]; | 928 makeFloat(32), makeFloat(64), makeArray(), makeString(), makelambda(), makeCPointer()]; |
879 } | 929 } |
880 | 930 |
881 function addBuiltinModules(toplevel) | 931 function addBuiltinModules(toplevel) |
882 { | 932 { |
883 var os = new cObject('mod_obj_os'); | 933 var os = new cObject('mod_obj_os'); |