-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: Have the number of bits be part of the type #2
Comments
Actually this is even simpler: import macros, typetraits
macro getBase*(bits: static[int]): untyped =
# Check if power of 2 greater or equal to 16
assert bits >= 16, $bits & " should be greater or equal 16"
assert (bits and (bits-1)) == 0, $bits & " is not a power of 2"
case bits:
of 128: result = ident("uint64")
of 64: result = ident("uint32") # This is useful for test purposes to compare with actual uint64
of 32: result = ident("uint16")
of 16: result = ident("uint8")
else:
result = newTree(nnkBracketExpr, ident("MpUint"), newIntLitNode(bits div 2))
#type
# MpUint*[bits: static[int]] = object
# lo*, hi*: getBase(bits)
type MpUint*[bits: static[int]] = object
## This works fine
var foo: getBase(128)
echo foo.type.name We can always get the subtype by using |
New try, but stuck again, upstreamed: nim-lang/Nim#7378 type
MpUint*[bits: static[int]] = object
when system.cpuEndian == littleEndian:
when bits == 128: lo*, hi*: uint64
elif bits == 64: lo*, hi*: uint32
elif bits == 32: lo*, hi*: uint16
elif bits == 16: lo*, hi*: uint8
else:
lo*, hi*: MpUint[bits div 2]
else:
when bits == 128: hi*, lo*: uint64
elif bits == 64: hi*, lo*: uint32
elif bits == 32: hi*, lo*: uint16
elif bits == 16: hi*, lo*: uint8
else:
hi*, lo*: MpUint[bits div 2]
proc toMpUint*(n: uint16): MpUint[16] =
cast[type result](n)
let a = 10'u16
var b = a.toMpUint()
echo b # works
## uncomment the following for failure
# proc fails_always(x: MpUint, y: MpUint) =
# echo x
# Error: cannot generate code for: bits
proc fails_if_called*[bits: static[int]](x: MpUint[bits], y: MpUint[bits]) =
echo x
## uncomment the following for failure
# fails_if_called(b, b) # Error: cannot generate code for: bits
fails_if_called[16](b, b) # This works but we shouldn't have to tell the size each time |
Another try, it's when that cannot access the static int: nim-lang/Nim#7378 type
BaseUint* = SomeUnsignedInt or MpUintBase
MpUintBase*[BaseUint] = object
lo*, hi*: BaseUint
type
# works
Foo*[bits: static[int]] = (
when true:
MpUintBase[uint64]
)
type
# Cannot generate bits
Bar*[bits: static[int]] = (
when bits == 128: # Error points to the bits here
MpUintBase[uint64]
) |
Yet another try, upstreamed: nim-lang/Nim#7379 import macros
macro works(): untyped =
result = getType(int)
macro fails(bits: static[int]): untyped =
result = getType(int)
type
Foo*[bits: static[int]] = works()
Bar*[bits: static[int]] = fails(bits)
|
Another bug raised, non-blocking but impacts performance (we can't inline type conversion otherwise it might triggers memory corruption): nim-lang/Nim#7382 |
Implemented by #6 |
Currently the type for Uint256 is
MpUint[MpUint[uint64]]
. Also making the jump fromMpUint[uint32]
touint64
is logic but not intuitive.A better way would be to use
MpUint[256]
orMpUint[64]
for example, so have the number of bits be part of the type. Still being able to retrieve the underlying type (uint64 or MpUint64) eases the implementation a lot.Here is a proposed solution, it is currently blocked by the following Nim bug: nim-lang/Nim#7230
The text was updated successfully, but these errors were encountered: