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');