improved unsigned support
This commit is contained in:
parent
1005961192
commit
b4084df434
9 changed files with 121 additions and 98 deletions
59
lib/core/unsigned.nim
Normal file
59
lib/core/unsigned.nim
Normal 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)``.
|
||||
|
|
@ -107,10 +107,10 @@ type
|
|||
PPixels = ptr TPixels
|
||||
|
||||
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 =
|
||||
colors.TColor(video[y * pitch.int + x])
|
||||
colors.TColor(video[y * pitch + x])
|
||||
|
||||
const
|
||||
ColSize = 4
|
||||
|
|
@ -118,7 +118,7 @@ const
|
|||
proc getPixel(sur: PSurface, x, y: Natural): colors.TColor {.inline.} =
|
||||
assert x <% sur.w
|
||||
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)
|
||||
|
||||
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
|
||||
var pixs = cast[PPixels](sur.s.pixels)
|
||||
#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 =
|
||||
## 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
|
||||
dx = dx * 2
|
||||
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)
|
||||
if dx > dy:
|
||||
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) =
|
||||
## draws a horizontal line from (x,y) to (x+w-1, y).
|
||||
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:
|
||||
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) =
|
||||
## draws a vertical line from (x,y) to (x, y+h-1).
|
||||
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:
|
||||
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) =
|
||||
## draws a rectangle.
|
||||
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):
|
||||
var minW = min(sur.s.w - r.x, r.width - 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) =
|
||||
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 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) =
|
||||
if (x > 0 and x < sur.s.w) and (y > 0 and
|
||||
y < sur.s.h):
|
||||
if (x > 0 and x < sur.s.w) and (y > 0 and y < sur.s.h):
|
||||
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)
|
||||
|
||||
setPix(video, pitch, x, y,
|
||||
setPix(video, pitch, x, y,
|
||||
pixColor.intensity(1.0 - c) + color.intensity(c))
|
||||
|
||||
|
||||
|
|
@ -561,7 +560,7 @@ when isMainModule:
|
|||
else:
|
||||
#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")
|
||||
SDL.Quit()
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ type
|
|||
TInteger* = TSignedInt|TUnsignedInt
|
||||
## 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
|
||||
## holes.
|
||||
|
||||
|
|
@ -533,85 +533,44 @@ proc abs*(x: int64): int64 {.magic: "AbsI64", noSideEffect.}
|
|||
## checking is turned on).
|
||||
|
||||
type
|
||||
UIntMax32 = distinct uint|uint8|uint16|uint32
|
||||
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: Int64): Int64 {.magic: "AddU64", noSideEffect.}
|
||||
## treats `x` and `y` as unsigned and adds them. The result is truncated to
|
||||
## fit into the result. This implements modulo arithmetic. No overflow
|
||||
## 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: Int64): Int64 {.magic: "SubU64", noSideEffect.}
|
||||
## treats `x` and `y` as unsigned and subtracts them. The result is
|
||||
## truncated to fit into the result. This implements modulo arithmetic.
|
||||
## 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: Int64): Int64 {.magic: "MulU64", noSideEffect.}
|
||||
## treats `x` and `y` as unsigned and multiplies them. The result is
|
||||
## truncated to fit into the result. This implements modulo arithmetic.
|
||||
## 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: Int64): Int64 {.magic: "DivU64", noSideEffect.}
|
||||
## treats `x` and `y` as unsigned and divides them. The result is
|
||||
## truncated to fit into the result. This implements modulo arithmetic.
|
||||
## 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: Int64): Int64 {.magic: "ModU64", noSideEffect.}
|
||||
## treats `x` and `y` as unsigned and compute the modulo of `x` and `y`.
|
||||
## The result is truncated to fit into the result.
|
||||
## This implements modulo arithmetic.
|
||||
## 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: Int64): bool {.magic: "LeU64", noSideEffect.}
|
||||
## treats `x` and `y` as unsigned and compares them.
|
||||
## 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: Int64): bool {.magic: "LtU64", noSideEffect.}
|
||||
## treats `x` and `y` as unsigned and compares them.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue