Add the IntImpl type. Rename uint_type to datatypes

This commit is contained in:
mratsim 2018-04-25 14:27:55 +02:00
parent 00a634d2f2
commit 40c2215804
12 changed files with 53 additions and 19 deletions

View File

@ -11,7 +11,7 @@
import import
strutils, strutils,
../private/[uint_type, getSize] ../private/[datatypes, getSize]
func tohexBE*[T: uint8 or uint16 or uint32 or uint64](x: T): string = func tohexBE*[T: uint8 or uint16 or uint32 or uint64](x: T): string =
## Stringify an uint to hex, Most significant byte on the left ## Stringify an uint to hex, Most significant byte on the left

View File

@ -7,7 +7,7 @@
# #
# at your option. This file may not be copied, modified, or distributed except according to those terms. # 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 = proc optim(x: NimNode): NimNode =
let size = getSize(x) let size = getSize(x)

View File

@ -7,7 +7,7 @@
# #
# at your option. This file may not be copied, modified, or distributed except according to those terms. # 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 export stdlib_bitops
# We reuse bitops from Nim standard lib, and expand it for multi-precision int. # We reuse bitops from Nim standard lib, and expand it for multi-precision int.

View File

@ -7,7 +7,7 @@
# #
# at your option. This file may not be copied, modified, or distributed except according to those terms. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import ./uint_type, import ./datatypes,
macros, typetraits macros, typetraits
func initUintImpl*[InType, OutType](x: InType, _: typedesc[OutType]): OutType {.inline.} = func initUintImpl*[InType, OutType](x: InType, _: typedesc[OutType]): OutType {.inline.} =

View File

@ -12,16 +12,16 @@
import macros import macros
# The macro getUintImpl must be exported # The macro uintImpl must be exported
when defined(mpint_test): 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 # 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 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" assert bits >= 16, "The number of bits in a should be greater or equal to 16"
if bits >= 128: if bits >= 128:
let inner = getAST(getUintImpl(bits div 2)) let inner = getAST(uintImpl(bits div 2))
result = newTree(nnkBracketExpr, ident("UintImpl"), inner) result = newTree(nnkBracketExpr, ident("UintImpl"), inner)
elif bits == 64: elif bits == 64:
result = newTree(nnkBracketExpr, ident("UintImpl"), ident("uint32")) result = newTree(nnkBracketExpr, ident("UintImpl"), ident("uint32"))
@ -31,14 +31,21 @@ when defined(mpint_test):
result = newTree(nnkBracketExpr, ident("UintImpl"), ident("uint8")) result = newTree(nnkBracketExpr, ident("UintImpl"), ident("uint8"))
else: else:
error "Fatal: unreachable" 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: else:
macro getUintImpl*(bits: static[int]): untyped = macro uintImpl*(bits: static[int]): untyped =
# Release version, StUint[64] = uint64. # Release version, StUint[64] = uint64.
assert (bits and (bits-1)) == 0, $bits & " is not a power of 2" 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" assert bits >= 8, "The number of bits in a should be greater or equal to 8"
if bits >= 128: if bits >= 128:
let inner = getAST(getUintImpl(bits div 2)) let inner = getAST(uintImpl(bits div 2))
result = newTree(nnkBracketExpr, ident("UintImpl"), inner) result = newTree(nnkBracketExpr, ident("UintImpl"), inner)
elif bits == 64: elif bits == 64:
result = ident("uint64") result = ident("uint64")
@ -51,6 +58,24 @@ else:
else: else:
error "Fatal: unreachable" 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] = 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 # 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 lo*, hi*: BaseUint
else: else:
hi*, lo*: BaseUint hi*, lo*: BaseUint
IntImpl*[Baseuint] = object
when system.cpuEndian == littleEndian:
lo*, hi*: BaseUint
else:
hi*, lo*: BaseUint
# ### Private ### # # ### Private ### #
StUint*[bits: static[int]] = object StUint*[bits: static[int]] = object
data*: getUintImpl(bits) data*: uintImpl(bits)
# wrapped in object to avoid recursive calls
StInt*[bits: static[int]] = object
data*: intImpl(bits)

View File

@ -8,7 +8,7 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import ./bithacks, ./conversion, import ./bithacks, ./conversion,
./uint_type, ./datatypes,
./uint_comparison, ./uint_comparison,
./uint_bitwise_ops ./uint_bitwise_ops

View File

@ -7,7 +7,7 @@
# #
# at your option. This file may not be copied, modified, or distributed except according to those terms. # 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.}= func `not`*(x: UintImpl): UintImpl {.noInit, inline.}=

View File

@ -7,7 +7,7 @@
# #
# at your option. This file may not be copied, modified, or distributed except according to those terms. # 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.} = func isZero*(n: SomeUnsignedInt): bool {.inline.} =
n == 0 n == 0

View File

@ -8,7 +8,7 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import ./bithacks, ./conversion, import ./bithacks, ./conversion,
./uint_type, ./datatypes,
./uint_comparison, ./uint_comparison,
./uint_bitwise_ops, ./uint_bitwise_ops,
./uint_addsub, ./uint_addsub,

View File

@ -8,7 +8,7 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import ./conversion, import ./conversion,
./uint_type, ./datatypes,
./uint_comparison, ./uint_comparison,
./uint_addsub ./uint_addsub

View File

@ -9,7 +9,7 @@
import typetraits import typetraits
import ./private/uint_type import ./private/datatypes
import typetraits import typetraits

View File

@ -7,8 +7,8 @@
# #
# at your option. This file may not be copied, modified, or distributed except according to those terms. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import ./private/uint_type, macros import ./private/datatypes, macros
export StUint, UintImpl, getUintImpl # TODO remove the need to export UintImpl and this macro export StUint, UintImpl, uintImpl # TODO remove the need to export UintImpl and this macro
type type
UInt128* = StUint[128] UInt128* = StUint[128]