Unsigned arith corrected for JS

This commit is contained in:
Yuriy Glukhov
2016-01-21 01:27:34 +02:00
parent 72b975d1ff
commit c0d0e5efd9
4 changed files with 67 additions and 147 deletions

View File

@@ -273,21 +273,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
@@ -336,90 +336,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)
@@ -428,6 +344,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)
@@ -455,10 +385,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)
@@ -1406,11 +1342,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)")
@@ -1635,7 +1577,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:

View File

@@ -417,42 +417,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

View File

@@ -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)

View File

@@ -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"]: