diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-01-21 16:28:03 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-01-21 16:28:03 +0100 |
commit | 1dac302975911752000e04fddb85b5302d7001b8 (patch) | |
tree | 9c67271c71b028811d178bca42cbd11771e7a3be | |
parent | b2854f21d6705f7957a21a0cc1a8688348a7fab8 (diff) | |
parent | c0d0e5efd935fbcce25de053f0b83bb2bb606faa (diff) | |
download | Nim-1dac302975911752000e04fddb85b5302d7001b8.tar.gz |
Merge pull request #3754 from yglukhov/js-unsigned
Unsigned arith corrected for JS
-rw-r--r-- | compiler/jsgen.nim | 142 | ||||
-rw-r--r-- | lib/system/jssys.nim | 36 | ||||
-rw-r--r-- | tests/misc/tunsignedinc.nim | 34 | ||||
-rw-r--r-- | tests/testament/categories.nim | 2 |
4 files changed, 67 insertions, 147 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 16a03a4ec..efd6e874b 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -291,21 +291,21 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64 ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64 - ["addU", "addU", "addU($1, $2)", "addU($1, $2)"], # addU - ["subU", "subU", "subU($1, $2)", "subU($1, $2)"], # subU - ["mulU", "mulU", "mulU($1, $2)", "mulU($1, $2)"], # mulU - ["divU", "divU", "divU($1, $2)", "divU($1, $2)"], # divU - ["modU", "modU", "modU($1, $2)", "modU($1, $2)"], # modU + ["", "", "", ""], # addU + ["", "", "", ""], # subU + ["", "", "", ""], # mulU + ["", "", "", ""], # divU + ["", "", "($1 % $2)", "($1 % $2)"], # modU ["", "", "($1 == $2)", "($1 == $2)"], # EqI ["", "", "($1 <= $2)", "($1 <= $2)"], # LeI ["", "", "($1 < $2)", "($1 < $2)"], # LtI ["", "", "($1 == $2)", "($1 == $2)"], # EqF64 ["", "", "($1 <= $2)", "($1 <= $2)"], # LeF64 ["", "", "($1 < $2)", "($1 < $2)"], # LtF64 - ["leU", "leU", "leU($1, $2)", "leU($1, $2)"], # leU - ["ltU", "ltU", "ltU($1, $2)", "ltU($1, $2)"], # ltU - ["leU64", "leU64", "leU64($1, $2)", "leU64($1, $2)"], # leU64 - ["ltU64", "ltU64", "ltU64($1, $2)", "ltU64($1, $2)"], # ltU64 + ["", "", "($1 <= $2)", "($1 <= $2)"], # leU + ["", "", "($1 < $2)", "($1 < $2)"], # ltU + ["", "", "($1 <= $2)", "($1 <= $2)"], # leU64 + ["", "", "($1 < $2)", "($1 < $2)"], # ltU64 ["", "", "($1 == $2)", "($1 == $2)"], # EqEnum ["", "", "($1 <= $2)", "($1 <= $2)"], # LeEnum ["", "", "($1 < $2)", "($1 < $2)"], # LtEnum @@ -354,90 +354,6 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"], ["", "", "$1", "$1"]] - luaOps: TMagicOps = [ - ["addInt", "", "addInt($1, $2)", "($1 + $2)"], # AddI - ["subInt", "", "subInt($1, $2)", "($1 - $2)"], # SubI - ["mulInt", "", "mulInt($1, $2)", "($1 * $2)"], # MulI - ["divInt", "", "divInt($1, $2)", "Math.floor($1 / $2)"], # DivI - ["modInt", "", "modInt($1, $2)", "Math.floor($1 % $2)"], # ModI - ["addInt", "", "addInt($1, $2)", "($1 + $2)"], # Succ - ["subInt", "", "subInt($1, $2)", "($1 - $2)"], # Pred - ["", "", "($1 + $2)", "($1 + $2)"], # AddF64 - ["", "", "($1 - $2)", "($1 - $2)"], # SubF64 - ["", "", "($1 * $2)", "($1 * $2)"], # MulF64 - ["", "", "($1 / $2)", "($1 / $2)"], # DivF64 - ["", "", "($1 >>> $2)", "($1 >>> $2)"], # ShrI - ["", "", "($1 << $2)", "($1 << $2)"], # ShlI - ["", "", "($1 & $2)", "($1 & $2)"], # BitandI - ["", "", "($1 | $2)", "($1 | $2)"], # BitorI - ["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI - ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinI - ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI - ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64 - ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64 - ["addU", "addU", "addU($1, $2)", "addU($1, $2)"], # addU - ["subU", "subU", "subU($1, $2)", "subU($1, $2)"], # subU - ["mulU", "mulU", "mulU($1, $2)", "mulU($1, $2)"], # mulU - ["divU", "divU", "divU($1, $2)", "divU($1, $2)"], # divU - ["modU", "modU", "modU($1, $2)", "modU($1, $2)"], # modU - ["", "", "($1 == $2)", "($1 == $2)"], # EqI - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeI - ["", "", "($1 < $2)", "($1 < $2)"], # LtI - ["", "", "($1 == $2)", "($1 == $2)"], # EqF64 - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeF64 - ["", "", "($1 < $2)", "($1 < $2)"], # LtF64 - ["leU", "leU", "leU($1, $2)", "leU($1, $2)"], # leU - ["ltU", "ltU", "ltU($1, $2)", "ltU($1, $2)"], # ltU - ["leU64", "leU64", "leU64($1, $2)", "leU64($1, $2)"], # leU64 - ["ltU64", "ltU64", "ltU64($1, $2)", "ltU64($1, $2)"], # ltU64 - ["", "", "($1 == $2)", "($1 == $2)"], # EqEnum - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeEnum - ["", "", "($1 < $2)", "($1 < $2)"], # LtEnum - ["", "", "($1 == $2)", "($1 == $2)"], # EqCh - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeCh - ["", "", "($1 < $2)", "($1 < $2)"], # LtCh - ["", "", "($1 == $2)", "($1 == $2)"], # EqB - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeB - ["", "", "($1 < $2)", "($1 < $2)"], # LtB - ["", "", "($1 == $2)", "($1 == $2)"], # EqRef - ["", "", "($1 == $2)", "($1 == $2)"], # EqUntracedRef - ["", "", "($1 <= $2)", "($1 <= $2)"], # LePtr - ["", "", "($1 < $2)", "($1 < $2)"], # LtPtr - ["", "", "($1 == $2)", "($1 == $2)"], # EqCString - ["", "", "($1 != $2)", "($1 != $2)"], # Xor - ["", "", "($1 == $2)", "($1 == $2)"], # EqProc - ["negInt", "", "negInt($1)", "-($1)"], # UnaryMinusI - ["negInt64", "", "negInt64($1)", "-($1)"], # UnaryMinusI64 - ["absInt", "", "absInt($1)", "Math.abs($1)"], # AbsI - ["", "", "not ($1)", "not ($1)"], # Not - ["", "", "+($1)", "+($1)"], # UnaryPlusI - ["", "", "~($1)", "~($1)"], # BitnotI - ["", "", "+($1)", "+($1)"], # UnaryPlusF64 - ["", "", "-($1)", "-($1)"], # UnaryMinusF64 - ["", "", "Math.abs($1)", "Math.abs($1)"], # AbsF64 - ["Ze8ToI", "Ze8ToI", "Ze8ToI($1)", "Ze8ToI($1)"], # mZe8ToI - ["Ze8ToI64", "Ze8ToI64", "Ze8ToI64($1)", "Ze8ToI64($1)"], # mZe8ToI64 - ["Ze16ToI", "Ze16ToI", "Ze16ToI($1)", "Ze16ToI($1)"], # mZe16ToI - ["Ze16ToI64", "Ze16ToI64", "Ze16ToI64($1)", "Ze16ToI64($1)"], # mZe16ToI64 - ["Ze32ToI64", "Ze32ToI64", "Ze32ToI64($1)", "Ze32ToI64($1)"], # mZe32ToI64 - ["ZeIToI64", "ZeIToI64", "ZeIToI64($1)", "ZeIToI64($1)"], # mZeIToI64 - ["toU8", "toU8", "toU8($1)", "toU8($1)"], # toU8 - ["toU16", "toU16", "toU16($1)", "toU16($1)"], # toU16 - ["toU32", "toU32", "toU32($1)", "toU32($1)"], # toU32 - ["", "", "$1", "$1"], # ToFloat - ["", "", "$1", "$1"], # ToBiggestFloat - ["", "", "Math.floor($1)", "Math.floor($1)"], # ToInt - ["", "", "Math.floor($1)", "Math.floor($1)"], # ToBiggestInt - ["nimCharToStr", "nimCharToStr", "nimCharToStr($1)", "nimCharToStr($1)"], - ["nimBoolToStr", "nimBoolToStr", "nimBoolToStr($1)", "nimBoolToStr($1)"], [ - "cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")", - "cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", "cstrToNimstr", - "cstrToNimstr(($1)+\"\")", - "cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", - "cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"], - ["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"], - ["", "", "$1", "$1"]] - proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = var x, y: TCompRes useMagic(p, magic) @@ -446,6 +362,20 @@ proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = r.res = frmt % [x.rdLoc, y.rdLoc] r.kind = resExpr +proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string, reassign: bool = false) = + var x, y: TCompRes + gen(p, n.sons[1], x) + gen(p, n.sons[2], y) + let trimmer = case n[1].typ.skipTypes(abstractRange).size + of 1: "& 0xff" + of 2: "& 0xffff" + of 4: ">>> 0" + else: "" + if reassign: + r.res = "$1 = (($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, rope trimmer] + else: + r.res = "(($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, rope trimmer] + proc ternaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = var x, y, z: TCompRes useMagic(p, magic) @@ -473,10 +403,16 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic, ops: TMagicOps) = else: gen(p, n.sons[1], r) r.res = ops[op][i + 2] % [r.rdLoc] - r.kind = resExpr proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) = - arithAux(p, n, r, op, jsOps | luaOps) + case op + of mAddU: binaryUintExpr(p, n, r, "+") + of mSubU: binaryUintExpr(p, n, r, "-") + of mMulU: binaryUintExpr(p, n, r, "*") + of mDivU: binaryUintExpr(p, n, r, "/") + else: + arithAux(p, n, r, op, jsOps) + r.kind = resExpr proc genLineDir(p: PProc, n: PNode) = let line = toLinenumber(n.info) @@ -1424,11 +1360,17 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = else: unaryExpr(p, n, r, "", "($1 != null ? ($1.length-1) : -1)") of mInc: - if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 += $2") - else: binaryExpr(p, n, r, "addInt", "$1 = addInt($1, $2)") + if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64: + binaryUintExpr(p, n, r, "+", true) + else: + if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 += $2") + else: binaryExpr(p, n, r, "addInt", "$1 = addInt($1, $2)") of ast.mDec: - if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2") - else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)") + if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64: + binaryUintExpr(p, n, r, "-", true) + else: + if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2") + else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)") of mSetLengthStr: binaryExpr(p, n, r, "", "$1.length = $2+1; $1[$1.length-1] = 0") of mSetLengthSeq: binaryExpr(p, n, r, "", "$1.length = $2") of mCard: unaryExpr(p, n, r, "SetCard", "SetCard($1)") @@ -1653,7 +1595,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) = case n.kind of nkSym: genSym(p, n, r) - of nkCharLit..nkInt64Lit: + of nkCharLit..nkUInt32Lit: if n.typ.kind == tyBool: r.res = if n.intVal == 0: rope"false" else: rope"true" else: diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 0bb0ffade..abee95f40 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -436,42 +436,6 @@ proc absInt(a: int): int {.compilerproc.} = proc absInt64(a: int64): int64 {.compilerproc.} = result = if a < 0: a*(-1) else: a -proc leU(a, b: int): bool {.compilerproc.} = - result = abs(a) <= abs(b) - -proc ltU(a, b: int): bool {.compilerproc.} = - result = abs(a) < abs(b) - -proc leU64(a, b: int64): bool {.compilerproc.} = - result = abs(a) <= abs(b) -proc ltU64(a, b: int64): bool {.compilerproc.} = - result = abs(a) < abs(b) - -proc addU(a, b: int): int {.compilerproc.} = - result = abs(a) + abs(b) -proc addU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) + abs(b) - -proc subU(a, b: int): int {.compilerproc.} = - result = abs(a) - abs(b) -proc subU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) - abs(b) - -proc mulU(a, b: int): int {.compilerproc.} = - result = abs(a) * abs(b) -proc mulU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) * abs(b) - -proc divU(a, b: int): int {.compilerproc.} = - result = abs(a) div abs(b) -proc divU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) div abs(b) - -proc modU(a, b: int): int {.compilerproc.} = - result = abs(a) mod abs(b) -proc modU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) mod abs(b) - proc ze*(a: int): int {.compilerproc.} = result = a diff --git a/tests/misc/tunsignedinc.nim b/tests/misc/tunsignedinc.nim index 95622156f..60c0559b0 100644 --- a/tests/misc/tunsignedinc.nim +++ b/tests/misc/tunsignedinc.nim @@ -1,14 +1,28 @@ -discard """ - output: '''253''' -""" -# bug #2427 +block: # bug #2427 + var x = 0'u8 + dec x # OverflowError + x -= 1 # OverflowError + x = x - 1 # No error -import unsigned + doAssert(x == 253'u8) -var x = 0'u8 -dec x # OverflowError -x -= 1 # OverflowError -x = x - 1 # No error +block: + var x = 130'u8 + x += 130'u8 + doAssert(x == 4'u8) -echo x +block: + var x = 40000'u16 + x = x + 40000'u16 + doAssert(x == 14464'u16) + +block: + var x = 4000000000'u32 + x = x + 4000000000'u32 + doAssert(x == 3705032704'u32) + +block: + var x = 123'u16 + x -= 125 + doAssert(x == 65534'u16) diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index 73d72289c..3200c7da9 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -220,7 +220,7 @@ proc jsTests(r: var TResults, cat: Category, options: string) = "actiontable/tactiontable", "method/tmultim1", "method/tmultim3", "method/tmultim4", "varres/tvarres0", "varres/tvarres3", "varres/tvarres4", - "varres/tvartup"]: + "varres/tvartup", "misc/tunsignedinc"]: test "tests/" & testfile & ".nim" for testfile in ["pure/strutils"]: |