improved unsigned support

This commit is contained in:
Araq 2012-07-14 14:03:13 +02:00
commit b4084df434
9 changed files with 121 additions and 98 deletions

View file

@ -409,32 +409,32 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
"($1 - $2)", # SubF64 "($1 - $2)", # SubF64
"($1 * $2)", # MulF64 "($1 * $2)", # MulF64
"($1 / $2)", # DivF64 "($1 / $2)", # DivF64
"(NI$3)((NU$3)($1) >> (NU$3)($2))", # ShrI "($4)((NU$3)($1) >> (NU$3)($2))", # ShrI
"(NI$3)((NU$3)($1) << (NU$3)($2))", # ShlI "($4)((NU$3)($1) << (NU$3)($2))", # ShlI
"(NI$3)($1 & $2)", # BitandI "($4)($1 & $2)", # BitandI
"(NI$3)($1 | $2)", # BitorI "($4)($1 | $2)", # BitorI
"(NI$3)($1 ^ $2)", # BitxorI "($4)($1 ^ $2)", # BitxorI
"(($1 <= $2) ? $1 : $2)", # MinI "(($1 <= $2) ? $1 : $2)", # MinI
"(($1 >= $2) ? $1 : $2)", # MaxI "(($1 >= $2) ? $1 : $2)", # MaxI
"(NI64)((NU64)($1) >> (NU64)($2))", # ShrI64 "($4)((NU64)($1) >> (NU64)($2))", # ShrI64
"(NI64)((NU64)($1) << (NU64)($2))", # ShlI64 "($4)((NU64)($1) << (NU64)($2))", # ShlI64
"($1 & $2)", # BitandI64 "($4)($1 & $2)", # BitandI64
"($1 | $2)", # BitorI64 "($4)($1 | $2)", # BitorI64
"($1 ^ $2)", # BitxorI64 "($4)($1 ^ $2)", # BitxorI64
"(($1 <= $2) ? $1 : $2)", # MinI64 "(($1 <= $2) ? $1 : $2)", # MinI64
"(($1 >= $2) ? $1 : $2)", # MaxI64 "(($1 >= $2) ? $1 : $2)", # MaxI64
"(($1 <= $2) ? $1 : $2)", # MinF64 "(($1 <= $2) ? $1 : $2)", # MinF64
"(($1 >= $2) ? $1 : $2)", # MaxF64 "(($1 >= $2) ? $1 : $2)", # MaxF64
"(NI$3)((NU$3)($1) + (NU$3)($2))", # AddU "($4)((NU$3)($1) + (NU$3)($2))", # AddU
"(NI$3)((NU$3)($1) - (NU$3)($2))", # SubU "($4)((NU$3)($1) - (NU$3)($2))", # SubU
"(NI$3)((NU$3)($1) * (NU$3)($2))", # MulU "($4)((NU$3)($1) * (NU$3)($2))", # MulU
"(NI$3)((NU$3)($1) / (NU$3)($2))", # DivU "($4)((NU$3)($1) / (NU$3)($2))", # DivU
"(NI$3)((NU$3)($1) % (NU$3)($2))", # ModU "($4)((NU$3)($1) % (NU$3)($2))", # ModU
"(NI64)((NU64)($1) + (NU64)($2))", # AddU64 "($4)((NU64)($1) + (NU64)($2))", # AddU64
"(NI64)((NU64)($1) - (NU64)($2))", # SubU64 "($4)((NU64)($1) - (NU64)($2))", # SubU64
"(NI64)((NU64)($1) * (NU64)($2))", # MulU64 "($4)((NU64)($1) * (NU64)($2))", # MulU64
"(NI64)((NU64)($1) / (NU64)($2))", # DivU64 "($4)((NU64)($1) / (NU64)($2))", # DivU64
"(NI64)((NU64)($1) % (NU64)($2))", # ModU64 "($4)((NU64)($1) % (NU64)($2))", # ModU64
"($1 == $2)", # EqI "($1 == $2)", # EqI
"($1 <= $2)", # LeI "($1 <= $2)", # LeI
"($1 < $2)", # LtI "($1 < $2)", # LtI
@ -474,28 +474,29 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
# BUGFIX: cannot use result-type here, as it may be a boolean # BUGFIX: cannot use result-type here, as it may be a boolean
s = max(getSize(a.t), getSize(b.t)) * 8 s = max(getSize(a.t), getSize(b.t)) * 8
putIntoDest(p, d, e.typ, putIntoDest(p, d, e.typ,
ropef(binArithTab[op], [rdLoc(a), rdLoc(b), toRope(s)])) ropef(binArithTab[op], [rdLoc(a), rdLoc(b), toRope(s),
getSimpleTypeDesc(p.module, e.typ)]))
proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
const const
unArithTab: array[mNot..mToBiggestInt, string] = ["!($1)", # Not unArithTab: array[mNot..mToBiggestInt, string] = ["!($1)", # Not
"$1", # UnaryPlusI "$1", # UnaryPlusI
"(NI$2)((NU$2) ~($1))", # BitnotI "($3)((NU$2) ~($1))", # BitnotI
"$1", # UnaryPlusI64 "$1", # UnaryPlusI64
"~($1)", # BitnotI64 "($3)((NU$2) ~($1))", # BitnotI64
"$1", # UnaryPlusF64 "$1", # UnaryPlusF64
"-($1)", # UnaryMinusF64 "-($1)", # UnaryMinusF64
"($1 > 0? ($1) : -($1))", # AbsF64; BUGFIX: fabs() makes problems "($1 > 0? ($1) : -($1))", # AbsF64; BUGFIX: fabs() makes problems
# for Tiny C, so we don't use it # for Tiny C, so we don't use it
"((NI)(NU)(NU8)($1))", # mZe8ToI "(($3)(NU)(NU8)($1))", # mZe8ToI
"((NI64)(NU64)(NU8)($1))", # mZe8ToI64 "(($3)(NU64)(NU8)($1))", # mZe8ToI64
"((NI)(NU)(NU16)($1))", # mZe16ToI "(($3)(NU)(NU16)($1))", # mZe16ToI
"((NI64)(NU64)(NU16)($1))", # mZe16ToI64 "(($3)(NU64)(NU16)($1))", # mZe16ToI64
"((NI64)(NU64)(NU32)($1))", # mZe32ToI64 "(($3)(NU64)(NU32)($1))", # mZe32ToI64
"((NI64)(NU64)(NU)($1))", # mZeIToI64 "(($3)(NU64)(NU)($1))", # mZeIToI64
"((NI8)(NU8)(NU)($1))", # ToU8 "(($3)(NU8)(NU)($1))", # ToU8
"((NI16)(NU16)(NU)($1))", # ToU16 "(($3)(NU16)(NU)($1))", # ToU16
"((NI32)(NU32)(NU64)($1))", # ToU32 "(($3)(NU32)(NU64)($1))", # ToU32
"((double) ($1))", # ToFloat "((double) ($1))", # ToFloat
"((double) ($1))", # ToBiggestFloat "((double) ($1))", # ToBiggestFloat
"float64ToInt32($1)", # ToInt XXX: this is not correct! "float64ToInt32($1)", # ToInt XXX: this is not correct!
@ -507,7 +508,8 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
InitLocExpr(p, e.sons[1], a) InitLocExpr(p, e.sons[1], a)
t = skipTypes(e.typ, abstractRange) t = skipTypes(e.typ, abstractRange)
putIntoDest(p, d, e.typ, putIntoDest(p, d, e.typ,
ropef(unArithTab[op], [rdLoc(a), toRope(getSize(t) * 8)])) ropef(unArithTab[op], [rdLoc(a), toRope(getSize(t) * 8),
getSimpleTypeDesc(p.module, e.typ)]))
proc genDeref(p: BProc, e: PNode, d: var TLoc) = proc genDeref(p: BProc, e: PNode, d: var TLoc) =
var a: TLoc var a: TLoc

View file

@ -263,15 +263,17 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
of tyInt8: result = newIntNodeT(int8(getInt(a)) shl int8(getInt(b)), n) of tyInt8: result = newIntNodeT(int8(getInt(a)) shl int8(getInt(b)), n)
of tyInt16: result = newIntNodeT(int16(getInt(a)) shl int16(getInt(b)), n) of tyInt16: result = newIntNodeT(int16(getInt(a)) shl int16(getInt(b)), n)
of tyInt32: result = newIntNodeT(int32(getInt(a)) shl int32(getInt(b)), n) of tyInt32: result = newIntNodeT(int32(getInt(a)) shl int32(getInt(b)), n)
of tyInt64, tyInt: result = newIntNodeT(`shl`(getInt(a), getInt(b)), n) of tyInt64, tyInt, tyUInt..tyUInt64:
result = newIntNodeT(`shl`(getInt(a), getInt(b)), n)
else: InternalError(n.info, "constant folding for shl") else: InternalError(n.info, "constant folding for shl")
of mShrI, mShrI64: of mShrI, mShrI64:
case skipTypes(n.typ, abstractRange).kind case skipTypes(n.typ, abstractRange).kind
of tyInt8: result = newIntNodeT(int8(getInt(a)) shr int8(getInt(b)), n) of tyInt8: result = newIntNodeT(int8(getInt(a)) shr int8(getInt(b)), n)
of tyInt16: result = newIntNodeT(int16(getInt(a)) shr int16(getInt(b)), n) of tyInt16: result = newIntNodeT(int16(getInt(a)) shr int16(getInt(b)), n)
of tyInt32: result = newIntNodeT(int32(getInt(a)) shr int32(getInt(b)), n) of tyInt32: result = newIntNodeT(int32(getInt(a)) shr int32(getInt(b)), n)
of tyInt64, tyInt: result = newIntNodeT(`shr`(getInt(a), getInt(b)), n) of tyInt64, tyInt, tyUInt..tyUInt64:
else: InternalError(n.info, "constant folding for shl") result = newIntNodeT(`shr`(getInt(a), getInt(b)), n)
else: InternalError(n.info, "constant folding for shr")
of mDivI, mDivI64: result = newIntNodeT(getInt(a) div getInt(b), n) of mDivI, mDivI64: result = newIntNodeT(getInt(a) div getInt(b), n)
of mModI, mModI64: result = newIntNodeT(getInt(a) mod getInt(b), n) of mModI, mModI64: result = newIntNodeT(getInt(a) mod getInt(b), n)
of mAddF64: result = newFloatNodeT(getFloat(a) + getFloat(b), n) of mAddF64: result = newFloatNodeT(getFloat(a) + getFloat(b), n)

View file

@ -64,7 +64,8 @@ proc initCandidate*(c: var TCandidate, callee: PType) =
proc put(t: var TIdTable, key, val: PType) {.inline.} = proc put(t: var TIdTable, key, val: PType) {.inline.} =
IdTablePut(t, key, val) IdTablePut(t, key, val)
proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode, calleeScope = -1) = proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode,
calleeScope = -1) =
initCandidateAux(c, callee.typ) initCandidateAux(c, callee.typ)
c.calleeSym = callee c.calleeSym = callee
c.calleeScope = calleeScope c.calleeScope = calleeScope

View file

@ -31,6 +31,11 @@ Core
implicitly by the compiler. Do not import it directly. It relies on compiler implicitly by the compiler. Do not import it directly. It relies on compiler
magic to work. magic to work.
* `unsigned <unsigned.html>`_
This module implements basic arithmetic operators for unsigned integers.
To discourage users from using unsigned integers, it's not part
of ``system``, but an extra import.
* `threads <threads.html>`_ * `threads <threads.html>`_
Nimrod thread support. **Note**: This is part of the system module. Do not Nimrod thread support. **Note**: This is part of the system module. Do not
import it explicitely. import it explicitely.

59
lib/core/unsigned.nim Normal file
View file

@ -0,0 +1,59 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2012 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## This module implements basic arithmetic operators for unsigned integers.
## To discourage users from using ``unsigned``, it's not part of ``system``,
## but an extra import.
type
SomeUInt = uint|uint8|uint16|uint32|uint64
proc `not`*[T: SomeUInt](x: T): T {.magic: "BitnotI", noSideEffect.}
## computes the `bitwise complement` of the integer `x`.
proc `shr`*[T: SomeUInt](x, y: T): T {.magic: "ShrI", noSideEffect.}
## computes the `shift right` operation of `x` and `y`.
proc `shl`*[T: SomeUInt](x, y: T): T {.magic: "ShlI", noSideEffect.}
## computes the `shift left` operation of `x` and `y`.
proc `and`*[T: SomeUInt](x, y: T): T {.magic: "BitandI", noSideEffect.}
## computes the `bitwise and` of numbers `x` and `y`.
proc `or`*[T: SomeUInt](x, y: T): T {.magic: "BitorI", noSideEffect.}
## computes the `bitwise or` of numbers `x` and `y`.
proc `xor`*[T: SomeUInt](x, y: T): T {.magic: "BitxorI", noSideEffect.}
## computes the `bitwise xor` of numbers `x` and `y`.
proc `==`*[T: SomeUInt](x, y: T): bool {.magic: "EqI", noSideEffect.}
## Compares two unsigned integers for equality.
proc `+`*[T: SomeUInt](x, y: T): T {.magic: "AddU", noSideEffect.}
## Binary `+` operator for unsigned integers.
proc `-`*[T: SomeUInt](x, y: T): T {.magic: "SubU", noSideEffect.}
## Binary `-` operator for unsigned integers.
proc `*`*[T: SomeUInt](x, y: T): T {.magic: "MulU", noSideEffect.}
## Binary `*` operator for unsigned integers.
proc `div`*[T: SomeUInt](x, y: T): T {.magic: "DivU", noSideEffect.}
## computes the integer division. This is roughly the same as
## ``floor(x/y)``.
proc `mod`*[T: SomeUInt](x, y: T): T {.magic: "ModU", noSideEffect.}
## computes the integer modulo operation. This is the same as
## ``x - (x div y) * y``.
proc `<=`*[T: SomeUInt](x, y: SomeUInt): bool {.magic: "LeU", noSideEffect.}
## Returns true iff ``x <= y``.
proc `<`*[T: SomeUInt](x, y: T): bool {.magic: "LtU", noSideEffect.}
## Returns true iff ``unsigned(x) < unsigned(y)``.

View file

@ -107,10 +107,10 @@ type
PPixels = ptr TPixels PPixels = ptr TPixels
template setPix(video, pitch, x, y, col: expr): stmt = template setPix(video, pitch, x, y, col: expr): stmt =
video[y * pitch.int + x] = int32(col) video[y * pitch + x] = int32(col)
template getPix(video, pitch, x, y: expr): expr = template getPix(video, pitch, x, y: expr): expr =
colors.TColor(video[y * pitch.int + x]) colors.TColor(video[y * pitch + x])
const const
ColSize = 4 ColSize = 4
@ -118,7 +118,7 @@ const
proc getPixel(sur: PSurface, x, y: Natural): colors.TColor {.inline.} = proc getPixel(sur: PSurface, x, y: Natural): colors.TColor {.inline.} =
assert x <% sur.w assert x <% sur.w
assert y <% sur.h assert y <% sur.h
result = getPix(cast[PPixels](sur.s.pixels), sur.s.pitch div ColSize.uint16, result = getPix(cast[PPixels](sur.s.pixels), sur.s.pitch.int div ColSize,
x, y) x, y)
proc setPixel(sur: PSurface, x, y: Natural, col: colors.TColor) {.inline.} = proc setPixel(sur: PSurface, x, y: Natural, col: colors.TColor) {.inline.} =
@ -126,7 +126,7 @@ proc setPixel(sur: PSurface, x, y: Natural, col: colors.TColor) {.inline.} =
assert y <% sur.h assert y <% sur.h
var pixs = cast[PPixels](sur.s.pixels) var pixs = cast[PPixels](sur.s.pixels)
#pixs[y * (sur.s.pitch div colSize) + x] = int(col) #pixs[y * (sur.s.pitch div colSize) + x] = int(col)
setPix(pixs, sur.s.pitch div ColSize.uint16, x, y, col) setPix(pixs, sur.s.pitch.int div ColSize, x, y, col)
proc `[]`*(sur: PSurface, p: TPoint): TColor = proc `[]`*(sur: PSurface, p: TPoint): TColor =
## get pixel at position `p`. No range checking is done! ## get pixel at position `p`. No range checking is done!
@ -252,7 +252,7 @@ proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
dy = dy * 2 dy = dy * 2
dx = dx * 2 dx = dx * 2
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch div ColSize var pitch = sur.s.pitch.int div ColSize
setPix(video, pitch, x0, y0, color) setPix(video, pitch, x0, y0, color)
if dx > dy: if dx > dy:
var fraction = dy - (dx div 2) var fraction = dy - (dx div 2)
@ -276,7 +276,7 @@ proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) = proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) =
## draws a horizontal line from (x,y) to (x+w-1, y). ## draws a horizontal line from (x,y) to (x+w-1, y).
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch div ColSize var pitch = sur.s.pitch.int div ColSize
if y >= 0 and y <= sur.s.h: if y >= 0 and y <= sur.s.h:
for i in 0 .. min(sur.s.w-x, w)-1: for i in 0 .. min(sur.s.w-x, w)-1:
@ -285,7 +285,7 @@ proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) =
proc drawVerLine*(sur: PSurface, x, y, h: Natural, Color: TColor) = proc drawVerLine*(sur: PSurface, x, y, h: Natural, Color: TColor) =
## draws a vertical line from (x,y) to (x, y+h-1). ## draws a vertical line from (x,y) to (x, y+h-1).
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch div ColSize var pitch = sur.s.pitch.int div ColSize
if x >= 0 and x <= sur.s.w: if x >= 0 and x <= sur.s.w:
for i in 0 .. min(sur.s.h-y, h)-1: for i in 0 .. min(sur.s.h-y, h)-1:
@ -322,7 +322,7 @@ proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) =
proc drawRect*(sur: PSurface, r: TRect, color: TColor) = proc drawRect*(sur: PSurface, r: TRect, color: TColor) =
## draws a rectangle. ## draws a rectangle.
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch div ColSize var pitch = sur.s.pitch.int div ColSize
if (r.x >= 0 and r.x <= sur.s.w) and (r.y >= 0 and r.y <= sur.s.h): if (r.x >= 0 and r.x <= sur.s.w) and (r.y >= 0 and r.y <= sur.s.h):
var minW = min(sur.s.w - r.x, r.width - 1) var minW = min(sur.s.w - r.x, r.width - 1)
var minH = min(sur.s.h - r.y, r.height - 1) var minH = min(sur.s.h - r.y, r.height - 1)
@ -345,7 +345,7 @@ proc fillRect*(sur: PSurface, r: TRect, col: TColor) =
proc Plot4EllipsePoints(sur: PSurface, CX, CY, X, Y: Natural, col: TColor) = proc Plot4EllipsePoints(sur: PSurface, CX, CY, X, Y: Natural, col: TColor) =
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch div ColSize var pitch = sur.s.pitch.int div ColSize
if CX+X <= sur.s.w-1: if CX+X <= sur.s.w-1:
if CY+Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY+Y, col) if CY+Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY+Y, col)
if CY-Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY-Y, col) if CY-Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY-Y, col)
@ -409,14 +409,13 @@ proc drawEllipse*(sur: PSurface, CX, CY, XRadius, YRadius: Natural,
proc plotAA(sur: PSurface, x, y: int, c: float, color: TColor) = proc plotAA(sur: PSurface, x, y: int, c: float, color: TColor) =
if (x > 0 and x < sur.s.w) and (y > 0 and if (x > 0 and x < sur.s.w) and (y > 0 and y < sur.s.h):
y < sur.s.h):
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch div ColSize var pitch = sur.s.pitch.int div ColSize
var pixColor = getPix(video, pitch, x, y) var pixColor = getPix(video, pitch, x, y)
setPix(video, pitch, x, y, setPix(video, pitch, x, y,
pixColor.intensity(1.0 - c) + color.intensity(c)) pixColor.intensity(1.0 - c) + color.intensity(c))
@ -561,7 +560,7 @@ when isMainModule:
else: else:
#echo(event.kind) #echo(event.kind)
SDL.UpdateRect(surf.s, int32(0), int32(0), int32(800), int32(600)) SDL.UpdateRect(surf.s, 0, 0, 800, 600)
surf.writeToBMP("test.bmp") surf.writeToBMP("test.bmp")
SDL.Quit() SDL.Quit()

View file

@ -64,7 +64,7 @@ type
TInteger* = TSignedInt|TUnsignedInt TInteger* = TSignedInt|TUnsignedInt
## type class matching all integer types ## type class matching all integer types
TOrdinal* = TInteger|bool|enum TOrdinal* = int|int8|int16|int32|int64|bool|enum|uint8|uint16|uint32
## type class matching all ordinal types; however this includes enums with ## type class matching all ordinal types; however this includes enums with
## holes. ## holes.
@ -533,85 +533,44 @@ proc abs*(x: int64): int64 {.magic: "AbsI64", noSideEffect.}
## checking is turned on). ## checking is turned on).
type type
UIntMax32 = distinct uint|uint8|uint16|uint32
IntMax32 = distinct int|int8|int16|int32 IntMax32 = distinct int|int8|int16|int32
proc `+` *(x, y: UIntMax32): UIntMax32 {.magic: "AddU", noSideEffect.}
proc `+` *(x, y: UInt64): uint64 {.magic: "AddU64", noSideEffect.}
## Binary `+` operator for unsigned integers.
proc `+%` *(x, y: IntMax32): IntMax32 {.magic: "AddU", noSideEffect.} proc `+%` *(x, y: IntMax32): IntMax32 {.magic: "AddU", noSideEffect.}
proc `+%` *(x, y: Int64): Int64 {.magic: "AddU64", noSideEffect.} proc `+%` *(x, y: Int64): Int64 {.magic: "AddU64", noSideEffect.}
## treats `x` and `y` as unsigned and adds them. The result is truncated to ## treats `x` and `y` as unsigned and adds them. The result is truncated to
## fit into the result. This implements modulo arithmetic. No overflow ## fit into the result. This implements modulo arithmetic. No overflow
## errors are possible. ## errors are possible.
proc `-` *(x, y: UIntMax32): UIntMax32 {.magic: "SubU", noSideEffect.}
proc `-` *(x, y: UInt64): UInt64 {.magic: "SubU64", noSideEffect.}
## Binary `-` operator for unsigned integers.
proc `-%` *(x, y: IntMax32): IntMax32 {.magic: "SubU", noSideEffect.} proc `-%` *(x, y: IntMax32): IntMax32 {.magic: "SubU", noSideEffect.}
proc `-%` *(x, y: Int64): Int64 {.magic: "SubU64", noSideEffect.} proc `-%` *(x, y: Int64): Int64 {.magic: "SubU64", noSideEffect.}
## treats `x` and `y` as unsigned and subtracts them. The result is ## treats `x` and `y` as unsigned and subtracts them. The result is
## truncated to fit into the result. This implements modulo arithmetic. ## truncated to fit into the result. This implements modulo arithmetic.
## No overflow errors are possible. ## No overflow errors are possible.
proc `*` *(x, y: UIntMax32): UIntMax32 {.magic: "MulU", noSideEffect.}
proc `*` *(x, y: UInt64): UInt64 {.magic: "MulU64", noSideEffect.}
## Binary `*` operator for unsigned integers.
proc `*%` *(x, y: IntMax32): IntMax32 {.magic: "MulU", noSideEffect.} proc `*%` *(x, y: IntMax32): IntMax32 {.magic: "MulU", noSideEffect.}
proc `*%` *(x, y: Int64): Int64 {.magic: "MulU64", noSideEffect.} proc `*%` *(x, y: Int64): Int64 {.magic: "MulU64", noSideEffect.}
## treats `x` and `y` as unsigned and multiplies them. The result is ## treats `x` and `y` as unsigned and multiplies them. The result is
## truncated to fit into the result. This implements modulo arithmetic. ## truncated to fit into the result. This implements modulo arithmetic.
## No overflow errors are possible. ## No overflow errors are possible.
proc `div` *(x, y: UIntMax32): UIntMax32 {.magic: "DivU", noSideEffect.}
proc `div` *(x, y: UInt64): UInt64 {.magic: "DivU64", noSideEffect.}
## computes the integer division. This is roughly the same as
## ``floor(x/y)``.
proc `/` *(x, y: UIntMax32): UIntMax32 {.magic: "DivU", noSideEffect.}
proc `/` *(x, y: UInt64): UInt64 {.magic: "DivU64", noSideEffect.}
## computes the integer division. This is roughly the same as
## ``floor(x/y)``.
proc `/%` *(x, y: IntMax32): IntMax32 {.magic: "DivU", noSideEffect.} proc `/%` *(x, y: IntMax32): IntMax32 {.magic: "DivU", noSideEffect.}
proc `/%` *(x, y: Int64): Int64 {.magic: "DivU64", noSideEffect.} proc `/%` *(x, y: Int64): Int64 {.magic: "DivU64", noSideEffect.}
## treats `x` and `y` as unsigned and divides them. The result is ## treats `x` and `y` as unsigned and divides them. The result is
## truncated to fit into the result. This implements modulo arithmetic. ## truncated to fit into the result. This implements modulo arithmetic.
## No overflow errors are possible. ## No overflow errors are possible.
proc `%` *(x, y: UIntMax32): UIntMax32 {.magic: "DivU", noSideEffect.}
proc `%` *(x, y: UInt64): UInt64 {.magic: "DivU64", noSideEffect.}
## computes the integer modulo operation. This is the same as
## ``x - (x div y) * y``.
proc `mod` *(x, y: UIntMax32): UIntMax32 {.magic: "DivU", noSideEffect.}
proc `mod` *(x, y: UInt64): UInt64 {.magic: "DivU64", noSideEffect.}
## computes the integer modulo operation. This is the same as
## ``x - (x div y) * y``.
proc `%%` *(x, y: IntMax32): IntMax32 {.magic: "ModU", noSideEffect.} proc `%%` *(x, y: IntMax32): IntMax32 {.magic: "ModU", noSideEffect.}
proc `%%` *(x, y: Int64): Int64 {.magic: "ModU64", noSideEffect.} proc `%%` *(x, y: Int64): Int64 {.magic: "ModU64", noSideEffect.}
## treats `x` and `y` as unsigned and compute the modulo of `x` and `y`. ## treats `x` and `y` as unsigned and compute the modulo of `x` and `y`.
## The result is truncated to fit into the result. ## The result is truncated to fit into the result.
## This implements modulo arithmetic. ## This implements modulo arithmetic.
## No overflow errors are possible. ## No overflow errors are possible.
proc `<=` *(x, y: UIntMax32): bool {.magic: "LeU", noSideEffect.}
proc `<=` *(x, y: UInt64): bool {.magic: "LeU64", noSideEffect.}
## Returns true iff ``x <= y``.
proc `<=%` *(x, y: IntMax32): bool {.magic: "LeU", noSideEffect.} proc `<=%` *(x, y: IntMax32): bool {.magic: "LeU", noSideEffect.}
proc `<=%` *(x, y: Int64): bool {.magic: "LeU64", noSideEffect.} proc `<=%` *(x, y: Int64): bool {.magic: "LeU64", noSideEffect.}
## treats `x` and `y` as unsigned and compares them. ## treats `x` and `y` as unsigned and compares them.
## Returns true iff ``unsigned(x) <= unsigned(y)``. ## Returns true iff ``unsigned(x) <= unsigned(y)``.
proc `<` *(x, y: UIntMax32): bool {.magic: "LtU", noSideEffect.}
proc `<` *(x, y: UInt64): bool {.magic: "LtU64", noSideEffect.}
## Returns true iff ``unsigned(x) < unsigned(y)``.
proc `<%` *(x, y: IntMax32): bool {.magic: "LtU", noSideEffect.} proc `<%` *(x, y: IntMax32): bool {.magic: "LtU", noSideEffect.}
proc `<%` *(x, y: Int64): bool {.magic: "LtU64", noSideEffect.} proc `<%` *(x, y: Int64): bool {.magic: "LtU64", noSideEffect.}
## treats `x` and `y` as unsigned and compares them. ## treats `x` and `y` as unsigned and compares them.

View file

@ -3,10 +3,6 @@ version 0.9.0
- implicit deref for parameter matching - implicit deref for parameter matching
- deprecate ``var x, y = 0`` as it's confusing for tuple consistency - deprecate ``var x, y = 0`` as it's confusing for tuple consistency
- finish support for unsigned ints:
- support more unsigned operations
- test codegen
- test sequence of closures; especially that the GC does not leak for those! - test sequence of closures; especially that the GC does not leak for those!
New pragmas: New pragmas:

View file

@ -24,7 +24,7 @@ file: ticker
doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview;filters" doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview;filters"
doc: "tools;c2nim;niminst;nimgrep" doc: "tools;c2nim;niminst;nimgrep"
pdf: "manual;lib;tut1;tut2;nimrodc;c2nim;niminst;gc" pdf: "manual;lib;tut1;tut2;nimrodc;c2nim;niminst;gc"
srcdoc: "core/macros;pure/marshal;core/typeinfo" srcdoc: "core/macros;pure/marshal;core/typeinfo;core/unsigned"
srcdoc: "impure/graphics;impure/re;pure/sockets" srcdoc: "impure/graphics;impure/re;pure/sockets"
srcdoc: "system.nim;system/threads.nim;system/channels.nim" srcdoc: "system.nim;system/threads.nim;system/channels.nim"
srcdoc: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm" srcdoc: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm"