From 40c2215804b3afa18c04d4e068c174adcba55d72 Mon Sep 17 00:00:00 2001 From: mratsim Date: Wed, 25 Apr 2018 14:27:55 +0200 Subject: [PATCH] Add the IntImpl type. Rename uint_type to datatypes --- src/debug/debugutils.nim | 2 +- src/private/as_words.nim | 2 +- src/private/bithacks.nim | 2 +- src/private/conversion.nim | 2 +- src/private/{uint_type.nim => datatypes.nim} | 48 +++++++++++++++++--- src/private/uint_addsub.nim | 2 +- src/private/uint_bitwise_ops.nim | 2 +- src/private/uint_comparison.nim | 2 +- src/private/uint_div.nim | 2 +- src/private/uint_mul.nim | 2 +- src/uint_init.nim | 2 +- src/uint_public.nim | 4 +- 12 files changed, 53 insertions(+), 19 deletions(-) rename src/private/{uint_type.nim => datatypes.nim} (71%) diff --git a/src/debug/debugutils.nim b/src/debug/debugutils.nim index 0382850..3688aeb 100644 --- a/src/debug/debugutils.nim +++ b/src/debug/debugutils.nim @@ -11,7 +11,7 @@ import strutils, - ../private/[uint_type, getSize] + ../private/[datatypes, getSize] func tohexBE*[T: uint8 or uint16 or uint32 or uint64](x: T): string = ## Stringify an uint to hex, Most significant byte on the left diff --git a/src/private/as_words.nim b/src/private/as_words.nim index 0a3c83f..09f16cc 100644 --- a/src/private/as_words.nim +++ b/src/private/as_words.nim @@ -7,7 +7,7 @@ # # at your option. This file may not be copied, modified, or distributed except according to those terms. -import ./uint_type, macros +import ./datatypes, macros proc optim(x: NimNode): NimNode = let size = getSize(x) diff --git a/src/private/bithacks.nim b/src/private/bithacks.nim index f7b4ea3..0caaa67 100644 --- a/src/private/bithacks.nim +++ b/src/private/bithacks.nim @@ -7,7 +7,7 @@ # # at your option. This file may not be copied, modified, or distributed except according to those terms. -import ./uint_type, stdlib_bitops +import ./datatypes, stdlib_bitops export stdlib_bitops # We reuse bitops from Nim standard lib, and expand it for multi-precision int. diff --git a/src/private/conversion.nim b/src/private/conversion.nim index a54e61b..821184f 100644 --- a/src/private/conversion.nim +++ b/src/private/conversion.nim @@ -7,7 +7,7 @@ # # at your option. This file may not be copied, modified, or distributed except according to those terms. -import ./uint_type, +import ./datatypes, macros, typetraits func initUintImpl*[InType, OutType](x: InType, _: typedesc[OutType]): OutType {.inline.} = diff --git a/src/private/uint_type.nim b/src/private/datatypes.nim similarity index 71% rename from src/private/uint_type.nim rename to src/private/datatypes.nim index 68c0703..31799d1 100644 --- a/src/private/uint_type.nim +++ b/src/private/datatypes.nim @@ -12,16 +12,16 @@ import macros -# The macro getUintImpl must be exported +# The macro uintImpl must be exported when defined(mpint_test): - macro getUintImpl*(bits: static[int]): untyped = + macro uintImpl*(bits: static[int]): untyped = # Test version, StUint[64] = 2 uint32. Test the logic of the library assert (bits and (bits-1)) == 0, $bits & " is not a power of 2" assert bits >= 16, "The number of bits in a should be greater or equal to 16" if bits >= 128: - let inner = getAST(getUintImpl(bits div 2)) + let inner = getAST(uintImpl(bits div 2)) result = newTree(nnkBracketExpr, ident("UintImpl"), inner) elif bits == 64: result = newTree(nnkBracketExpr, ident("UintImpl"), ident("uint32")) @@ -31,14 +31,21 @@ when defined(mpint_test): result = newTree(nnkBracketExpr, ident("UintImpl"), ident("uint8")) else: error "Fatal: unreachable" + + macro intImpl*(bits: static[int]): untyped = + # Test version, StInt[64] = 2 uint32. Test the logic of the library + # Note that ints are implemented in terms of unsigned ints + # SIgned operatiosn will be built on top of that. + result = getAst(uintImpl(bits)) + else: - macro getUintImpl*(bits: static[int]): untyped = + macro uintImpl*(bits: static[int]): untyped = # Release version, StUint[64] = uint64. assert (bits and (bits-1)) == 0, $bits & " is not a power of 2" assert bits >= 8, "The number of bits in a should be greater or equal to 8" if bits >= 128: - let inner = getAST(getUintImpl(bits div 2)) + let inner = getAST(uintImpl(bits div 2)) result = newTree(nnkBracketExpr, ident("UintImpl"), inner) elif bits == 64: result = ident("uint64") @@ -51,6 +58,24 @@ else: else: error "Fatal: unreachable" + macro intImpl*(bits: static[int]): untyped = + # Release version, StInt[64] = int64. + # Note that int of size 128+ are implemented in terms of unsigned ints + # Signed operations will be built on top of that. + + if bits >= 128: + result = getAst(uintImpl(bits)) + elif bits == 64: + result = ident("int64") + elif bits == 32: + result = ident("int32") + elif bits == 16: + result = ident("int16") + elif bits == 8: + result = ident("int8") + else: + error "Fatal: unreachable" + proc getSize*(x: NimNode): static[int] = # Size of doesn't always work at compile-time, pending PR https://github.com/nim-lang/Nim/pull/5664 @@ -93,8 +118,17 @@ type lo*, hi*: BaseUint else: hi*, lo*: BaseUint + + IntImpl*[Baseuint] = object + when system.cpuEndian == littleEndian: + lo*, hi*: BaseUint + else: + hi*, lo*: BaseUint + # ### Private ### # StUint*[bits: static[int]] = object - data*: getUintImpl(bits) - # wrapped in object to avoid recursive calls + data*: uintImpl(bits) + + StInt*[bits: static[int]] = object + data*: intImpl(bits) diff --git a/src/private/uint_addsub.nim b/src/private/uint_addsub.nim index b83b5fe..86cebe3 100644 --- a/src/private/uint_addsub.nim +++ b/src/private/uint_addsub.nim @@ -8,7 +8,7 @@ # at your option. This file may not be copied, modified, or distributed except according to those terms. import ./bithacks, ./conversion, - ./uint_type, + ./datatypes, ./uint_comparison, ./uint_bitwise_ops diff --git a/src/private/uint_bitwise_ops.nim b/src/private/uint_bitwise_ops.nim index b724de8..86f2d2f 100644 --- a/src/private/uint_bitwise_ops.nim +++ b/src/private/uint_bitwise_ops.nim @@ -7,7 +7,7 @@ # # at your option. This file may not be copied, modified, or distributed except according to those terms. -import ./uint_type, ./as_words +import ./datatypes, ./as_words func `not`*(x: UintImpl): UintImpl {.noInit, inline.}= diff --git a/src/private/uint_comparison.nim b/src/private/uint_comparison.nim index 21e1894..2eca293 100644 --- a/src/private/uint_comparison.nim +++ b/src/private/uint_comparison.nim @@ -7,7 +7,7 @@ # # at your option. This file may not be copied, modified, or distributed except according to those terms. -import ./uint_type, ./as_words +import ./datatypes, ./as_words func isZero*(n: SomeUnsignedInt): bool {.inline.} = n == 0 diff --git a/src/private/uint_div.nim b/src/private/uint_div.nim index 61b3452..fb65639 100644 --- a/src/private/uint_div.nim +++ b/src/private/uint_div.nim @@ -8,7 +8,7 @@ # at your option. This file may not be copied, modified, or distributed except according to those terms. import ./bithacks, ./conversion, - ./uint_type, + ./datatypes, ./uint_comparison, ./uint_bitwise_ops, ./uint_addsub, diff --git a/src/private/uint_mul.nim b/src/private/uint_mul.nim index 1740149..e60aad5 100644 --- a/src/private/uint_mul.nim +++ b/src/private/uint_mul.nim @@ -8,7 +8,7 @@ # at your option. This file may not be copied, modified, or distributed except according to those terms. import ./conversion, - ./uint_type, + ./datatypes, ./uint_comparison, ./uint_addsub diff --git a/src/uint_init.nim b/src/uint_init.nim index 78c9cef..76358da 100644 --- a/src/uint_init.nim +++ b/src/uint_init.nim @@ -9,7 +9,7 @@ import typetraits -import ./private/uint_type +import ./private/datatypes import typetraits diff --git a/src/uint_public.nim b/src/uint_public.nim index e4d4f40..8e9a7ec 100644 --- a/src/uint_public.nim +++ b/src/uint_public.nim @@ -7,8 +7,8 @@ # # at your option. This file may not be copied, modified, or distributed except according to those terms. -import ./private/uint_type, macros -export StUint, UintImpl, getUintImpl # TODO remove the need to export UintImpl and this macro +import ./private/datatypes, macros +export StUint, UintImpl, uintImpl # TODO remove the need to export UintImpl and this macro type UInt128* = StUint[128]