# HG changeset patch # User Michael Pavone # Date 1406079091 25200 # Node ID ddf38b66b2e2e5b1aca4ccd01f822686ca9791e6 # Parent bb1539decd625efac7d542f77f6868f2310dad46 Finish support for floating point numbers in C backend diff -r bb1539decd62 -r ddf38b66b2e2 cbackend.js --- a/cbackend.js Tue Jul 22 08:35:30 2014 -0700 +++ b/cbackend.js Tue Jul 22 18:31:31 2014 -0700 @@ -164,7 +164,13 @@ }; floatlit.prototype.toC = function() { - return 'make_float(' + this.val.toString() + ')'; + var floatType = this.bits == 32 ? 'float' : 'double'; + var str = floatType + '_' + (this.val < 0 ? 'neg_' + (0-this.val).toString() : this.val.toString()).replace('.', '_'); + if (!(str in declaredInts)) { + toplevelcode += 'obj_float' + this.bits + ' ' + str + ' = {{&obj_float' + this.bits + '_meta, NULL}, ' + this.val.toString() + '};\n'; + declaredInts[str] = true; + } + return '((object *)&' + str + ')'; } floatlit.prototype.toCLLExpr = function(vars) { return this.val.toString(); @@ -707,27 +713,40 @@ }); } +function addNumberOps(obj, typename) +{ + addBinaryOp(obj, '+', '+', typename); + addBinaryOp(obj, '-', '-', typename); + addBinaryOp(obj, '*', '*', typename); + addBinaryOp(obj, '/', '/', typename); + addCompOp(obj, '<', '<', typename); + addCompOp(obj, '>', '>', typename); + addCompOp(obj, '=', '==', typename); + addCompOp(obj, '!=', '!=', typename); + addCompOp(obj, '>=', '>=', typename); + addCompOp(obj, '<=', '<=', typename); + + obj.addMessage('jsonEncode', { + vars: {}, + lines: [ + 'return mcall(' + getMethodId('string') + ', 1, &self->header);' + ] + }); +} + function makeInt(bits, unsigned) { var typename = 'obj_' + (unsigned ? 'u' : '') + 'int' + bits; var intObj = new cObject(typename); intObj.addProperty('num', null, (unsigned ? 'u' : '') + 'int' + bits +'_t'); - addBinaryOp(intObj, '+', '+', typename); - addBinaryOp(intObj, '-', '-', typename); - addBinaryOp(intObj, '*', '*', typename); - addBinaryOp(intObj, '/', '/', typename); + addNumberOps(intObj, typename); addBinaryOp(intObj, '%', '%', typename); addBinaryOp(intObj, 'or', '|', typename); addBinaryOp(intObj, 'xor', '^', typename); addBinaryOp(intObj, 'and', '&', typename); addBinaryOp(intObj, 'lshift:by', '<<', typename); addBinaryOp(intObj, 'rshift:by', '>>', typename); - addCompOp(intObj, '<', '<', typename); - addCompOp(intObj, '>', '>', typename); - addCompOp(intObj, '=', '==', typename); - addCompOp(intObj, '!=', '!=', typename); - addCompOp(intObj, '>=', '>=', typename); - addCompOp(intObj, '<=', '<=', typename); + intObj.addInclude(''); //-9223372036854775808 //01234567890123456789 @@ -741,12 +760,6 @@ 'return &(str->header);' ] }); - intObj.addMessage('jsonEncode', { - vars: {}, - lines: [ - 'return mcall(' + getMethodId('string') + ', 1, &self->header);' - ] - }); //7FFFFFFFFFFFFFFF //01234567890123456789 intObj.addMessage('hex', { @@ -811,6 +824,43 @@ return intObj; } +function makeFloat(bits) +{ + var typename = 'obj_float' + bits; + var floatObj = new cObject(typename); + floatObj.addProperty('num', null, bits == 32 ? 'float' : 'double'); + addNumberOps(floatObj, typename); + + floatObj.addInclude(''); + floatObj.addMessage('string', { + vars: {str: 'string *'}, + lines: [ + 'str = (string *)make_object(&string_meta, NULL, 0);', + //probably overkill, but lets play it safe for now + 'str->data = GC_MALLOC(128);', + 'sprintf(str->data, "%f", self->num);', + 'str->len = str->bytes = strlen(str->data);', + 'return &(str->header);' + ] + }); + floatObj.addMessage('f' + bits, { + vars: {}, + lines: [ + 'return &(self->header);' + ] + }); + + floatObj.addMessage('f' + (bits == 32 ? 64 : 32), { + vars: {trans: 'obj_float' + (bits == 32 ? 64 : 32) + ' *'}, + lines: [ + 'trans = make_object(&obj_float' + (bits == 32 ? 64 : 32) + '_meta, NULL, 0);', + 'trans->num = self->num;', + 'return &(trans->header);' + ] + }); + return floatObj; +} + function makeCPointer() { var cptr = new cObject('cpointer'); @@ -875,7 +925,7 @@ { return [makeInt(64, false), makeInt(32, false), makeInt(16, false), makeInt(8, false), makeInt(64, true) , makeInt(32, true), makeInt(16, true), makeInt(8, true), - makeArray(), makeString(), makelambda(), makeCPointer()]; + makeFloat(32), makeFloat(64), makeArray(), makeString(), makelambda(), makeCPointer()]; } function addBuiltinModules(toplevel) diff -r bb1539decd62 -r ddf38b66b2e2 modules/json.tp --- a/modules/json.tp Tue Jul 22 08:35:30 2014 -0700 +++ b/modules/json.tp Tue Jul 22 18:31:31 2014 -0700 @@ -189,9 +189,9 @@ baz <- ["fizz" "buzz" "buzzzz"] qux <- ((dict hash) set: "fo" "shizzle") set: "my" "nizzle" arr <- #["pirate" "booty"] - numbers <- [1 2 3 42 (0-1337)] + numbers <- [1 2 3 42 (0-1337) 3.14159] booleans <- [ - true + true false ] } diff -r bb1539decd62 -r ddf38b66b2e2 parser.js --- a/parser.js Tue Jul 22 08:35:30 2014 -0700 +++ b/parser.js Tue Jul 22 18:31:31 2014 -0700 @@ -46,9 +46,10 @@ return val; }; -function floatlit(val) +function floatlit(val, bits) { this.val = val; + this.bits = bits; } floatlit.prototype.valueOf = function() { return '' + val; @@ -206,7 +207,7 @@ 'muldiv = left:primlitsym pieces:(hws ("*"/"/"/"%") ws primlitsym)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ 'primlitsym = hws val:(float / hex / binary / int / string / symbol / object / array / list / lambda / "(" ws expr:expr hws ")" { return expr; }) { return val; };' + 'symbol = chars:[a-zA-Z_!?@]+ trailing:(":"? [a-zA-Z_!?@0-9])* ! ":" { for (var i = 0; i < trailing.length; i++) { trailing[i] = trailing[i].join(""); } return new symbol(chars.join("") + trailing.join("")); };' + -'float = digits:[0-9]+ "." decimals:[0-9]+ { return new floatlit(parseFloat(digits.join("") + "." + decimals.join(""))); };' + +'float = digits:[0-9]+ "." decimals:[0-9]+ size:("f" ("32" / "64"))? { var bits = size ? parseInt(size[1], 10) : 64; return new floatlit(parseFloat(digits.join("") + "." + decimals.join("")), bits); };' + 'binary = "0b" digits:[01]+ { return new intlit(parseInt(digits.join(""), 2)); };' + 'hex = "0x" digits:[0-9a-fA-F]+ size:([iu] ("8" / "16" / "32" / "64"))? { var bits = size ? parseInt(size[1], 10) : 0; return new intlit(parseInt(digits.join(""), 16), bits, size[0] == "u"); };' + 'int = sign:"-"? digits:[0-9]+ size:([iu] ("8" / "16" / "32" / "64"))? { var bits = size ? parseInt(size[1], 10) : 0; return new intlit(parseInt(sign + digits.join(""), 10), bits, size[0] == "u"); };' +