summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2012-06-10 23:33:05 +0300
committerZahary Karadjov <zahary@gmail.com>2012-06-11 21:38:01 +0300
commite2d38a57ecdc3aa7b5cd81a9f2f588eb0dc5586f (patch)
tree396ef1c332c4ec460cd91ec0358a9ec02f76052c /lib
parentce933c90a48ddf0331016edbc684ba6937412e22 (diff)
downloadNim-e2d38a57ecdc3aa7b5cd81a9f2f588eb0dc5586f.tar.gz
better support for unsigned integers.
Diffstat (limited to 'lib')
-rwxr-xr-xlib/core/macros.nim5
-rwxr-xr-xlib/system.nim114
2 files changed, 79 insertions, 40 deletions
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index b0f237924..9d0994c2f 100755
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -17,8 +17,9 @@ type
   TNimrodNodeKind* = enum

     nnkNone, nnkEmpty, nnkIdent, nnkSym, 

     nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit, 

-    nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkFloatLit, 

-    nnkFloat32Lit, nnkFloat64Lit, nnkStrLit, nnkRStrLit, 

+    nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkUIntLit, nnkUInt8Lit, 

+    nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit, 

+    nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit, 

     nnkTripleStrLit, nnkNilLit, nnkMetaNode, nnkDotCall, 

     nnkCommand, nnkCall, nnkCallStrLit, nnkExprEqExpr, 

     nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkInfix, 

diff --git a/lib/system.nim b/lib/system.nim
index 5d01c5a44..fe8f7a517 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -21,9 +21,15 @@ type
   int16* {.magic: Int16.} ## signed 16 bit integer type
   int32* {.magic: Int32.} ## signed 32 bit integer type
   int64* {.magic: Int64.} ## signed 64 bit integer type
+  uint* {.magic: UInt.} ## unsigned default integer type
+  uint8* {.magic: UInt8.} ## unsigned 8 bit integer type
+  uint16* {.magic: UInt16.} ## unsigned 16 bit integer type
+  uint32* {.magic: UInt32.} ## unsigned 32 bit integer type
+  uint64* {.magic: UInt64.} ## unsigned 64 bit integer type
   float* {.magic: Float.} ## default floating point type
   float32* {.magic: Float32.} ## 32 bit floating point type
   float64* {.magic: Float64.} ## 64 bit floating point type
+
 type # we need to start a new type section here, so that ``0`` can have a type
   bool* {.magic: Bool.} = enum ## built-in boolean type
     false = 0, true = 1
@@ -49,14 +55,23 @@ type
                                 ## a type description (for templates)
   void* {.magic: "VoidType".}  ## meta type to denote the absense of any type
   
-  TInteger* = int|int8|int16|int32|int64
+  TSignedInt* = distinct int|int8|int16|int32|int64
+    ## type class matching all signed integer types
+
+  TUnsignedInt* = distinct uint|uint8|uint16|uint32|uint64
+    ## type class matching all unsigned integer types
+
+  TInteger* = distinct TSignedInt|TUnsignedInt
     ## type class matching all integer types
 
-  TOrdinal* = TInteger|bool|enum
+  TOrdinal* = distinct TInteger|bool|enum
     ## type class matching all ordinal types; however this includes enums with
     ## holes.
+  
+  TReal* = distinct float|float32|float64
+    ## type class matching all floating point number types
 
-  TNumber* = TInteger|float|float32|float64
+  TNumber* = distinct TInteger|TReal
     ## type class matching all number types
 
 proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.}
@@ -517,65 +532,88 @@ proc abs*(x: int64): int64 {.magic: "AbsI64", noSideEffect.}
   ## is -MININT for its type), an overflow exception is thrown (if overflow
   ## checking is turned on).
 
-proc `+%` *(x, y: int): int {.magic: "AddU", noSideEffect.}
-proc `+%` *(x, y: int8): int8 {.magic: "AddU", noSideEffect.}
-proc `+%` *(x, y: int16): int16 {.magic: "AddU", noSideEffect.}
-proc `+%` *(x, y: int32): int32 {.magic: "AddU", noSideEffect.}
-proc `+%` *(x, y: int64): int64 {.magic: "AddU64", noSideEffect.}
+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: int): int {.magic: "SubU", noSideEffect.}
-proc `-%` *(x, y: int8): int8 {.magic: "SubU", noSideEffect.}
-proc `-%` *(x, y: int16): int16 {.magic: "SubU", noSideEffect.}
-proc `-%` *(x, y: int32): int32 {.magic: "SubU", noSideEffect.}
-proc `-%` *(x, y: int64): int64 {.magic: "SubU64", noSideEffect.}
+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: int): int {.magic: "MulU", noSideEffect.}
-proc `*%` *(x, y: int8): int8 {.magic: "MulU", noSideEffect.}
-proc `*%` *(x, y: int16): int16 {.magic: "MulU", noSideEffect.}
-proc `*%` *(x, y: int32): int32 {.magic: "MulU", noSideEffect.}
-proc `*%` *(x, y: int64): int64 {.magic: "MulU64", noSideEffect.}
+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 `/%` *(x, y: int): int {.magic: "DivU", noSideEffect.}
-proc `/%` *(x, y: int8): int8 {.magic: "DivU", noSideEffect.}
-proc `/%` *(x, y: int16): int16 {.magic: "DivU", noSideEffect.}
-proc `/%` *(x, y: int32): int32 {.magic: "DivU", noSideEffect.}
-proc `/%` *(x, y: int64): int64 {.magic: "DivU64", noSideEffect.}
+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: int): int {.magic: "ModU", noSideEffect.}
-proc `%%` *(x, y: int8): int8 {.magic: "ModU", noSideEffect.}
-proc `%%` *(x, y: int16): int16 {.magic: "ModU", noSideEffect.}
-proc `%%` *(x, y: int32): int32 {.magic: "ModU", noSideEffect.}
-proc `%%` *(x, y: int64): int64 {.magic: "ModU64", noSideEffect.}
+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: int): bool {.magic: "LeU", noSideEffect.}
-proc `<=%` *(x, y: int8): bool {.magic: "LeU", noSideEffect.}
-proc `<=%` *(x, y: int16): bool {.magic: "LeU", noSideEffect.}
-proc `<=%` *(x, y: int32): bool {.magic: "LeU", noSideEffect.}
-proc `<=%` *(x, y: int64): bool {.magic: "LeU64", noSideEffect.}
+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: int): bool {.magic: "LtU", noSideEffect.}
-proc `<%` *(x, y: int8): bool {.magic: "LtU", noSideEffect.}
-proc `<%` *(x, y: int16): bool {.magic: "LtU", noSideEffect.}
-proc `<%` *(x, y: int32): bool {.magic: "LtU", noSideEffect.}
-proc `<%` *(x, y: int64): bool {.magic: "LtU64", noSideEffect.}
+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.
   ## Returns true iff ``unsigned(x) < unsigned(y)``.