Merge branch 'devel' into uint-range-checks
This commit is contained in:
commit
ac6fcab7a4
18 changed files with 123 additions and 51 deletions
|
|
@ -608,7 +608,6 @@ type
|
||||||
mAddF64, mSubF64, mMulF64, mDivF64,
|
mAddF64, mSubF64, mMulF64, mDivF64,
|
||||||
mShrI, mShlI, mAshrI, mBitandI, mBitorI, mBitxorI,
|
mShrI, mShlI, mAshrI, mBitandI, mBitorI, mBitxorI,
|
||||||
mMinI, mMaxI,
|
mMinI, mMaxI,
|
||||||
mMinF64, mMaxF64,
|
|
||||||
mAddU, mSubU, mMulU, mDivU, mModU,
|
mAddU, mSubU, mMulU, mDivU, mModU,
|
||||||
mEqI, mLeI, mLtI,
|
mEqI, mLeI, mLtI,
|
||||||
mEqF64, mLeF64, mLtF64,
|
mEqF64, mLeF64, mLtF64,
|
||||||
|
|
@ -621,7 +620,7 @@ type
|
||||||
mXor, mEqCString, mEqProc,
|
mXor, mEqCString, mEqProc,
|
||||||
mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot,
|
mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot,
|
||||||
mUnaryPlusI, mBitnotI,
|
mUnaryPlusI, mBitnotI,
|
||||||
mUnaryPlusF64, mUnaryMinusF64, mAbsF64,
|
mUnaryPlusF64, mUnaryMinusF64,
|
||||||
mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr,
|
mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr,
|
||||||
mStrToStr, mEnumToStr,
|
mStrToStr, mEnumToStr,
|
||||||
mAnd, mOr,
|
mAnd, mOr,
|
||||||
|
|
@ -678,7 +677,6 @@ const
|
||||||
mAddF64, mSubF64, mMulF64, mDivF64,
|
mAddF64, mSubF64, mMulF64, mDivF64,
|
||||||
mShrI, mShlI, mBitandI, mBitorI, mBitxorI,
|
mShrI, mShlI, mBitandI, mBitorI, mBitxorI,
|
||||||
mMinI, mMaxI,
|
mMinI, mMaxI,
|
||||||
mMinF64, mMaxF64,
|
|
||||||
mAddU, mSubU, mMulU, mDivU, mModU,
|
mAddU, mSubU, mMulU, mDivU, mModU,
|
||||||
mEqI, mLeI, mLtI,
|
mEqI, mLeI, mLtI,
|
||||||
mEqF64, mLeF64, mLtF64,
|
mEqF64, mLeF64, mLtF64,
|
||||||
|
|
@ -689,7 +687,7 @@ const
|
||||||
mEqB, mLeB, mLtB,
|
mEqB, mLeB, mLtB,
|
||||||
mEqRef, mEqProc, mEqUntracedRef, mLePtr, mLtPtr, mEqCString, mXor,
|
mEqRef, mEqProc, mEqUntracedRef, mLePtr, mLtPtr, mEqCString, mXor,
|
||||||
mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot, mUnaryPlusI, mBitnotI,
|
mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot, mUnaryPlusI, mBitnotI,
|
||||||
mUnaryPlusF64, mUnaryMinusF64, mAbsF64,
|
mUnaryPlusF64, mUnaryMinusF64,
|
||||||
mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr,
|
mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr,
|
||||||
mStrToStr, mEnumToStr,
|
mStrToStr, mEnumToStr,
|
||||||
mAnd, mOr,
|
mAnd, mOr,
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,6 @@ proc idNodeTablePut*(t: var TIdNodeTable, key: PIdObj, val: PNode)
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
proc getSymFromList*(list: PNode, ident: PIdent, start: int = 0): PSym
|
|
||||||
proc lookupInRecord*(n: PNode, field: PIdent): PSym
|
proc lookupInRecord*(n: PNode, field: PIdent): PSym
|
||||||
proc mustRehash*(length, counter: int): bool
|
proc mustRehash*(length, counter: int): bool
|
||||||
proc nextTry*(h, maxHash: Hash): Hash {.inline.}
|
proc nextTry*(h, maxHash: Hash): Hash {.inline.}
|
||||||
|
|
@ -174,7 +173,7 @@ proc getModule*(s: PSym): PSym =
|
||||||
assert((result.kind == skModule) or (result.owner != result))
|
assert((result.kind == skModule) or (result.owner != result))
|
||||||
while result != nil and result.kind != skModule: result = result.owner
|
while result != nil and result.kind != skModule: result = result.owner
|
||||||
|
|
||||||
proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym =
|
proc getSymFromList*(list: PNode, ident: PIdent, start: int = 0): PSym =
|
||||||
for i in start ..< sonsLen(list):
|
for i in start ..< sonsLen(list):
|
||||||
if list.sons[i].kind == nkSym:
|
if list.sons[i].kind == nkSym:
|
||||||
result = list.sons[i].sym
|
result = list.sons[i].sym
|
||||||
|
|
@ -182,6 +181,45 @@ proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym =
|
||||||
else: return nil
|
else: return nil
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
|
proc sameIgnoreBacktickGensymInfo(a, b: string): bool =
|
||||||
|
if a[0] != b[0]: return false
|
||||||
|
var last = a.len - 1
|
||||||
|
while last > 0 and a[last] != '`': dec(last)
|
||||||
|
|
||||||
|
var i = 1
|
||||||
|
var j = 1
|
||||||
|
while true:
|
||||||
|
while i < last and a[i] == '_': inc i
|
||||||
|
while j < b.len and b[j] == '_': inc j
|
||||||
|
var aa = if i < last: toLowerAscii(a[i]) else: '\0'
|
||||||
|
var bb = if j < b.len: toLowerAscii(b[j]) else: '\0'
|
||||||
|
if aa != bb: return false
|
||||||
|
|
||||||
|
# the characters are identical:
|
||||||
|
if i >= last:
|
||||||
|
# both cursors at the end:
|
||||||
|
if j >= b.len: return true
|
||||||
|
# not yet at the end of 'b':
|
||||||
|
return false
|
||||||
|
elif j >= b.len:
|
||||||
|
return false
|
||||||
|
inc i
|
||||||
|
inc j
|
||||||
|
|
||||||
|
proc getNamedParamFromList*(list: PNode, ident: PIdent): PSym =
|
||||||
|
## Named parameters are special because a named parameter can be
|
||||||
|
## gensym'ed and then they have '`<number>' suffix that we need to
|
||||||
|
## ignore, see compiler / evaltempl.nim, snippet:
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
##
|
||||||
|
## result.add newIdentNode(getIdent(c.ic, x.name.s & "`gensym" & $x.id),
|
||||||
|
## if c.instLines: actual.info else: templ.info)
|
||||||
|
for i in 1 ..< len(list):
|
||||||
|
let it = list[i].sym
|
||||||
|
if it.name.id == ident.id or
|
||||||
|
sameIgnoreBacktickGensymInfo(it.name.s, ident.s): return it
|
||||||
|
|
||||||
proc hashNode(p: RootRef): Hash =
|
proc hashNode(p: RootRef): Hash =
|
||||||
result = hash(cast[pointer](p))
|
result = hash(cast[pointer](p))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -588,8 +588,6 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
of mBitxorI: applyFormat("($4)($1 ^ $2)")
|
of mBitxorI: applyFormat("($4)($1 ^ $2)")
|
||||||
of mMinI: applyFormat("(($1 <= $2) ? $1 : $2)")
|
of mMinI: applyFormat("(($1 <= $2) ? $1 : $2)")
|
||||||
of mMaxI: applyFormat("(($1 >= $2) ? $1 : $2)")
|
of mMaxI: applyFormat("(($1 >= $2) ? $1 : $2)")
|
||||||
of mMinF64: applyFormat("(($1 <= $2) ? $1 : $2)")
|
|
||||||
of mMaxF64: applyFormat("(($1 >= $2) ? $1 : $2)")
|
|
||||||
of mAddU: applyFormat("($4)((NU$3)($1) + (NU$3)($2))")
|
of mAddU: applyFormat("($4)((NU$3)($1) + (NU$3)($2))")
|
||||||
of mSubU: applyFormat("($4)((NU$3)($1) - (NU$3)($2))")
|
of mSubU: applyFormat("($4)((NU$3)($1) - (NU$3)($2))")
|
||||||
of mMulU: applyFormat("($4)((NU$3)($1) * (NU$3)($2))")
|
of mMulU: applyFormat("($4)((NU$3)($1) * (NU$3)($2))")
|
||||||
|
|
@ -663,9 +661,6 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
applyFormat("$1")
|
applyFormat("$1")
|
||||||
of mUnaryMinusF64:
|
of mUnaryMinusF64:
|
||||||
applyFormat("-($1)")
|
applyFormat("-($1)")
|
||||||
of mAbsF64:
|
|
||||||
applyFormat("($1 < 0? -($1) : ($1))")
|
|
||||||
# BUGFIX: fabs() makes problems for Tiny C
|
|
||||||
else:
|
else:
|
||||||
assert false, $op
|
assert false, $op
|
||||||
|
|
||||||
|
|
@ -2086,7 +2081,7 @@ proc genEnumToStr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
case op
|
case op
|
||||||
of mOr, mAnd: genAndOr(p, e, d, op)
|
of mOr, mAnd: genAndOr(p, e, d, op)
|
||||||
of mNot..mAbsF64: unaryArith(p, e, d, op)
|
of mNot..mUnaryMinusF64: unaryArith(p, e, d, op)
|
||||||
of mUnaryMinusI..mAbsI: unaryArithOverflow(p, e, d, op)
|
of mUnaryMinusI..mAbsI: unaryArithOverflow(p, e, d, op)
|
||||||
of mAddF64..mDivF64: binaryFloatArith(p, e, d, op)
|
of mAddF64..mDivF64: binaryFloatArith(p, e, d, op)
|
||||||
of mShrI..mXor: binaryArith(p, e, d, op)
|
of mShrI..mXor: binaryArith(p, e, d, op)
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ const
|
||||||
someMul = {mMulI, mMulF64}
|
someMul = {mMulI, mMulF64}
|
||||||
someDiv = {mDivI, mDivF64}
|
someDiv = {mDivI, mDivF64}
|
||||||
someMod = {mModI}
|
someMod = {mModI}
|
||||||
someMax = {mMaxI, mMaxF64}
|
someMax = {mMaxI}
|
||||||
someMin = {mMinI, mMinF64}
|
someMin = {mMinI}
|
||||||
someBinaryOp = someAdd+someSub+someMul+someMax+someMin
|
someBinaryOp = someAdd+someSub+someMul+someMax+someMin
|
||||||
|
|
||||||
proc isValue(n: PNode): bool = n.kind in {nkCharLit..nkNilLit}
|
proc isValue(n: PNode): bool = n.kind in {nkCharLit..nkNilLit}
|
||||||
|
|
|
||||||
|
|
@ -389,8 +389,6 @@ const # magic checked op; magic unchecked op;
|
||||||
["", ""], # BitxorI
|
["", ""], # BitxorI
|
||||||
["nimMin", "nimMin"], # MinI
|
["nimMin", "nimMin"], # MinI
|
||||||
["nimMax", "nimMax"], # MaxI
|
["nimMax", "nimMax"], # MaxI
|
||||||
["nimMin", "nimMin"], # MinF64
|
|
||||||
["nimMax", "nimMax"], # MaxF64
|
|
||||||
["", ""], # addU
|
["", ""], # addU
|
||||||
["", ""], # subU
|
["", ""], # subU
|
||||||
["", ""], # mulU
|
["", ""], # mulU
|
||||||
|
|
@ -430,7 +428,6 @@ const # magic checked op; magic unchecked op;
|
||||||
["", ""], # BitnotI
|
["", ""], # BitnotI
|
||||||
["", ""], # UnaryPlusF64
|
["", ""], # UnaryPlusF64
|
||||||
["", ""], # UnaryMinusF64
|
["", ""], # UnaryMinusF64
|
||||||
["", ""], # AbsF64
|
|
||||||
["nimCharToStr", "nimCharToStr"],
|
["nimCharToStr", "nimCharToStr"],
|
||||||
["nimBoolToStr", "nimBoolToStr"],
|
["nimBoolToStr", "nimBoolToStr"],
|
||||||
["cstrToNimstr", "cstrToNimstr"],
|
["cstrToNimstr", "cstrToNimstr"],
|
||||||
|
|
@ -566,8 +563,6 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
|
||||||
of mBitxorI: applyFormat("($1 ^ $2)", "($1 ^ $2)")
|
of mBitxorI: applyFormat("($1 ^ $2)", "($1 ^ $2)")
|
||||||
of mMinI: applyFormat("nimMin($1, $2)", "nimMin($1, $2)")
|
of mMinI: applyFormat("nimMin($1, $2)", "nimMin($1, $2)")
|
||||||
of mMaxI: applyFormat("nimMax($1, $2)", "nimMax($1, $2)")
|
of mMaxI: applyFormat("nimMax($1, $2)", "nimMax($1, $2)")
|
||||||
of mMinF64: applyFormat("nimMin($1, $2)", "nimMin($1, $2)")
|
|
||||||
of mMaxF64: applyFormat("nimMax($1, $2)", "nimMax($1, $2)")
|
|
||||||
of mAddU: applyFormat("", "")
|
of mAddU: applyFormat("", "")
|
||||||
of mSubU: applyFormat("", "")
|
of mSubU: applyFormat("", "")
|
||||||
of mMulU: applyFormat("", "")
|
of mMulU: applyFormat("", "")
|
||||||
|
|
@ -607,7 +602,6 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
|
||||||
of mBitnotI: applyFormat("~($1)", "~($1)")
|
of mBitnotI: applyFormat("~($1)", "~($1)")
|
||||||
of mUnaryPlusF64: applyFormat("+($1)", "+($1)")
|
of mUnaryPlusF64: applyFormat("+($1)", "+($1)")
|
||||||
of mUnaryMinusF64: applyFormat("-($1)", "-($1)")
|
of mUnaryMinusF64: applyFormat("-($1)", "-($1)")
|
||||||
of mAbsF64: applyFormat("Math.abs($1)", "Math.abs($1)")
|
|
||||||
of mCharToStr: applyFormat("nimCharToStr($1)", "nimCharToStr($1)")
|
of mCharToStr: applyFormat("nimCharToStr($1)", "nimCharToStr($1)")
|
||||||
of mBoolToStr: applyFormat("nimBoolToStr($1)", "nimBoolToStr($1)")
|
of mBoolToStr: applyFormat("nimBoolToStr($1)", "nimBoolToStr($1)")
|
||||||
of mIntToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")
|
of mIntToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")
|
||||||
|
|
|
||||||
|
|
@ -224,14 +224,14 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
|
||||||
result = arLocalLValue
|
result = arLocalLValue
|
||||||
else:
|
else:
|
||||||
result = arLValue
|
result = arLValue
|
||||||
elif n.sym.kind == skParam and n.sym.typ.kind == tyVar:
|
elif n.sym.kind == skParam and n.sym.typ.kind in {tyVar, tySink}:
|
||||||
result = arLValue
|
result = arLValue
|
||||||
elif n.sym.kind == skType:
|
elif n.sym.kind == skType:
|
||||||
let t = n.sym.typ.skipTypes({tyTypeDesc})
|
let t = n.sym.typ.skipTypes({tyTypeDesc})
|
||||||
if t.kind == tyVar: result = arStrange
|
if t.kind == tyVar: result = arStrange
|
||||||
of nkDotExpr:
|
of nkDotExpr:
|
||||||
let t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc})
|
let t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc})
|
||||||
if t.kind in {tyVar, tyPtr, tyRef}:
|
if t.kind in {tyVar, tySink, tyPtr, tyRef}:
|
||||||
result = arLValue
|
result = arLValue
|
||||||
elif isUnsafeAddr and t.kind == tyLent:
|
elif isUnsafeAddr and t.kind == tyLent:
|
||||||
result = arLValue
|
result = arLValue
|
||||||
|
|
@ -242,7 +242,7 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
|
||||||
result = arDiscriminant
|
result = arDiscriminant
|
||||||
of nkBracketExpr:
|
of nkBracketExpr:
|
||||||
let t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc})
|
let t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc})
|
||||||
if t.kind in {tyVar, tyPtr, tyRef}:
|
if t.kind in {tyVar, tySink, tyPtr, tyRef}:
|
||||||
result = arLValue
|
result = arLValue
|
||||||
elif isUnsafeAddr and t.kind == tyLent:
|
elif isUnsafeAddr and t.kind == tyLent:
|
||||||
result = arLValue
|
result = arLValue
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,6 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
|
||||||
result = newIntNodeT(toInt128(sonsLen(a)), n, g)
|
result = newIntNodeT(toInt128(sonsLen(a)), n, g)
|
||||||
of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
|
of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
|
||||||
# XXX: Hides overflow/underflow
|
# XXX: Hides overflow/underflow
|
||||||
of mAbsF64: result = newFloatNodeT(abs(getFloat(a)), n, g)
|
|
||||||
of mAbsI: result = foldAbs(getInt(a), n, g)
|
of mAbsI: result = foldAbs(getInt(a), n, g)
|
||||||
of mUnaryLt: result = foldSub(getOrdValue(a), One, n, g)
|
of mUnaryLt: result = foldSub(getOrdValue(a), One, n, g)
|
||||||
of mSucc: result = foldAdd(getOrdValue(a), getInt(b), n, g)
|
of mSucc: result = foldAdd(getOrdValue(a), getInt(b), n, g)
|
||||||
|
|
@ -277,12 +276,6 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
|
||||||
of mMulF64: result = newFloatNodeT(getFloat(a) * getFloat(b), n, g)
|
of mMulF64: result = newFloatNodeT(getFloat(a) * getFloat(b), n, g)
|
||||||
of mDivF64:
|
of mDivF64:
|
||||||
result = newFloatNodeT(getFloat(a) / getFloat(b), n, g)
|
result = newFloatNodeT(getFloat(a) / getFloat(b), n, g)
|
||||||
of mMaxF64:
|
|
||||||
if getFloat(a) > getFloat(b): result = newFloatNodeT(getFloat(a), n, g)
|
|
||||||
else: result = newFloatNodeT(getFloat(b), n, g)
|
|
||||||
of mMinF64:
|
|
||||||
if getFloat(a) > getFloat(b): result = newFloatNodeT(getFloat(b), n, g)
|
|
||||||
else: result = newFloatNodeT(getFloat(a), n, g)
|
|
||||||
of mIsNil: result = newIntNodeT(ord(a.kind == nkNilLit), n, g)
|
of mIsNil: result = newIntNodeT(ord(a.kind == nkNilLit), n, g)
|
||||||
of mLtI, mLtB, mLtEnum, mLtCh:
|
of mLtI, mLtB, mLtEnum, mLtCh:
|
||||||
result = newIntNodeT(ord(getOrdValue(a) < getOrdValue(b)), n, g)
|
result = newIntNodeT(ord(getOrdValue(a) < getOrdValue(b)), n, g)
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule;
|
||||||
while a != nil:
|
while a != nil:
|
||||||
if a.kind != skModule and (not isField or sfGenSym notin s.flags):
|
if a.kind != skModule and (not isField or sfGenSym notin s.flags):
|
||||||
incl(a.flags, sfUsed)
|
incl(a.flags, sfUsed)
|
||||||
|
markOwnerModuleAsUsed(c, a)
|
||||||
addSon(result, newSymNode(a, info))
|
addSon(result, newSymNode(a, info))
|
||||||
onUse(info, a)
|
onUse(info, a)
|
||||||
a = nextOverloadIter(o, c, n)
|
a = nextOverloadIter(o, c, n)
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ const
|
||||||
isNilConversion = isConvertible # maybe 'isIntConv' fits better?
|
isNilConversion = isConvertible # maybe 'isIntConv' fits better?
|
||||||
|
|
||||||
proc markUsed*(c: PContext; info: TLineInfo, s: PSym)
|
proc markUsed*(c: PContext; info: TLineInfo, s: PSym)
|
||||||
|
proc markOwnerModuleAsUsed*(c: PContext; s: PSym)
|
||||||
|
|
||||||
template hasFauxMatch*(c: TCandidate): bool = c.fauxMatch != tyNone
|
template hasFauxMatch*(c: TCandidate): bool = c.fauxMatch != tyNone
|
||||||
|
|
||||||
|
|
@ -380,7 +381,7 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||||
isIntLit(ab) and getInt(ab.n) >= firstOrd(nil, f) and
|
isIntLit(ab) and getInt(ab.n) >= firstOrd(nil, f) and
|
||||||
getInt(ab.n) <= lastOrd(nil, f):
|
getInt(ab.n) <= lastOrd(nil, f):
|
||||||
# passing 'nil' to firstOrd/lastOrd here as type checking rules should
|
# passing 'nil' to firstOrd/lastOrd here as type checking rules should
|
||||||
# not depent on the target integer size configurations!
|
# not depend on the target integer size configurations!
|
||||||
# integer literal in the proper range; we want ``i16 + 4`` to stay an
|
# integer literal in the proper range; we want ``i16 + 4`` to stay an
|
||||||
# ``int16`` operation so we declare the ``4`` pseudo-equal to int16
|
# ``int16`` operation so we declare the ``4`` pseudo-equal to int16
|
||||||
result = isFromIntLit
|
result = isFromIntLit
|
||||||
|
|
@ -396,7 +397,7 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||||
f.kind in {tyUInt8..tyUInt32} and a[0].kind in {tyUInt8..tyInt32}) and
|
f.kind in {tyUInt8..tyUInt32} and a[0].kind in {tyUInt8..tyInt32}) and
|
||||||
a.n[0].intVal >= firstOrd(nil, f) and a.n[1].intVal <= lastOrd(nil, f):
|
a.n[0].intVal >= firstOrd(nil, f) and a.n[1].intVal <= lastOrd(nil, f):
|
||||||
# passing 'nil' to firstOrd/lastOrd here as type checking rules should
|
# passing 'nil' to firstOrd/lastOrd here as type checking rules should
|
||||||
# not depent on the target integer size configurations!
|
# not depend on the target integer size configurations!
|
||||||
result = isConvertible
|
result = isConvertible
|
||||||
else: result = isNone
|
else: result = isNone
|
||||||
|
|
||||||
|
|
@ -408,13 +409,13 @@ proc isConvertibleToRange(f, a: PType): bool =
|
||||||
of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16}
|
of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16}
|
||||||
of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32}
|
of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32}
|
||||||
# This is wrong, but seems like there's a lot of code that relies on it :(
|
# This is wrong, but seems like there's a lot of code that relies on it :(
|
||||||
of tyInt: result = true
|
of tyInt, tyUInt, tyUInt64: result = true
|
||||||
of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64}
|
of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64}
|
||||||
of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8}
|
of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8}
|
||||||
of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16}
|
of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16}
|
||||||
of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32}
|
of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32}
|
||||||
of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
|
#of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
|
||||||
of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64}
|
#of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64}
|
||||||
else: result = false
|
else: result = false
|
||||||
elif f.kind in {tyFloat..tyFloat128}:
|
elif f.kind in {tyFloat..tyFloat128}:
|
||||||
# `isIntLit` is correct and should be used above as well, see PR:
|
# `isIntLit` is correct and should be used above as well, see PR:
|
||||||
|
|
@ -2362,7 +2363,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
localError(c.config, n.sons[a].info, "named parameter has to be an identifier")
|
localError(c.config, n.sons[a].info, "named parameter has to be an identifier")
|
||||||
noMatch()
|
noMatch()
|
||||||
return
|
return
|
||||||
formal = getSymFromList(m.callee.n, n.sons[a].sons[0].ident, 1)
|
formal = getNamedParamFromList(m.callee.n, n.sons[a].sons[0].ident)
|
||||||
if formal == nil:
|
if formal == nil:
|
||||||
# no error message!
|
# no error message!
|
||||||
noMatch()
|
noMatch()
|
||||||
|
|
|
||||||
|
|
@ -1309,7 +1309,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
tyNone, tyForward, tyFromExpr:
|
tyNone, tyForward, tyFromExpr:
|
||||||
result = t
|
result = t
|
||||||
of tyNil:
|
of tyNil:
|
||||||
if kind != skConst and kind != skParam and kind != skResult: result = t
|
if kind != skConst and kind != skParam: result = t
|
||||||
of tyString, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString, tyPointer:
|
of tyString, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString, tyPointer:
|
||||||
result = nil
|
result = nil
|
||||||
of tyOrdinal:
|
of tyOrdinal:
|
||||||
|
|
|
||||||
|
|
@ -1288,7 +1288,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
||||||
if dest < 0: dest = c.getTemp(n.typ)
|
if dest < 0: dest = c.getTemp(n.typ)
|
||||||
c.gABC(n, opcCallSite, dest)
|
c.gABC(n, opcCallSite, dest)
|
||||||
of mNGenSym: genBinaryABC(c, n, dest, opcGenSym)
|
of mNGenSym: genBinaryABC(c, n, dest, opcGenSym)
|
||||||
of mMinI, mMaxI, mAbsF64, mMinF64, mMaxF64, mAbsI, mDotDot:
|
of mMinI, mMaxI, mAbsI, mDotDot:
|
||||||
c.genCall(n, dest)
|
c.genCall(n, dest)
|
||||||
of mExpandToAst:
|
of mExpandToAst:
|
||||||
if n.len != 2:
|
if n.len != 2:
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@
|
||||||
when not defined(profiler) and not defined(memProfiler):
|
when not defined(profiler) and not defined(memProfiler):
|
||||||
{.error: "Profiling support is turned off! Enable profiling by passing `--profiler:on --stackTrace:on` to the compiler (see the Nim Compiler User Guide for more options).".}
|
{.error: "Profiling support is turned off! Enable profiling by passing `--profiler:on --stackTrace:on` to the compiler (see the Nim Compiler User Guide for more options).".}
|
||||||
|
|
||||||
|
when defined(nimHasUsed):
|
||||||
|
{.used.}
|
||||||
|
|
||||||
# We don't want to profile the profiling code ...
|
# We don't want to profile the profiling code ...
|
||||||
{.push profiler: off.}
|
{.push profiler: off.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2880,17 +2880,21 @@ proc max*[T](x: openArray[T]): T =
|
||||||
for i in 1..high(x):
|
for i in 1..high(x):
|
||||||
if result < x[i]: result = x[i]
|
if result < x[i]: result = x[i]
|
||||||
|
|
||||||
proc abs*(x: float): float {.magic: "AbsF64", noSideEffect.} =
|
proc abs*(x: float64): float64 {.noSideEffect, inline.} =
|
||||||
if x < 0.0: -x else: x
|
if x < 0.0: -x else: x
|
||||||
proc min*(x, y: float): float {.magic: "MinF64", noSideEffect.} =
|
proc abs*(x: float32): float32 {.noSideEffect, inline.} =
|
||||||
|
if x < 0.0: -x else: x
|
||||||
|
proc min*(x, y: float32): float32 {.noSideEffect, inline.} =
|
||||||
|
if x <= y or y != y: x else: y
|
||||||
|
proc min*(x, y: float64): float64 {.noSideEffect, inline.} =
|
||||||
|
if x <= y or y != y: x else: y
|
||||||
|
proc max*(x, y: float32): float32 {.noSideEffect, inline.} =
|
||||||
|
if y <= x or y != y: x else: y
|
||||||
|
proc max*(x, y: float64): float64 {.noSideEffect, inline.} =
|
||||||
|
if y <= x or y != y: x else: y
|
||||||
|
proc min*[T: not SomeFloat](x, y: T): T {.inline.} =
|
||||||
if x <= y: x else: y
|
if x <= y: x else: y
|
||||||
proc max*(x, y: float): float {.magic: "MaxF64", noSideEffect.} =
|
proc max*[T: not SomeFloat](x, y: T): T {.inline.} =
|
||||||
if y <= x: x else: y
|
|
||||||
|
|
||||||
proc min*[T](x, y: T): T {.inline.}=
|
|
||||||
if x <= y: x else: y
|
|
||||||
|
|
||||||
proc max*[T](x, y: T): T {.inline.}=
|
|
||||||
if y <= x: x else: y
|
if y <= x: x else: y
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,3 @@ f3(typeof(nil))
|
||||||
|
|
||||||
proc f4[T](_: T) = discard
|
proc f4[T](_: T) = discard
|
||||||
f4(nil)
|
f4(nil)
|
||||||
|
|
||||||
proc f5(): typeof(nil) = nil
|
|
||||||
discard f5()
|
|
||||||
|
|
|
||||||
|
|
@ -85,3 +85,16 @@ testWrongAt()
|
||||||
|
|
||||||
let (a, d) = allocCounters()
|
let (a, d) = allocCounters()
|
||||||
discard cprintf("%ld new: %ld\n", a - unpairedEnvAllocs() - d, allocs)
|
discard cprintf("%ld new: %ld\n", a - unpairedEnvAllocs() - d, allocs)
|
||||||
|
|
||||||
|
#-------------------------------------------------
|
||||||
|
type
|
||||||
|
Table[A, B] = object
|
||||||
|
x: seq[(A, B)]
|
||||||
|
|
||||||
|
|
||||||
|
proc toTable[A,B](p: sink openArray[(A, B)]): Table[A, B] =
|
||||||
|
for zz in mitems(p):
|
||||||
|
result.x.add move(zz)
|
||||||
|
|
||||||
|
|
||||||
|
let table = {"a": new(int)}.toTable()
|
||||||
|
|
|
||||||
|
|
@ -136,3 +136,9 @@ block:
|
||||||
const x11: range[0'f..1'f] = 2'f
|
const x11: range[0'f..1'f] = 2'f
|
||||||
reject:
|
reject:
|
||||||
const x12: range[0'f..1'f] = 2
|
const x12: range[0'f..1'f] = 2
|
||||||
|
|
||||||
|
# ensure unsigned array indexing is remains lenient:
|
||||||
|
var a: array[4'u, string]
|
||||||
|
|
||||||
|
for i in 0..<a.len:
|
||||||
|
a[i] = "foo"
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,6 @@ block: # `$`*[T: tuple|object](x: T)
|
||||||
doAssert $Foo(x:2) == "(x: 2, x2: 0.0)"
|
doAssert $Foo(x:2) == "(x: 2, x2: 0.0)"
|
||||||
doAssert $() == "()"
|
doAssert $() == "()"
|
||||||
|
|
||||||
|
|
||||||
# this is a call indirection to prevent `toInt` to be resolved at compile time.
|
# this is a call indirection to prevent `toInt` to be resolved at compile time.
|
||||||
proc testToInt(arg: float64, a: int, b: BiggestInt) =
|
proc testToInt(arg: float64, a: int, b: BiggestInt) =
|
||||||
doAssert toInt(arg) == a
|
doAssert toInt(arg) == a
|
||||||
|
|
@ -174,3 +173,14 @@ testToInt(13.37, 13, 13) # should round towards 0
|
||||||
testToInt(-13.37, -13, -13) # should round towards 0
|
testToInt(-13.37, -13, -13) # should round towards 0
|
||||||
testToInt(7.8, 8, 8) # should round away from 0
|
testToInt(7.8, 8, 8) # should round away from 0
|
||||||
testToInt(-7.8, -8, -8) # should round away from 0
|
testToInt(-7.8, -8, -8) # should round away from 0
|
||||||
|
|
||||||
|
# test min/max for correct NaN handling
|
||||||
|
|
||||||
|
proc testMinMax(a,b: float32) =
|
||||||
|
doAssert max(float32(a),float32(b)) == 0'f32
|
||||||
|
doAssert min(float32(a),float32(b)) == 0'f32
|
||||||
|
doAssert max(float64(a),float64(b)) == 0'f64
|
||||||
|
doAssert min(float64(a),float64(b)) == 0'f64
|
||||||
|
|
||||||
|
testMinMax(0.0, NaN)
|
||||||
|
testMinMax(NaN, 0.0)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,11 @@ output: '''
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
wth
|
wth
|
||||||
|
3
|
||||||
|
2
|
||||||
|
1
|
||||||
|
0
|
||||||
|
(total: 6)
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
# bug #1915
|
# bug #1915
|
||||||
|
|
@ -145,3 +150,17 @@ macro m(): untyped =
|
||||||
|
|
||||||
let meh = m()
|
let meh = m()
|
||||||
meh("wth")
|
meh("wth")
|
||||||
|
|
||||||
|
|
||||||
|
macro foo(body: untyped): untyped =
|
||||||
|
result = body
|
||||||
|
|
||||||
|
template baz(): untyped =
|
||||||
|
foo:
|
||||||
|
proc bar2(b: int): int =
|
||||||
|
echo b
|
||||||
|
if b > 0: b + bar2(b = b - 1)
|
||||||
|
else: 0
|
||||||
|
echo (total: bar2(3))
|
||||||
|
|
||||||
|
baz()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue