codegen doesn't produce line tracing commands anymore; fixes #1344
This commit is contained in:
parent
508e8bd686
commit
5641be51c1
9 changed files with 277 additions and 216 deletions
|
|
@ -532,12 +532,14 @@ type
|
||||||
mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf,
|
mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf,
|
||||||
mEcho, mShallowCopy, mSlurp, mStaticExec,
|
mEcho, mShallowCopy, mSlurp, mStaticExec,
|
||||||
mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
|
mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
|
||||||
mUnaryLt, mSucc,
|
mUnaryLt, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray,
|
||||||
mPred, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray,
|
|
||||||
mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref,
|
mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref,
|
||||||
mGCunref, mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
|
mGCunref,
|
||||||
mDivI64, mModI64,
|
|
||||||
|
mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
|
||||||
|
mDivI64, mModI64, mSucc, mPred,
|
||||||
mAddF64, mSubF64, mMulF64, mDivF64,
|
mAddF64, mSubF64, mMulF64, mDivF64,
|
||||||
|
|
||||||
mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI,
|
mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI,
|
||||||
mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinI64, mMaxI64,
|
mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinI64, mMaxI64,
|
||||||
mMinF64, mMaxF64, mAddU, mSubU, mMulU,
|
mMinF64, mMaxF64, mAddU, mSubU, mMulU,
|
||||||
|
|
|
||||||
|
|
@ -485,37 +485,48 @@ proc unaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdCharLoc(a)]))
|
putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdCharLoc(a)]))
|
||||||
|
|
||||||
|
proc binaryArithOverflowRaw(p: BProc, t: PType, a, b: TLoc;
|
||||||
|
frmt: string): PRope =
|
||||||
|
var size = getSize(t)
|
||||||
|
let storage = if size < platform.intSize: toRope("NI")
|
||||||
|
else: getTypeDesc(p.module, t)
|
||||||
|
result = getTempName()
|
||||||
|
linefmt(p, cpsLocals, "$1 $2;$n", storage, result)
|
||||||
|
lineCg(p, cpsStmts, frmt, result, rdLoc(a), rdLoc(b))
|
||||||
|
if size < platform.intSize or t.kind in {tyRange, tyEnum}:
|
||||||
|
linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
|
||||||
|
result, intLiteral(firstOrd(t)), intLiteral(lastOrd(t)))
|
||||||
|
|
||||||
proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
const
|
const
|
||||||
prc: array[mAddI..mModI64, string] = ["addInt", "subInt", "mulInt",
|
prc: array[mAddI..mPred, string] = [
|
||||||
"divInt", "modInt", "addInt64", "subInt64", "mulInt64", "divInt64",
|
"$# = #addInt($#, $#);$n", "$# = #subInt($#, $#);$n",
|
||||||
"modInt64"]
|
"$# = #mulInt($#, $#);$n", "$# = #divInt($#, $#);$n",
|
||||||
opr: array[mAddI..mModI64, string] = ["+", "-", "*", "/", "%", "+", "-",
|
"$# = #modInt($#, $#);$n",
|
||||||
"*", "/", "%"]
|
"$# = #addInt64($#, $#);$n", "$# = #subInt64($#, $#);$n",
|
||||||
|
"$# = #mulInt64($#, $#);$n", "$# = #divInt64($#, $#);$n",
|
||||||
|
"$# = #modInt64($#, $#);$n",
|
||||||
|
"$# = #addInt($#, $#);$n", "$# = #subInt($#, $#);$n"]
|
||||||
|
opr: array[mAddI..mPred, string] = [
|
||||||
|
"($#)($# + $#)", "($#)($# - $#)", "($#)($# * $#)",
|
||||||
|
"($#)($# / $#)", "($#)($# % $#)",
|
||||||
|
"($#)($# + $#)", "($#)($# - $#)", "($#)($# * $#)",
|
||||||
|
"($#)($# / $#)", "($#)($# % $#)",
|
||||||
|
"($#)($# + $#)", "($#)($# - $#)"]
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
assert(e.sons[1].typ != nil)
|
assert(e.sons[1].typ != nil)
|
||||||
assert(e.sons[2].typ != nil)
|
assert(e.sons[2].typ != nil)
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
var t = skipTypes(e.typ, abstractRange)
|
# skipping 'range' is correct here as we'll generate a proper range check
|
||||||
|
# later via 'chckRange'
|
||||||
|
let t = e.typ.skipTypes(abstractRange)
|
||||||
if optOverflowCheck notin p.options:
|
if optOverflowCheck notin p.options:
|
||||||
putIntoDest(p, d, e.typ, ropef("(NI$4)($2 $1 $3)", [toRope(opr[m]),
|
let res = ropef(opr[m], [getTypeDesc(p.module, t), rdLoc(a), rdLoc(b)])
|
||||||
rdLoc(a), rdLoc(b), toRope(getSize(t) * 8)]))
|
putIntoDest(p, d, e.typ, res)
|
||||||
else:
|
else:
|
||||||
var storage: PRope
|
let res = binaryArithOverflowRaw(p, t, a, b, prc[m])
|
||||||
var size = getSize(t)
|
putIntoDest(p, d, e.typ, ropef("($#)($#)", [getTypeDesc(p.module, t), res]))
|
||||||
if size < platform.intSize:
|
|
||||||
storage = toRope("NI")
|
|
||||||
else:
|
|
||||||
storage = getTypeDesc(p.module, t)
|
|
||||||
var tmp = getTempName()
|
|
||||||
linefmt(p, cpsLocals, "$1 $2;$n", storage, tmp)
|
|
||||||
lineCg(p, cpsStmts, "$1 = #$2($3, $4);$n",
|
|
||||||
tmp, toRope(prc[m]), rdLoc(a), rdLoc(b))
|
|
||||||
if size < platform.intSize or t.kind in {tyRange, tyEnum, tySet}:
|
|
||||||
linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
|
|
||||||
tmp, intLiteral(firstOrd(t)), intLiteral(lastOrd(t)))
|
|
||||||
putIntoDest(p, d, e.typ, ropef("(NI$1)($2)", [toRope(getSize(t)*8), tmp]))
|
|
||||||
|
|
||||||
proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
const
|
const
|
||||||
|
|
@ -1648,35 +1659,35 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
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)
|
||||||
of mEqProc: genEqProc(p, e, d)
|
of mEqProc: genEqProc(p, e, d)
|
||||||
of mAddI..mModI64: binaryArithOverflow(p, e, d, op)
|
of mAddI..mPred: binaryArithOverflow(p, e, d, op)
|
||||||
of mRepr: genRepr(p, e, d)
|
of mRepr: genRepr(p, e, d)
|
||||||
of mGetTypeInfo: genGetTypeInfo(p, e, d)
|
of mGetTypeInfo: genGetTypeInfo(p, e, d)
|
||||||
of mSwap: genSwap(p, e, d)
|
of mSwap: genSwap(p, e, d)
|
||||||
of mUnaryLt:
|
of mUnaryLt:
|
||||||
if optOverflowCheck notin p.options: unaryExpr(p, e, d, "($1 - 1)")
|
if optOverflowCheck notin p.options: unaryExpr(p, e, d, "($1 - 1)")
|
||||||
else: unaryExpr(p, e, d, "#subInt($1, 1)")
|
else: unaryExpr(p, e, d, "#subInt($1, 1)")
|
||||||
of mPred:
|
of mInc, mDec:
|
||||||
# XXX: range checking?
|
const opr: array [mInc..mDec, string] = ["$1 += $2;$n", "$1 -= $2;$n"]
|
||||||
if optOverflowCheck notin p.options: binaryExpr(p, e, d, "($1 - $2)")
|
const fun64: array [mInc..mDec, string] = ["$# = #addInt64($#, $#);$n",
|
||||||
else: binaryExpr(p, e, d, "#subInt($1, $2)")
|
"$# = #subInt64($#, $#);$n"]
|
||||||
of mSucc:
|
const fun: array [mInc..mDec, string] = ["$# = #addInt($#, $#);$n",
|
||||||
# XXX: range checking?
|
"$# = #subInt($#, $#);$n"]
|
||||||
if optOverflowCheck notin p.options: binaryExpr(p, e, d, "($1 + $2)")
|
|
||||||
else: binaryExpr(p, e, d, "#addInt($1, $2)")
|
|
||||||
of mInc:
|
|
||||||
if optOverflowCheck notin p.options:
|
if optOverflowCheck notin p.options:
|
||||||
binaryStmt(p, e, d, "$1 += $2;$n")
|
binaryStmt(p, e, d, opr[op])
|
||||||
elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64:
|
|
||||||
binaryStmt(p, e, d, "$1 = #addInt64($1, $2);$n")
|
|
||||||
else:
|
else:
|
||||||
binaryStmt(p, e, d, "$1 = #addInt($1, $2);$n")
|
var a, b: TLoc
|
||||||
of ast.mDec:
|
assert(e.sons[1].typ != nil)
|
||||||
if optOverflowCheck notin p.options:
|
assert(e.sons[2].typ != nil)
|
||||||
binaryStmt(p, e, d, "$1 -= $2;$n")
|
initLocExpr(p, e.sons[1], a)
|
||||||
elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64:
|
initLocExpr(p, e.sons[2], b)
|
||||||
binaryStmt(p, e, d, "$1 = #subInt64($1, $2);$n")
|
|
||||||
else:
|
let underlying = skipTypes(e.sons[1].typ, {tyGenericInst, tyVar, tyRange})
|
||||||
binaryStmt(p, e, d, "$1 = #subInt($1, $2);$n")
|
let ranged = skipTypes(e.sons[1].typ, {tyGenericInst, tyVar})
|
||||||
|
let res = binaryArithOverflowRaw(p, ranged, a, b,
|
||||||
|
if underlying.kind == tyInt64: fun64[op] else: fun[op])
|
||||||
|
putIntoDest(p, a, ranged, ropef("($#)($#)", [
|
||||||
|
getTypeDesc(p.module, ranged), res]))
|
||||||
|
|
||||||
of mConStrStr: genStrConcat(p, e, d)
|
of mConStrStr: genStrConcat(p, e, d)
|
||||||
of mAppendStrCh:
|
of mAppendStrCh:
|
||||||
binaryStmt(p, e, d, "$1 = #addChar($1, $2);$n")
|
binaryStmt(p, e, d, "$1 = #addChar($1, $2);$n")
|
||||||
|
|
|
||||||
|
|
@ -978,12 +978,13 @@ proc genAsmStmt(p: BProc, t: PNode) =
|
||||||
lineF(p, cpsStmts, CC[cCompiler].asmStmtFrmt, [s])
|
lineF(p, cpsStmts, CC[cCompiler].asmStmtFrmt, [s])
|
||||||
|
|
||||||
proc genEmit(p: BProc, t: PNode) =
|
proc genEmit(p: BProc, t: PNode) =
|
||||||
genLineDir(p, t)
|
|
||||||
var s = genAsmOrEmitStmt(p, t.sons[1])
|
var s = genAsmOrEmitStmt(p, t.sons[1])
|
||||||
if p.prc == nil:
|
if p.prc == nil:
|
||||||
# top level emit pragma?
|
# top level emit pragma?
|
||||||
|
genCLineDir(p.module.s[cfsProcHeaders], t.info)
|
||||||
app(p.module.s[cfsProcHeaders], s)
|
app(p.module.s[cfsProcHeaders], s)
|
||||||
else:
|
else:
|
||||||
|
genLineDir(p, t)
|
||||||
line(p, cpsStmts, s)
|
line(p, cpsStmts, s)
|
||||||
|
|
||||||
var
|
var
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import
|
||||||
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp,
|
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp,
|
||||||
options, intsets,
|
options, intsets,
|
||||||
nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os,
|
nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os,
|
||||||
times, ropes, math, passes, rodread, wordrecg, treetab, cgmeth, condsyms,
|
ropes, math, passes, rodread, wordrecg, treetab, cgmeth, condsyms,
|
||||||
rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases, lowerings,
|
rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases, lowerings,
|
||||||
semparallel
|
semparallel
|
||||||
|
|
||||||
|
|
@ -183,6 +183,13 @@ proc genCLineDir(r: var PRope, filename: string, line: int) =
|
||||||
proc genCLineDir(r: var PRope, info: TLineInfo) =
|
proc genCLineDir(r: var PRope, info: TLineInfo) =
|
||||||
genCLineDir(r, info.toFullPath, info.safeLineNm)
|
genCLineDir(r, info.toFullPath, info.safeLineNm)
|
||||||
|
|
||||||
|
proc freshLineInfo(p: BProc; info: TLineInfo): bool =
|
||||||
|
if p.lastLineInfo.line != info.line or
|
||||||
|
p.lastLineInfo.fileIndex != info.fileIndex:
|
||||||
|
p.lastLineInfo.line = info.line
|
||||||
|
p.lastLineInfo.fileIndex = info.fileIndex
|
||||||
|
result = true
|
||||||
|
|
||||||
proc genLineDir(p: BProc, t: PNode) =
|
proc genLineDir(p: BProc, t: PNode) =
|
||||||
var line = t.info.safeLineNm
|
var line = t.info.safeLineNm
|
||||||
if optEmbedOrigSrc in gGlobalOptions:
|
if optEmbedOrigSrc in gGlobalOptions:
|
||||||
|
|
@ -190,13 +197,15 @@ proc genLineDir(p: BProc, t: PNode) =
|
||||||
genCLineDir(p.s(cpsStmts), t.info.toFullPath, line)
|
genCLineDir(p.s(cpsStmts), t.info.toFullPath, line)
|
||||||
if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and
|
if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and
|
||||||
(p.prc == nil or sfPure notin p.prc.flags):
|
(p.prc == nil or sfPure notin p.prc.flags):
|
||||||
linefmt(p, cpsStmts, "#endb($1, $2);$n",
|
if freshLineInfo(p, t.info):
|
||||||
line.toRope, makeCString(toFilename(t.info)))
|
linefmt(p, cpsStmts, "#endb($1, $2);$n",
|
||||||
|
line.toRope, makeCString(toFilename(t.info)))
|
||||||
elif ({optLineTrace, optStackTrace} * p.options ==
|
elif ({optLineTrace, optStackTrace} * p.options ==
|
||||||
{optLineTrace, optStackTrace}) and
|
{optLineTrace, optStackTrace}) and
|
||||||
(p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex >= 0:
|
(p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex >= 0:
|
||||||
linefmt(p, cpsStmts, "nimln($1, $2);$n",
|
if freshLineInfo(p, t.info):
|
||||||
line.toRope, t.info.quotedFilename)
|
linefmt(p, cpsStmts, "nimln($1, $2);$n",
|
||||||
|
line.toRope, t.info.quotedFilename)
|
||||||
|
|
||||||
proc postStmtActions(p: BProc) {.inline.} =
|
proc postStmtActions(p: BProc) {.inline.} =
|
||||||
app(p.s(cpsStmts), p.module.injectStmt)
|
app(p.s(cpsStmts), p.module.injectStmt)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
import
|
import
|
||||||
ast, astalgo, ropes, passes, options, intsets, lists, platform
|
ast, astalgo, ropes, passes, options, intsets, lists, platform
|
||||||
|
|
||||||
|
from msgs import TLineInfo
|
||||||
|
|
||||||
type
|
type
|
||||||
TLabel* = PRope # for the C generator a label is just a rope
|
TLabel* = PRope # for the C generator a label is just a rope
|
||||||
TCFileSection* = enum # the sections a generated C file consists of
|
TCFileSection* = enum # the sections a generated C file consists of
|
||||||
|
|
@ -65,6 +67,7 @@ type
|
||||||
prc*: PSym # the Nim proc that this C proc belongs to
|
prc*: PSym # the Nim proc that this C proc belongs to
|
||||||
beforeRetNeeded*: bool # true iff 'BeforeRet' label for proc is needed
|
beforeRetNeeded*: bool # true iff 'BeforeRet' label for proc is needed
|
||||||
threadVarAccessed*: bool # true if the proc already accessed some threadvar
|
threadVarAccessed*: bool # true if the proc already accessed some threadvar
|
||||||
|
lastLineInfo*: TLineInfo # to avoid generating excessive 'nimln' statements
|
||||||
nestedTryStmts*: seq[PNode] # in how many nested try statements we are
|
nestedTryStmts*: seq[PNode] # in how many nested try statements we are
|
||||||
# (the vars must be volatile then)
|
# (the vars must be volatile then)
|
||||||
inExceptBlock*: int # are we currently inside an except block?
|
inExceptBlock*: int # are we currently inside an except block?
|
||||||
|
|
|
||||||
|
|
@ -262,6 +262,8 @@ const # magic checked op; magic unchecked op; checked op; unchecked op
|
||||||
["mulInt64", "", "mulInt64($1, $2)", "($1 * $2)"], # MulI64
|
["mulInt64", "", "mulInt64($1, $2)", "($1 * $2)"], # MulI64
|
||||||
["divInt64", "", "divInt64($1, $2)", "Math.floor($1 / $2)"], # DivI64
|
["divInt64", "", "divInt64($1, $2)", "Math.floor($1 / $2)"], # DivI64
|
||||||
["modInt64", "", "modInt64($1, $2)", "Math.floor($1 % $2)"], # ModI64
|
["modInt64", "", "modInt64($1, $2)", "Math.floor($1 % $2)"], # ModI64
|
||||||
|
["addInt", "", "addInt($1, $2)", "($1 + $2)"], # Succ
|
||||||
|
["subInt", "", "subInt($1, $2)", "($1 - $2)"], # Pred
|
||||||
["", "", "($1 + $2)", "($1 + $2)"], # AddF64
|
["", "", "($1 + $2)", "($1 + $2)"], # AddF64
|
||||||
["", "", "($1 - $2)", "($1 - $2)"], # SubF64
|
["", "", "($1 - $2)", "($1 - $2)"], # SubF64
|
||||||
["", "", "($1 * $2)", "($1 * $2)"], # MulF64
|
["", "", "($1 * $2)", "($1 * $2)"], # MulF64
|
||||||
|
|
@ -362,6 +364,8 @@ const # magic checked op; magic unchecked op; checked op; unchecked op
|
||||||
["mulInt64", "", "mulInt64($1, $2)", "($1 * $2)"], # MulI64
|
["mulInt64", "", "mulInt64($1, $2)", "($1 * $2)"], # MulI64
|
||||||
["divInt64", "", "divInt64($1, $2)", "Math.floor($1 / $2)"], # DivI64
|
["divInt64", "", "divInt64($1, $2)", "Math.floor($1 / $2)"], # DivI64
|
||||||
["modInt64", "", "modInt64($1, $2)", "Math.floor($1 % $2)"], # ModI64
|
["modInt64", "", "modInt64($1, $2)", "Math.floor($1 % $2)"], # ModI64
|
||||||
|
["addInt", "", "addInt($1, $2)", "($1 + $2)"], # Succ
|
||||||
|
["subInt", "", "subInt($1, $2)", "($1 - $2)"], # Pred
|
||||||
["", "", "($1 + $2)", "($1 + $2)"], # AddF64
|
["", "", "($1 + $2)", "($1 + $2)"], # AddF64
|
||||||
["", "", "($1 - $2)", "($1 - $2)"], # SubF64
|
["", "", "($1 - $2)", "($1 - $2)"], # SubF64
|
||||||
["", "", "($1 * $2)", "($1 * $2)"], # MulF64
|
["", "", "($1 * $2)", "($1 * $2)"], # MulF64
|
||||||
|
|
@ -1323,14 +1327,6 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
# XXX: range checking?
|
# XXX: range checking?
|
||||||
if not (optOverflowCheck in p.options): unaryExpr(p, n, r, "", "$1 - 1")
|
if not (optOverflowCheck in p.options): unaryExpr(p, n, r, "", "$1 - 1")
|
||||||
else: unaryExpr(p, n, r, "subInt", "subInt($1, 1)")
|
else: unaryExpr(p, n, r, "subInt", "subInt($1, 1)")
|
||||||
of mPred:
|
|
||||||
# XXX: range checking?
|
|
||||||
if not (optOverflowCheck in p.options): binaryExpr(p, n, r, "", "$1 - $2")
|
|
||||||
else: binaryExpr(p, n, r, "subInt", "subInt($1, $2)")
|
|
||||||
of mSucc:
|
|
||||||
# XXX: range checking?
|
|
||||||
if not (optOverflowCheck in p.options): binaryExpr(p, n, r, "", "$1 - $2")
|
|
||||||
else: binaryExpr(p, n, r, "addInt", "addInt($1, $2)")
|
|
||||||
of mAppendStrCh: binaryExpr(p, n, r, "addChar", "addChar($1, $2)")
|
of mAppendStrCh: binaryExpr(p, n, r, "addChar", "addChar($1, $2)")
|
||||||
of mAppendStrStr:
|
of mAppendStrStr:
|
||||||
if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString:
|
if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString:
|
||||||
|
|
|
||||||
|
|
@ -1557,9 +1557,9 @@ when not defined(nimrodVM) and hostOS != "standalone":
|
||||||
## process. This is only available when threads are enabled.
|
## process. This is only available when threads are enabled.
|
||||||
|
|
||||||
when sizeof(int) <= 2:
|
when sizeof(int) <= 2:
|
||||||
type IntLikeForCount = int|int8|int16|char|bool|uint8
|
type IntLikeForCount = int|int8|int16|char|bool|uint8|enum
|
||||||
else:
|
else:
|
||||||
type IntLikeForCount = int|int8|int16|int32|char|bool|uint8|uint16
|
type IntLikeForCount = int|int8|int16|int32|char|bool|uint8|uint16|enum
|
||||||
|
|
||||||
iterator countdown*[T](a, b: T, step = 1): T {.inline.} =
|
iterator countdown*[T](a, b: T, step = 1): T {.inline.} =
|
||||||
## Counts from ordinal value `a` down to `b` with the given
|
## Counts from ordinal value `a` down to `b` with the given
|
||||||
|
|
@ -2900,20 +2900,16 @@ proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[Idx]): seq[T] =
|
||||||
## because the array might have negative bounds.
|
## because the array might have negative bounds.
|
||||||
var L = ord(x.b) - ord(x.a) + 1
|
var L = ord(x.b) - ord(x.a) + 1
|
||||||
newSeq(result, L)
|
newSeq(result, L)
|
||||||
var j = x.a
|
|
||||||
for i in 0.. <L:
|
for i in 0.. <L:
|
||||||
result[i] = a[j]
|
result[i] = a[Idx(ord(x.a) + i)]
|
||||||
inc(j)
|
|
||||||
|
|
||||||
proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[Idx], b: openArray[T]) =
|
proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[Idx], b: openArray[T]) =
|
||||||
## slice assignment for arrays. Negative indexes are **not** supported
|
## slice assignment for arrays. Negative indexes are **not** supported
|
||||||
## because the array might have negative bounds.
|
## because the array might have negative bounds.
|
||||||
var L = ord(x.b) - ord(x.a) + 1
|
var L = ord(x.b) - ord(x.a) + 1
|
||||||
if L == b.len:
|
if L == b.len:
|
||||||
var j = x.a
|
|
||||||
for i in 0 .. <L:
|
for i in 0 .. <L:
|
||||||
a[j] = b[i]
|
a[Idx(ord(x.a) + i)] = b[i]
|
||||||
inc(j)
|
|
||||||
else:
|
else:
|
||||||
sysFatal(RangeError, "different lengths for slice assignment")
|
sysFatal(RangeError, "different lengths for slice assignment")
|
||||||
|
|
||||||
|
|
|
||||||
43
tests/misc/trangechecks.nim
Normal file
43
tests/misc/trangechecks.nim
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
discard """
|
||||||
|
output: '''10
|
||||||
|
10
|
||||||
|
1
|
||||||
|
1
|
||||||
|
true'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #1344
|
||||||
|
|
||||||
|
var expected: int
|
||||||
|
var x: range[1..10] = 10
|
||||||
|
|
||||||
|
try:
|
||||||
|
x += 1
|
||||||
|
echo x
|
||||||
|
except OverflowError, RangeError:
|
||||||
|
expected += 1
|
||||||
|
echo x
|
||||||
|
|
||||||
|
try:
|
||||||
|
inc x
|
||||||
|
echo x
|
||||||
|
except OverflowError, RangeError:
|
||||||
|
expected += 1
|
||||||
|
echo x
|
||||||
|
|
||||||
|
x = 1
|
||||||
|
try:
|
||||||
|
x -= 1
|
||||||
|
echo x
|
||||||
|
except OverflowError, RangeError:
|
||||||
|
expected += 1
|
||||||
|
echo x
|
||||||
|
|
||||||
|
try:
|
||||||
|
dec x
|
||||||
|
echo x
|
||||||
|
except OverflowError, RangeError:
|
||||||
|
expected += 1
|
||||||
|
echo x
|
||||||
|
|
||||||
|
echo expected == 4
|
||||||
Loading…
Add table
Add a link
Reference in a new issue