squashed and merged with devel
This commit is contained in:
parent
2b2efe3dbe
commit
a562de2d91
8 changed files with 55 additions and 13 deletions
|
|
@ -117,7 +117,7 @@ proc sameValue*(a, b: PNode): bool =
|
|||
result = false
|
||||
case a.kind
|
||||
of nkCharLit..nkUInt64Lit:
|
||||
if b.kind in {nkCharLit..nkUInt64Lit}: result = a.intVal == b.intVal
|
||||
if b.kind in {nkCharLit..nkUInt64Lit}: result = getInt(a) == getInt(b)
|
||||
of nkFloatLit..nkFloat64Lit:
|
||||
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal
|
||||
of nkStrLit..nkTripleStrLit:
|
||||
|
|
@ -131,8 +131,8 @@ proc leValue*(a, b: PNode): bool =
|
|||
# a <= b?
|
||||
result = false
|
||||
case a.kind
|
||||
of nkCharLit..nkUInt32Lit:
|
||||
if b.kind in {nkCharLit..nkUInt32Lit}: result = a.intVal <= b.intVal
|
||||
of nkCharLit..nkUInt64Lit:
|
||||
if b.kind in {nkCharLit..nkUInt64Lit}: result = getInt(a) <= getInt(b)
|
||||
of nkFloatLit..nkFloat64Lit:
|
||||
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal <= b.floatVal
|
||||
of nkStrLit..nkTripleStrLit:
|
||||
|
|
|
|||
|
|
@ -565,7 +565,7 @@ proc getNumber(L: var TLexer, result: var TToken) =
|
|||
case result.tokType
|
||||
of floatTypes:
|
||||
result.fNumber = parseFloat(result.literal)
|
||||
of tkUInt64Lit:
|
||||
of tkUInt64Lit, tkUIntLit:
|
||||
var iNumber: uint64
|
||||
var len: int
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
|
|||
n.typ = getSysType(c.graph, n.info, tyInt)
|
||||
of tyArray:
|
||||
n.typ = typ.sons[0] # indextype
|
||||
of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32, tyFloat..tyFloat64:
|
||||
of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt..tyUInt64, tyFloat..tyFloat64:
|
||||
n.typ = n.sons[1].typ.skipTypes({tyTypeDesc})
|
||||
of tyGenericParam:
|
||||
# prepare this for resolving in semtypinst:
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
|||
if not hasUnknownTypes:
|
||||
if not sameType(rangeT[0].skipTypes({tyRange}), rangeT[1].skipTypes({tyRange})):
|
||||
localError(c.config, n.info, "type mismatch")
|
||||
elif not rangeT[0].isOrdinalType and rangeT[0].kind notin tyFloat..tyFloat128 or
|
||||
elif not rangeT[0].isOrdinalType(allowUint=true) and rangeT[0].kind notin tyFloat..tyFloat128 or
|
||||
rangeT[0].kind == tyBool:
|
||||
localError(c.config, n.info, "ordinal or float type expected")
|
||||
elif enumHasHoles(rangeT[0]):
|
||||
|
|
|
|||
|
|
@ -155,14 +155,13 @@ proc enumHasHoles*(t: PType): bool =
|
|||
var b = t.skipTypes({tyRange, tyGenericInst, tyAlias, tySink})
|
||||
result = b.kind == tyEnum and tfEnumHasHoles in b.flags
|
||||
|
||||
proc isOrdinalType*(t: PType, allowEnumWithHoles = false): bool =
|
||||
proc isOrdinalType*(t: PType, allowEnumWithHoles: bool = false): bool =
|
||||
assert(t != nil)
|
||||
const
|
||||
# caution: uint, uint64 are no ordinal types!
|
||||
baseKinds = {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum}
|
||||
baseKinds = {tyChar,tyInt..tyUInt64,tyBool,tyEnum}
|
||||
parentKinds = {tyRange, tyOrdinal, tyGenericInst, tyAlias, tySink, tyDistinct}
|
||||
(t.kind in baseKinds and not (t.enumHasHoles and not allowEnumWithHoles)) or
|
||||
(t.kind in parentKinds and isOrdinalType(t.lastSon))
|
||||
result = (t.kind in baseKinds and not (t.enumHasHoles and not allowEnumWithHoles)) or
|
||||
(t.kind in parentKinds and isOrdinalType(t.lastSon, allowEnumWithHoles))
|
||||
|
||||
proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
|
||||
closure: RootRef): bool
|
||||
|
|
@ -1284,7 +1283,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
|||
result = typeAllowedAux(marker, lastSon(t), kind, flags)
|
||||
of tyRange:
|
||||
if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
|
||||
{tyChar, tyEnum, tyInt..tyFloat128, tyUInt8..tyUInt32}: result = t
|
||||
{tyChar, tyEnum, tyInt..tyFloat128, tyInt..tyUInt64}: result = t
|
||||
of tyOpenArray, tyVarargs, tySink:
|
||||
if kind != skParam:
|
||||
result = t
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ type
|
|||
SomeInteger* = SomeSignedInt|SomeUnsignedInt
|
||||
## Type class matching all integer types.
|
||||
|
||||
SomeOrdinal* = int|int8|int16|int32|int64|bool|enum|uint8|uint16|uint32
|
||||
SomeOrdinal* = int|int8|int16|int32|int64|bool|enum|uint|uint8|uint16|uint32|uint64
|
||||
## Type class matching all ordinal types; however this includes enums with
|
||||
## holes.
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ block tcast:
|
|||
crossCheck(uint16, uint16.high + 5'u16)
|
||||
crossCheck(uint32, uint32.high + 5'u32)
|
||||
crossCheck(uint64, 0xFFFFFFFFFFFFFFFF'u64 + 5'u64)
|
||||
crossCheck(uint64, uint64.high + 5'u64)
|
||||
|
||||
doAssert $sub1(0'u8) == "255"
|
||||
doAssert $sub1(0'u16) == "65535"
|
||||
|
|
|
|||
42
tests/converter/tstatic_range_checks.nim
Normal file
42
tests/converter/tstatic_range_checks.nim
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
template reject(e) =
|
||||
static: assert(not compiles(e))
|
||||
|
||||
template accept(e) =
|
||||
static: assert(compiles(e))
|
||||
|
||||
type
|
||||
UnsignedRange = 0'u64 .. 100'u64
|
||||
SemiOutOfBounds = 0x7ffffffffffffe00'u64 .. 0x8000000000000100'u64
|
||||
FullOutOfBounds = 0x8000000000000000'u64 .. 0x8000000000000200'u64
|
||||
|
||||
FullNegativeRange = -200 .. -100
|
||||
HalfNegativeRange = -50 .. 50
|
||||
FullPositiveRange = 100 .. 200
|
||||
|
||||
reject(int32(0x80000000'i64))
|
||||
accept(int32(0x7fffffff'i64))
|
||||
|
||||
reject(uint64(-1'i64))
|
||||
accept(uint64(0'i64))
|
||||
|
||||
reject(FullNegativeRange(0xff'u32))
|
||||
reject(HalfNegativeRange(0xffffffffffffffff'u64)) # internal `intVal` is `-1` which would be in range.
|
||||
accept(HalfNegativeRange(25'u64))
|
||||
reject(FullPositiveRange(300'u64))
|
||||
|
||||
accept(UnsignedRange(50'u64))
|
||||
reject(UnsignedRange(101'u64))
|
||||
|
||||
accept(SemiOutOfBounds(0x7ffffffffffffe00'i64))
|
||||
reject(SemiOutOfBounds(0x8000000000000000'i64)) #
|
||||
accept(SemiOutOfBounds(0x8000000000000000'u64)) # the last two literals have internally the same `intVal`.
|
||||
|
||||
reject(int32(NaN))
|
||||
reject(int64(1e100))
|
||||
reject(uint64(1e100))
|
||||
|
||||
# removed cross checks from tarithm.nim
|
||||
reject(int64(0xFFFFFFFFFFFFFFFF'u64))
|
||||
reject(int32(0xFFFFFFFFFFFFFFFF'u64))
|
||||
reject(int16(0xFFFFFFFFFFFFFFFF'u64))
|
||||
reject( int8(0xFFFFFFFFFFFFFFFF'u64))
|
||||
Loading…
Add table
Add a link
Reference in a new issue