IC: next steps (#16705)

* code cleanups
* refactorings for IC
* more refactorings for IC
* IC: attach the 'nil' type to its module
* IC: refactorings and improvements
* IC: progress
* IC: more serialization fixes
* IC: embarrassing omission
* code cleanups
This commit is contained in:
Andreas Rumpf 2021-01-14 17:30:41 +01:00 • committed by GitHub
commit 1fd4c666dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 289 additions and 277 deletions

View file

@ -22,13 +22,19 @@ proc errorType*(g: ModuleGraph): PType =
result = newType(tyError, nextTypeId(g.idgen), g.owners[^1])
result.flags.incl tfCheckedForDestructor
proc newIntNodeT*(intVal: Int128, n: PNode; g: ModuleGraph): PNode =
proc getIntLitTypeG(g: ModuleGraph; literal: PNode; idgen: IdGenerator): PType =
# we cache some common integer literal types for performance:
let ti = getSysType(g, literal.info, tyInt)
result = copyType(ti, nextTypeId(idgen), ti.owner)
result.n = literal
proc newIntNodeT*(intVal: Int128, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
result = newIntTypeNode(intVal, n.typ)
# See bug #6989. 'pred' et al only produce an int literal type if the
# original type was 'int', not a distinct int etc.
if n.typ.kind == tyInt:
# access cache for the int lit type
result.typ = getIntLitType(g, result)
result.typ = getIntLitTypeG(g, result, idgen)
result.info = n.info
proc newFloatNodeT*(floatVal: BiggestFloat, n: PNode; g: ModuleGraph): PNode =
@ -47,33 +53,33 @@ proc newStrNodeT*(strVal: string, n: PNode; g: ModuleGraph): PNode =
proc getConstExpr*(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
# evaluates the constant expression or returns nil if it is no constant
# expression
proc evalOp*(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode
proc evalOp*(m: TMagic, n, a, b, c: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
proc checkInRange(conf: ConfigRef; n: PNode, res: Int128): bool =
res in firstOrd(conf, n.typ)..lastOrd(conf, n.typ)
proc foldAdd(a, b: Int128, n: PNode; g: ModuleGraph): PNode =
proc foldAdd(a, b: Int128, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
let res = a + b
if checkInRange(g.config, n, res):
result = newIntNodeT(res, n, g)
result = newIntNodeT(res, n, idgen, g)
proc foldSub(a, b: Int128, n: PNode; g: ModuleGraph): PNode =
proc foldSub(a, b: Int128, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
let res = a - b
if checkInRange(g.config, n, res):
result = newIntNodeT(res, n, g)
result = newIntNodeT(res, n, idgen, g)
proc foldUnarySub(a: Int128, n: PNode, g: ModuleGraph): PNode =
proc foldUnarySub(a: Int128, n: PNode; idgen: IdGenerator, g: ModuleGraph): PNode =
if a != firstOrd(g.config, n.typ):
result = newIntNodeT(-a, n, g)
result = newIntNodeT(-a, n, idgen, g)
proc foldAbs(a: Int128, n: PNode; g: ModuleGraph): PNode =
proc foldAbs(a: Int128, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
if a != firstOrd(g.config, n.typ):
result = newIntNodeT(abs(a), n, g)
result = newIntNodeT(abs(a), n, idgen, g)
proc foldMul(a, b: Int128, n: PNode; g: ModuleGraph): PNode =
proc foldMul(a, b: Int128, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
let res = a * b
if checkInRange(g.config, n, res):
return newIntNodeT(res, n, g)
return newIntNodeT(res, n, idgen, g)
proc ordinalValToString*(a: PNode; g: ModuleGraph): string =
# because $ has the param ordinal[T], `a` is not necessarily an enum, but an
@ -115,68 +121,68 @@ proc pickIntRange(a, b: PType): PType =
proc isIntRangeOrLit(t: PType): bool =
result = isIntRange(t) or isIntLit(t)
proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
proc evalOp(m: TMagic, n, a, b, c: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
# b and c may be nil
result = nil
case m
of mOrd: result = newIntNodeT(getOrdValue(a), n, g)
of mChr: result = newIntNodeT(getInt(a), n, g)
of mUnaryMinusI, mUnaryMinusI64: result = foldUnarySub(getInt(a), n, g)
of mOrd: result = newIntNodeT(getOrdValue(a), n, idgen, g)
of mChr: result = newIntNodeT(getInt(a), n, idgen, g)
of mUnaryMinusI, mUnaryMinusI64: result = foldUnarySub(getInt(a), n, idgen, g)
of mUnaryMinusF64: result = newFloatNodeT(-getFloat(a), n, g)
of mNot: result = newIntNodeT(One - getInt(a), n, g)
of mCard: result = newIntNodeT(toInt128(nimsets.cardSet(g.config, a)), n, g)
of mNot: result = newIntNodeT(One - getInt(a), n, idgen, g)
of mCard: result = newIntNodeT(toInt128(nimsets.cardSet(g.config, a)), n, idgen, g)
of mBitnotI:
if n.typ.isUnsigned:
result = newIntNodeT(bitnot(getInt(a)).maskBytes(int(n.typ.size)), n, g)
result = newIntNodeT(bitnot(getInt(a)).maskBytes(int(n.typ.size)), n, idgen, g)
else:
result = newIntNodeT(bitnot(getInt(a)), n, g)
of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, g)
result = newIntNodeT(bitnot(getInt(a)), n, idgen, g)
of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, idgen, g)
of mLengthSeq, mLengthOpenArray, mLengthStr:
if a.kind == nkNilLit:
result = newIntNodeT(Zero, n, g)
result = newIntNodeT(Zero, n, idgen, g)
elif a.kind in {nkStrLit..nkTripleStrLit}:
if a.typ.kind == tyString:
result = newIntNodeT(toInt128(a.strVal.len), n, g)
result = newIntNodeT(toInt128(a.strVal.len), n, idgen, g)
elif a.typ.kind == tyCString:
result = newIntNodeT(toInt128(nimCStrLen(a.strVal)), n, g)
result = newIntNodeT(toInt128(nimCStrLen(a.strVal)), n, idgen, g)
else:
result = newIntNodeT(toInt128(a.len), n, g)
result = newIntNodeT(toInt128(a.len), n, idgen, g)
of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
# XXX: Hides overflow/underflow
of mAbsI: result = foldAbs(getInt(a), n, g)
of mSucc: result = foldAdd(getOrdValue(a), getInt(b), n, g)
of mPred: result = foldSub(getOrdValue(a), getInt(b), n, g)
of mAddI: result = foldAdd(getInt(a), getInt(b), n, g)
of mSubI: result = foldSub(getInt(a), getInt(b), n, g)
of mMulI: result = foldMul(getInt(a), getInt(b), n, g)
of mAbsI: result = foldAbs(getInt(a), n, idgen, g)
of mSucc: result = foldAdd(getOrdValue(a), getInt(b), n, idgen, g)
of mPred: result = foldSub(getOrdValue(a), getInt(b), n, idgen, g)
of mAddI: result = foldAdd(getInt(a), getInt(b), n, idgen, g)
of mSubI: result = foldSub(getInt(a), getInt(b), n, idgen, g)
of mMulI: result = foldMul(getInt(a), getInt(b), n, idgen, g)
of mMinI:
let argA = getInt(a)
let argB = getInt(b)
result = newIntNodeT(if argA < argB: argA else: argB, n, g)
result = newIntNodeT(if argA < argB: argA else: argB, n, idgen, g)
of mMaxI:
let argA = getInt(a)
let argB = getInt(b)
result = newIntNodeT(if argA > argB: argA else: argB, n, g)
result = newIntNodeT(if argA > argB: argA else: argB, n, idgen, g)
of mShlI:
case skipTypes(n.typ, abstractRange).kind
of tyInt8: result = newIntNodeT(toInt128(toInt8(getInt(a)) shl toInt64(getInt(b))), n, g)
of tyInt16: result = newIntNodeT(toInt128(toInt16(getInt(a)) shl toInt64(getInt(b))), n, g)
of tyInt32: result = newIntNodeT(toInt128(toInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
of tyInt64: result = newIntNodeT(toInt128(toInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
of tyInt8: result = newIntNodeT(toInt128(toInt8(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
of tyInt16: result = newIntNodeT(toInt128(toInt16(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
of tyInt32: result = newIntNodeT(toInt128(toInt32(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
of tyInt64: result = newIntNodeT(toInt128(toInt64(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
of tyInt:
if g.config.target.intSize == 4:
result = newIntNodeT(toInt128(toInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
result = newIntNodeT(toInt128(toInt32(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
else:
result = newIntNodeT(toInt128(toInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
of tyUInt8: result = newIntNodeT(toInt128(toUInt8(getInt(a)) shl toInt64(getInt(b))), n, g)
of tyUInt16: result = newIntNodeT(toInt128(toUInt16(getInt(a)) shl toInt64(getInt(b))), n, g)
of tyUInt32: result = newIntNodeT(toInt128(toUInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
of tyUInt64: result = newIntNodeT(toInt128(toUInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
result = newIntNodeT(toInt128(toInt64(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
of tyUInt8: result = newIntNodeT(toInt128(toUInt8(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
of tyUInt16: result = newIntNodeT(toInt128(toUInt16(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
of tyUInt32: result = newIntNodeT(toInt128(toUInt32(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
of tyUInt64: result = newIntNodeT(toInt128(toUInt64(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
of tyUInt:
if g.config.target.intSize == 4:
result = newIntNodeT(toInt128(toUInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
result = newIntNodeT(toInt128(toUInt32(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
else:
result = newIntNodeT(toInt128(toUInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
result = newIntNodeT(toInt128(toUInt64(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
else: internalError(g.config, n.info, "constant folding for shl")
of mShrI:
var a = cast[uint64](getInt(a))
@ -197,75 +203,75 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
# unsigned and 64 bit integers don't need masking
discard
let c = cast[BiggestInt](a shr b)
result = newIntNodeT(toInt128(c), n, g)
result = newIntNodeT(toInt128(c), n, idgen, g)
of mAshrI:
case skipTypes(n.typ, abstractRange).kind
of tyInt8: result = newIntNodeT(toInt128(ashr(toInt8(getInt(a)), toInt8(getInt(b)))), n, g)
of tyInt16: result = newIntNodeT(toInt128(ashr(toInt16(getInt(a)), toInt16(getInt(b)))), n, g)
of tyInt32: result = newIntNodeT(toInt128(ashr(toInt32(getInt(a)), toInt32(getInt(b)))), n, g)
of tyInt8: result = newIntNodeT(toInt128(ashr(toInt8(getInt(a)), toInt8(getInt(b)))), n, idgen, g)
of tyInt16: result = newIntNodeT(toInt128(ashr(toInt16(getInt(a)), toInt16(getInt(b)))), n, idgen, g)
of tyInt32: result = newIntNodeT(toInt128(ashr(toInt32(getInt(a)), toInt32(getInt(b)))), n, idgen, g)
of tyInt64, tyInt:
result = newIntNodeT(toInt128(ashr(toInt64(getInt(a)), toInt64(getInt(b)))), n, g)
result = newIntNodeT(toInt128(ashr(toInt64(getInt(a)), toInt64(getInt(b)))), n, idgen, g)
else: internalError(g.config, n.info, "constant folding for ashr")
of mDivI:
let argA = getInt(a)
let argB = getInt(b)
if argB != Zero and (argA != firstOrd(g.config, n.typ) or argB != NegOne):
result = newIntNodeT(argA div argB, n, g)
result = newIntNodeT(argA div argB, n, idgen, g)
of mModI:
let argA = getInt(a)
let argB = getInt(b)
if argB != Zero and (argA != firstOrd(g.config, n.typ) or argB != NegOne):
result = newIntNodeT(argA mod argB, n, g)
result = newIntNodeT(argA mod argB, n, idgen, g)
of mAddF64: result = newFloatNodeT(getFloat(a) + getFloat(b), n, g)
of mSubF64: result = newFloatNodeT(getFloat(a) - getFloat(b), n, g)
of mMulF64: result = newFloatNodeT(getFloat(a) * getFloat(b), n, g)
of mDivF64:
result = newFloatNodeT(getFloat(a) / getFloat(b), n, g)
of mIsNil: result = newIntNodeT(toInt128(ord(a.kind == nkNilLit)), n, g)
of mIsNil: result = newIntNodeT(toInt128(ord(a.kind == nkNilLit)), n, idgen, g)
of mLtI, mLtB, mLtEnum, mLtCh:
result = newIntNodeT(toInt128(ord(getOrdValue(a) < getOrdValue(b))), n, g)
result = newIntNodeT(toInt128(ord(getOrdValue(a) < getOrdValue(b))), n, idgen, g)
of mLeI, mLeB, mLeEnum, mLeCh:
result = newIntNodeT(toInt128(ord(getOrdValue(a) <= getOrdValue(b))), n, g)
result = newIntNodeT(toInt128(ord(getOrdValue(a) <= getOrdValue(b))), n, idgen, g)
of mEqI, mEqB, mEqEnum, mEqCh:
result = newIntNodeT(toInt128(ord(getOrdValue(a) == getOrdValue(b))), n, g)
of mLtF64: result = newIntNodeT(toInt128(ord(getFloat(a) < getFloat(b))), n, g)
of mLeF64: result = newIntNodeT(toInt128(ord(getFloat(a) <= getFloat(b))), n, g)
of mEqF64: result = newIntNodeT(toInt128(ord(getFloat(a) == getFloat(b))), n, g)
of mLtStr: result = newIntNodeT(toInt128(ord(getStr(a) < getStr(b))), n, g)
of mLeStr: result = newIntNodeT(toInt128(ord(getStr(a) <= getStr(b))), n, g)
of mEqStr: result = newIntNodeT(toInt128(ord(getStr(a) == getStr(b))), n, g)
result = newIntNodeT(toInt128(ord(getOrdValue(a) == getOrdValue(b))), n, idgen, g)
of mLtF64: result = newIntNodeT(toInt128(ord(getFloat(a) < getFloat(b))), n, idgen, g)
of mLeF64: result = newIntNodeT(toInt128(ord(getFloat(a) <= getFloat(b))), n, idgen, g)
of mEqF64: result = newIntNodeT(toInt128(ord(getFloat(a) == getFloat(b))), n, idgen, g)
of mLtStr: result = newIntNodeT(toInt128(ord(getStr(a) < getStr(b))), n, idgen, g)
of mLeStr: result = newIntNodeT(toInt128(ord(getStr(a) <= getStr(b))), n, idgen, g)
of mEqStr: result = newIntNodeT(toInt128(ord(getStr(a) == getStr(b))), n, idgen, g)
of mLtU:
result = newIntNodeT(toInt128(ord(`<%`(toInt64(getOrdValue(a)), toInt64(getOrdValue(b))))), n, g)
result = newIntNodeT(toInt128(ord(`<%`(toInt64(getOrdValue(a)), toInt64(getOrdValue(b))))), n, idgen, g)
of mLeU:
result = newIntNodeT(toInt128(ord(`<=%`(toInt64(getOrdValue(a)), toInt64(getOrdValue(b))))), n, g)
of mBitandI, mAnd: result = newIntNodeT(bitand(a.getInt, b.getInt), n, g)
of mBitorI, mOr: result = newIntNodeT(bitor(getInt(a), getInt(b)), n, g)
of mBitxorI, mXor: result = newIntNodeT(bitxor(getInt(a), getInt(b)), n, g)
result = newIntNodeT(toInt128(ord(`<=%`(toInt64(getOrdValue(a)), toInt64(getOrdValue(b))))), n, idgen, g)
of mBitandI, mAnd: result = newIntNodeT(bitand(a.getInt, b.getInt), n, idgen, g)
of mBitorI, mOr: result = newIntNodeT(bitor(getInt(a), getInt(b)), n, idgen, g)
of mBitxorI, mXor: result = newIntNodeT(bitxor(getInt(a), getInt(b)), n, idgen, g)
of mAddU:
let val = maskBytes(getInt(a) + getInt(b), int(n.typ.size))
result = newIntNodeT(val, n, g)
result = newIntNodeT(val, n, idgen, g)
of mSubU:
let val = maskBytes(getInt(a) - getInt(b), int(n.typ.size))
result = newIntNodeT(val, n, g)
result = newIntNodeT(val, n, idgen, g)
# echo "subU: ", val, " n: ", n, " result: ", val
of mMulU:
let val = maskBytes(getInt(a) * getInt(b), int(n.typ.size))
result = newIntNodeT(val, n, g)
result = newIntNodeT(val, n, idgen, g)
of mModU:
let argA = maskBytes(getInt(a), int(a.typ.size))
let argB = maskBytes(getInt(b), int(a.typ.size))
if argB != Zero:
result = newIntNodeT(argA mod argB, n, g)
result = newIntNodeT(argA mod argB, n, idgen, g)
of mDivU:
let argA = maskBytes(getInt(a), int(a.typ.size))
let argB = maskBytes(getInt(b), int(a.typ.size))
if argB != Zero:
result = newIntNodeT(argA div argB, n, g)
of mLeSet: result = newIntNodeT(toInt128(ord(containsSets(g.config, a, b))), n, g)
of mEqSet: result = newIntNodeT(toInt128(ord(equalSets(g.config, a, b))), n, g)
result = newIntNodeT(argA div argB, n, idgen, g)
of mLeSet: result = newIntNodeT(toInt128(ord(containsSets(g.config, a, b))), n, idgen, g)
of mEqSet: result = newIntNodeT(toInt128(ord(equalSets(g.config, a, b))), n, idgen, g)
of mLtSet:
result = newIntNodeT(toInt128(ord(
containsSets(g.config, a, b) and not equalSets(g.config, a, b))), n, g)
containsSets(g.config, a, b) and not equalSets(g.config, a, b))), n, idgen, g)
of mMulSet:
result = nimsets.intersectSets(g.config, a, b)
result.info = n.info
@ -276,7 +282,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
result = nimsets.diffSets(g.config, a, b)
result.info = n.info
of mConStrStr: result = newStrNodeT(getStrOrChar(a) & getStrOrChar(b), n, g)
of mInSet: result = newIntNodeT(toInt128(ord(inSet(a, b))), n, g)
of mInSet: result = newIntNodeT(toInt128(ord(inSet(a, b))), n, idgen, g)
of mRepr:
# BUGFIX: we cannot eval mRepr here for reasons that I forgot.
discard
@ -299,13 +305,13 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
result = copyTree(a)
result.typ = n.typ
of mCompileOption:
result = newIntNodeT(toInt128(ord(commands.testCompileOption(g.config, a.getStr, n.info))), n, g)
result = newIntNodeT(toInt128(ord(commands.testCompileOption(g.config, a.getStr, n.info))), n, idgen, g)
of mCompileOptionArg:
result = newIntNodeT(toInt128(ord(
testCompileOptionArg(g.config, getStr(a), getStr(b), n.info))), n, g)
testCompileOptionArg(g.config, getStr(a), getStr(b), n.info))), n, idgen, g)
of mEqProc:
result = newIntNodeT(toInt128(ord(
exprStructuralEquivalent(a, b, strictSymEquality=true))), n, g)
exprStructuralEquivalent(a, b, strictSymEquality=true))), n, idgen, g)
else: discard
proc getConstIfExpr(c: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
@ -351,7 +357,7 @@ proc magicCall(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
if n.len > 3:
c = getConstExpr(m, n[3], idgen, g)
if c == nil: return
result = evalOp(s.magic, n, a, b, c, g)
result = evalOp(s.magic, n, a, b, c, idgen, g)
proc getAppType(n: PNode; g: ModuleGraph): PNode =
if g.config.globalOptions.contains(optGenDynLib):
@ -368,7 +374,7 @@ proc rangeCheck(n: PNode, value: Int128; g: ModuleGraph) =
localError(g.config, n.info, "cannot convert " & $value &
" to " & typeToString(n.typ))
proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode =
proc foldConv(n, a: PNode; idgen: IdGenerator; g: ModuleGraph; check = false): PNode =
let dstTyp = skipTypes(n.typ, abstractRange - {tyTypeDesc})
let srcTyp = skipTypes(a.typ, abstractRange - {tyTypeDesc})
@ -382,9 +388,9 @@ proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode =
of tyBool:
case srcTyp.kind
of tyFloat..tyFloat64:
result = newIntNodeT(toInt128(getFloat(a) != 0.0), n, g)
result = newIntNodeT(toInt128(getFloat(a) != 0.0), n, idgen, g)
of tyChar, tyUInt..tyUInt64, tyInt..tyInt64:
result = newIntNodeT(toInt128(a.getOrdValue != 0), n, g)
result = newIntNodeT(toInt128(a.getOrdValue != 0), n, idgen, g)
of tyBool, tyEnum: # xxx shouldn't we disallow `tyEnum`?
result = a
result.typ = n.typ
@ -392,11 +398,11 @@ proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode =
of tyInt..tyInt64, tyUInt..tyUInt64:
case srcTyp.kind
of tyFloat..tyFloat64:
result = newIntNodeT(toInt128(getFloat(a)), n, g)
result = newIntNodeT(toInt128(getFloat(a)), n, idgen, g)
of tyChar, tyUInt..tyUInt64, tyInt..tyInt64:
var val = a.getOrdValue
if check: rangeCheck(n, val, g)
result = newIntNodeT(val, n, g)
result = newIntNodeT(val, n, idgen, g)
if dstTyp.kind in {tyUInt..tyUInt64}:
result.transitionIntKind(nkUIntLit)
else:
@ -493,13 +499,13 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
var s = n.sym
case s.kind
of skEnumField:
result = newIntNodeT(toInt128(s.position), n, g)
result = newIntNodeT(toInt128(s.position), n, idgen, g)
of skConst:
case s.magic
of mIsMainModule: result = newIntNodeT(toInt128(ord(sfMainModule in m.flags)), n, g)
of mIsMainModule: result = newIntNodeT(toInt128(ord(sfMainModule in m.flags)), n, idgen, g)
of mCompileDate: result = newStrNodeT(getDateStr(), n, g)
of mCompileTime: result = newStrNodeT(getClockStr(), n, g)
of mCpuEndian: result = newIntNodeT(toInt128(ord(CPU[g.config.target.targetCPU].endian)), n, g)
of mCpuEndian: result = newIntNodeT(toInt128(ord(CPU[g.config.target.targetCPU].endian)), n, idgen, g)
of mHostOS: result = newStrNodeT(toLowerAscii(platform.OS[g.config.target.targetOS].name), n, g)
of mHostCPU: result = newStrNodeT(platform.CPU[g.config.target.targetCPU].name.toLowerAscii, n, g)
of mBuildOS: result = newStrNodeT(toLowerAscii(platform.OS[g.config.target.hostOS].name), n, g)
@ -508,7 +514,7 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
of mIntDefine:
if isDefined(g.config, s.name.s):
try:
result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseInt), n, g)
result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseInt), n, idgen, g)
except ValueError:
localError(g.config, s.info,
"{.intdefine.} const was set to an invalid integer: '" &
@ -523,7 +529,7 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
of mBoolDefine:
if isDefined(g.config, s.name.s):
try:
result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseBool.int), n, g)
result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseBool.int), n, idgen, g)
except ValueError:
localError(g.config, s.info,
"{.booldefine.} const was set to an invalid bool: '" &
@ -569,30 +575,30 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
if skipTypes(n[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
result = newFloatNodeT(firstFloat(n[1].typ), n, g)
else:
result = newIntNodeT(firstOrd(g.config, n[1].typ), n, g)
result = newIntNodeT(firstOrd(g.config, n[1].typ), n, idgen, g)
of mHigh:
if skipTypes(n[1].typ, abstractVar+{tyUserTypeClassInst}).kind notin
{tySequence, tyString, tyCString, tyOpenArray, tyVarargs}:
if skipTypes(n[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
result = newFloatNodeT(lastFloat(n[1].typ), n, g)
else:
result = newIntNodeT(lastOrd(g.config, skipTypes(n[1].typ, abstractVar)), n, g)
result = newIntNodeT(lastOrd(g.config, skipTypes(n[1].typ, abstractVar)), n, idgen, g)
else:
var a = getArrayConstr(m, n[1], idgen, g)
if a.kind == nkBracket:
# we can optimize it away:
result = newIntNodeT(toInt128(a.len-1), n, g)
result = newIntNodeT(toInt128(a.len-1), n, idgen, g)
of mLengthOpenArray:
var a = getArrayConstr(m, n[1], idgen, g)
if a.kind == nkBracket:
# we can optimize it away! This fixes the bug ``len(134)``.
result = newIntNodeT(toInt128(a.len), n, g)
result = newIntNodeT(toInt128(a.len), n, idgen, g)
else:
result = magicCall(m, n, idgen, g)
of mLengthArray:
# It doesn't matter if the argument is const or not for mLengthArray.
# This fixes bug #544.
result = newIntNodeT(lengthOrd(g.config, n[1].typ), n, g)
result = newIntNodeT(lengthOrd(g.config, n[1].typ), n, idgen, g)
of mSizeOf:
result = foldSizeOf(g.config, n, nil)
of mAlignOf:
@ -675,7 +681,7 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
var a = getConstExpr(m, n[1], idgen, g)
if a == nil: return
result = foldConv(n, a, g, check=true)
result = foldConv(n, a, idgen, g, check=true)
of nkDerefExpr, nkHiddenDeref:
let a = getConstExpr(m, n[0], idgen, g)
if a != nil and a.kind == nkNilLit: