add custom literal feature

This commit is contained in:
jangko 2023-07-07 13:22:22 +07:00
parent 3e9d64c896
commit e374311f70
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
4 changed files with 69 additions and 2 deletions

View File

@ -31,3 +31,15 @@ func i256*(s: string): Int256 {.inline.} = s.parse(Int256)
# According to nim manual, you can write something like 1234567890'u256
# or 1234567890'i256, and the number will be passed as string to the
# constructor
func `'i128`*(s: static string): Int128 {.inline.} =
customLiteral(Int128, s)
func `'i256`*(s: static string): Int256 {.inline.} =
customLiteral(Int256, s)
func `'u128`*(s: static string): UInt128 {.inline.} =
customLiteral(UInt128, s)
func `'u256`*(s: static string): UInt256 {.inline.} =
customLiteral(UInt256, s)

View File

@ -261,7 +261,7 @@ func parse*[bits: static[int]](input: string,
func parse*[bits: static[int]](input: string,
T: typedesc[StInt[bits]],
radix: static[int8] = 10): T =
radix: static[uint8] = 10): T =
## Parse a string and store the result in a Stint[bits] or StUint[bits].
static: doAssert (radix >= 2) and radix <= 16, "Only base from 2..16 are supported"
@ -465,3 +465,27 @@ template toBytesBE*[bits: static[int]](n: StInt[bits]): array[bits div 8, byte]
result = n.impl.toBytesBE()
{.pop.}
func getRadix(s: static string): uint8 {.compileTime.} =
if s.len <= 2:
return 10
# maybe have prefix have prefix
if s[0] != '0':
return 10
if s[1] == 'b':
return 2
if s[1] == 'o':
return 8
if s[1] == 'x':
return 16
func customLiteral*(T: type SomeBigInteger, s: static string): T =
when s.len == 0:
doAssert(false, "customLiteral cannot accept param with zero length")
const radix = getRadix(s)
parse(s, T, radix)

View File

@ -35,4 +35,6 @@ import
test_io,
test_conversion,
t_randomized_divmod,
test_bugfix
test_bugfix,
test_features

29
tests/test_features.nim Normal file
View File

@ -0,0 +1,29 @@
# Copyright 2023 Status Research & Development GmbH
# Licensed under either of
#
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
#
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import ../stint, unittest
suite "new features":
test "custom literal":
const
a = 0xabcdef0123456'u128
b = 0xabcdef0123456'u256
c = -100'i128
d = -50000'i256
let
x = 0b111100011'u128
y = 0o777766666'u256
check:
a == 0xabcdef0123456.u128
b == 0xabcdef0123456.u256
c == -100.i128
d == -50000.i256
x == 0b111100011.u128
y == 0o777766666.u256