From 3c2d6924310ec62f334694804c47c7af1921af69 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 27 Apr 2020 08:33:03 -0700 Subject: [PATCH] `$(a: float)` now works consistently in nim js, avoiding printing floats as ints (#14134) * fix https://github.com/timotheecour/Nim/issues/133; $(a: float) works in nim js like in other backends * fix tests * fix test for windows that prints 1.1e17 differently than other OS --- compiler/jsgen.nim | 13 ++++---- lib/system/jssys.nim | 15 +++++++++ tests/js/tbyvar.nim | 11 ++++--- tests/js/tdollar_float.nim | 62 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 tests/js/tdollar_float.nim diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 2461443cd9d57..0e9575e9cd3f7 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -530,11 +530,10 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) = gen(p, n[1], r) xLoc = r.rdLoc - template applyFormat(frmtA, frmtB: string) = - if i == 0: - r.res = frmtA % [xLoc, yLoc] - else: - r.res = frmtB % [xLoc, yLoc] + template applyFormat(frmt) = + r.res = frmt % [xLoc, yLoc] + template applyFormat(frmtA, frmtB) = + if i == 0: applyFormat(frmtA) else: applyFormat(frmtB) case op: of mAddI: applyFormat("addInt($1, $2)", "($1 + $2)") @@ -596,7 +595,9 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) = of mBoolToStr: applyFormat("nimBoolToStr($1)", "nimBoolToStr($1)") of mIntToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")") of mInt64ToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")") - of mFloatToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")") + of mFloatToStr: + useMagic(p, "nimFloatToString") + applyFormat "cstrToNimstr(nimFloatToString($1))" of mCStrToStr: applyFormat("cstrToNimstr($1)", "cstrToNimstr($1)") of mStrToStr, mUnown: applyFormat("$1", "$1") else: diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 2f3512cfc8d4b..ec55733e1e160 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -476,6 +476,21 @@ proc negInt(a: int): int {.compilerproc.} = proc negInt64(a: int64): int64 {.compilerproc.} = result = a*(-1) +proc nimFloatToString(a: float): cstring {.compilerproc.} = + ## ensures the result doesn't print like an integer, ie return 2.0, not 2 + asm """ + function nimOnlyDigitsOrMinus(n) { + return n.toString().match(/^-?\d+$/); + } + if (Number.isSafeInteger(`a`)) `result` = `a`+".0" + else { + `result` = `a`+"" + if(nimOnlyDigitsOrMinus(`result`)){ + `result` = `a`+".0" + } + } + """ + proc absInt(a: int): int {.compilerproc.} = result = if a < 0: a*(-1) else: a diff --git a/tests/js/tbyvar.nim b/tests/js/tbyvar.nim index 705d62574b74c..a4c60b0b3bf78 100644 --- a/tests/js/tbyvar.nim +++ b/tests/js/tbyvar.nim @@ -1,15 +1,16 @@ discard """ - output: '''foo 12 + output: ''' +foo 12 bar 12 2 foo 12 bar 12 2 12.5 -(nums: @[5, 5, 10, 5, 5, 5, 5, 5, 5, 5]) -(nums: @[5, 5, 50, 5, 5, 5, 5, 5, 5, 5]) -(nums: @[5, 5, 45, 5, 5, 5, 5, 5, 5, 5]) -(nums: @[5, 5, 9, 5, 5, 5, 5, 5, 5, 5]) +(nums: @[5.0, 5.0, 10.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]) +(nums: @[5.0, 5.0, 50.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]) +(nums: @[5.0, 5.0, 45.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]) +(nums: @[5.0, 5.0, 9.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]) asd ''' """ diff --git a/tests/js/tdollar_float.nim b/tests/js/tdollar_float.nim new file mode 100644 index 0000000000000..4fd8e3cbacd80 --- /dev/null +++ b/tests/js/tdollar_float.nim @@ -0,0 +1,62 @@ +#[ +merge into tests/system/tdollars.nim once https://github.com/nim-lang/Nim/pull/14122 +is merged +]# + +import unittest + +block: # https://github.com/timotheecour/Nim/issues/133 + # simple test + var a: float = 2 + check $a == "2.0" + + # systematic tests + template fun(a2: static float) = + const a: float = a2 # needed pending https://github.com/timotheecour/Nim/issues/132 + var b = a + check $b == $a + + fun 2 + fun 2.0 + fun 2.1 + fun 1_000 + fun 1_000.1 + fun 1_000_000_000.1 + fun 1_000_000_000_000.1 + + # negatives + fun -2.0 + fun -2.1 + + # 0 + fun 0 + fun -0 + fun 0.0 + + block: + var a = -0.0 + check $a in ["-0.0", "0.0"] + + # exponents + block: + var a = 5e20 + check $a in ["5e20", "500000000000000000000.0"] + + fun 3.4e1'f32 + fun 3.4e-1'f32 + fun -3.4e-1'f32 + fun 3.4e-1'f32 + fun 3e-1'f32 + + block: + var a = 3.4e38'f32 + check $a in ["3.4e+38", "3.4e+038"] + # on windows, printf (used in VM) prints as 3.4e+038 + # but js prints as 3.4e+38 + # on osx, both print as 3.4e+38 + # see https://github.com/timotheecour/Nim/issues/138 + + when false: # edge cases + fun -0.0 # see https://github.com/timotheecour/Nim/issues/136 + fun 5e20 + fun 3.4e38'f32