codegen doesn't produce line tracing commands anymore; fixes #1344

This commit is contained in:
Araq 2015-03-21 15:18:32 +01:00
commit 5641be51c1
9 changed files with 277 additions and 216 deletions

View file

@ -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,

View file

@ -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")

View file

@ -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

View file

@ -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)

View file

@ -9,9 +9,11 @@
## This module contains the data structures for the C code generation phase. ## This module contains the data structures for the C code generation phase.
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
@ -51,7 +53,7 @@ type
TCProcSections* = array[TCProcSection, PRope] # represents a generated C proc TCProcSections* = array[TCProcSection, PRope] # represents a generated C proc
BModule* = ref TCGen BModule* = ref TCGen
BProc* = ref TCProc BProc* = ref TCProc
TBlock*{.final.} = object TBlock*{.final.} = object
id*: int # the ID of the label; positive means that it id*: int # the ID of the label; positive means that it
label*: PRope # generated text for the label label*: PRope # generated text for the label
# nil if label is not used # nil if label is not used
@ -60,11 +62,12 @@ type
nestedTryStmts*: int16 # how many try statements is it nested into nestedTryStmts*: int16 # how many try statements is it nested into
nestedExceptStmts*: int16 # how many except statements is it nested into nestedExceptStmts*: int16 # how many except statements is it nested into
frameLen*: int16 frameLen*: int16
TCProc{.final.} = object # represents C proc that is currently generated TCProc{.final.} = object # represents C proc that is currently generated
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?
@ -87,7 +90,7 @@ type
# (yes, C++ is weird like that) # (yes, C++ is weird like that)
gcFrameId*: Natural # for the GC stack marking gcFrameId*: Natural # for the GC stack marking
gcFrameType*: PRope # the struct {} we put the GC markers into gcFrameType*: PRope # the struct {} we put the GC markers into
TTypeSeq* = seq[PType] TTypeSeq* = seq[PType]
TCGen = object of TPassContext # represents a C source file TCGen = object of TPassContext # represents a C source file
module*: PSym module*: PSym
@ -140,7 +143,7 @@ proc bmod*(module: PSym): BModule =
# obtains the BModule for a given module PSym # obtains the BModule for a given module PSym
result = gModules[module.position] result = gModules[module.position]
proc newProc*(prc: PSym, module: BModule): BProc = proc newProc*(prc: PSym, module: BModule): BProc =
new(result) new(result)
result.prc = prc result.prc = prc
result.module = module result.module = module

View file

@ -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:

View file

@ -13,192 +13,192 @@
# Nimrod has been tested on this platform or that the RTL has been ported. # Nimrod has been tested on this platform or that the RTL has been ported.
# Feel free to test for your excentric platform! # Feel free to test for your excentric platform!
import import
strutils strutils
type type
TSystemOS* = enum # Also add OS in initialization section and alias TSystemOS* = enum # Also add OS in initialization section and alias
# conditionals to condsyms (end of module). # conditionals to condsyms (end of module).
osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris, osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris,
osIrix, osNetbsd, osFreebsd, osOpenbsd, osAix, osPalmos, osQnx, osAmiga, osIrix, osNetbsd, osFreebsd, osOpenbsd, osAix, osPalmos, osQnx, osAmiga,
osAtari, osNetware, osMacos, osMacosx, osHaiku, osVxworks, osAtari, osNetware, osMacos, osMacosx, osHaiku, osVxworks,
osJS, osNimrodVM, osStandalone osJS, osNimrodVM, osStandalone
type type
TInfoOSProp* = enum TInfoOSProp* = enum
ospNeedsPIC, # OS needs PIC for libraries ospNeedsPIC, # OS needs PIC for libraries
ospCaseInsensitive, # OS filesystem is case insensitive ospCaseInsensitive, # OS filesystem is case insensitive
ospPosix, # OS is posix-like ospPosix, # OS is posix-like
ospLacksThreadVars # OS lacks proper __threadvar support ospLacksThreadVars # OS lacks proper __threadvar support
TInfoOSProps* = set[TInfoOSProp] TInfoOSProps* = set[TInfoOSProp]
TInfoOS* = tuple[name: string, parDir: string, dllFrmt: string, TInfoOS* = tuple[name: string, parDir: string, dllFrmt: string,
altDirSep: string, objExt: string, newLine: string, altDirSep: string, objExt: string, newLine: string,
pathSep: string, dirSep: string, scriptExt: string, pathSep: string, dirSep: string, scriptExt: string,
curDir: string, exeExt: string, extSep: string, curDir: string, exeExt: string, extSep: string,
props: TInfoOSProps] props: TInfoOSProps]
const const
OS*: array[succ(low(TSystemOS))..high(TSystemOS), TInfoOS] = [ OS*: array[succ(low(TSystemOS))..high(TSystemOS), TInfoOS] = [
(name: "DOS", (name: "DOS",
parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", objExt: ".obj", parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", objExt: ".obj",
newLine: "\x0D\x0A", pathSep: ";", dirSep: "\\", scriptExt: ".bat", newLine: "\x0D\x0A", pathSep: ";", dirSep: "\\", scriptExt: ".bat",
curDir: ".", exeExt: ".exe", extSep: ".", props: {ospCaseInsensitive}), curDir: ".", exeExt: ".exe", extSep: ".", props: {ospCaseInsensitive}),
(name: "Windows", parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", (name: "Windows", parDir: "..", dllFrmt: "$1.dll", altDirSep: "/",
objExt: ".obj", newLine: "\x0D\x0A", pathSep: ";", dirSep: "\\", objExt: ".obj", newLine: "\x0D\x0A", pathSep: ";", dirSep: "\\",
scriptExt: ".bat", curDir: ".", exeExt: ".exe", extSep: ".", scriptExt: ".bat", curDir: ".", exeExt: ".exe", extSep: ".",
props: {ospCaseInsensitive}), props: {ospCaseInsensitive}),
(name: "OS2", parDir: "..", (name: "OS2", parDir: "..",
dllFrmt: "$1.dll", altDirSep: "/", dllFrmt: "$1.dll", altDirSep: "/",
objExt: ".obj", newLine: "\x0D\x0A", objExt: ".obj", newLine: "\x0D\x0A",
pathSep: ";", dirSep: "\\", pathSep: ";", dirSep: "\\",
scriptExt: ".bat", curDir: ".", scriptExt: ".bat", curDir: ".",
exeExt: ".exe", extSep: ".", exeExt: ".exe", extSep: ".",
props: {ospCaseInsensitive}), props: {ospCaseInsensitive}),
(name: "Linux", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", (name: "Linux", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC, ospPosix}), props: {ospNeedsPIC, ospPosix}),
(name: "MorphOS", parDir: "..", (name: "MorphOS", parDir: "..",
dllFrmt: "lib$1.so", altDirSep: "/", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", objExt: ".o", newLine: "\x0A",
pathSep: ":", dirSep: "/", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", scriptExt: ".sh", curDir: ".",
exeExt: "", extSep: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC, ospPosix}), props: {ospNeedsPIC, ospPosix}),
(name: "SkyOS", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", (name: "SkyOS", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC, ospPosix}), props: {ospNeedsPIC, ospPosix}),
(name: "Solaris", parDir: "..", (name: "Solaris", parDir: "..",
dllFrmt: "lib$1.so", altDirSep: "/", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", objExt: ".o", newLine: "\x0A",
pathSep: ":", dirSep: "/", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", scriptExt: ".sh", curDir: ".",
exeExt: "", extSep: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC, ospPosix}), props: {ospNeedsPIC, ospPosix}),
(name: "Irix", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", (name: "Irix", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC, ospPosix}), props: {ospNeedsPIC, ospPosix}),
(name: "NetBSD", parDir: "..", (name: "NetBSD", parDir: "..",
dllFrmt: "lib$1.so", altDirSep: "/", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", objExt: ".o", newLine: "\x0A",
pathSep: ":", dirSep: "/", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", scriptExt: ".sh", curDir: ".",
exeExt: "", extSep: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC, ospPosix}), props: {ospNeedsPIC, ospPosix}),
(name: "FreeBSD", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", (name: "FreeBSD", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC, ospPosix}), props: {ospNeedsPIC, ospPosix}),
(name: "OpenBSD", parDir: "..", (name: "OpenBSD", parDir: "..",
dllFrmt: "lib$1.so", altDirSep: "/", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", objExt: ".o", newLine: "\x0A",
pathSep: ":", dirSep: "/", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", scriptExt: ".sh", curDir: ".",
exeExt: "", extSep: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC, ospPosix}), props: {ospNeedsPIC, ospPosix}),
(name: "AIX", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", (name: "AIX", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC, ospPosix}), props: {ospNeedsPIC, ospPosix}),
(name: "PalmOS", parDir: "..", (name: "PalmOS", parDir: "..",
dllFrmt: "lib$1.so", altDirSep: "/", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", objExt: ".o", newLine: "\x0A",
pathSep: ":", dirSep: "/", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", scriptExt: ".sh", curDir: ".",
exeExt: "", extSep: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC}), props: {ospNeedsPIC}),
(name: "QNX", (name: "QNX",
parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", objExt: ".o", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", objExt: ".o",
newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", curDir: ".", newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", curDir: ".",
exeExt: "", extSep: ".", props: {ospNeedsPIC, ospPosix}), exeExt: "", extSep: ".", props: {ospNeedsPIC, ospPosix}),
(name: "Amiga", (name: "Amiga",
parDir: "..", dllFrmt: "$1.library", altDirSep: "/", objExt: ".o", parDir: "..", dllFrmt: "$1.library", altDirSep: "/", objExt: ".o",
newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", curDir: ".", newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", curDir: ".",
exeExt: "", extSep: ".", props: {ospNeedsPIC}), exeExt: "", extSep: ".", props: {ospNeedsPIC}),
(name: "Atari", (name: "Atari",
parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", objExt: ".o", parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", objExt: ".o",
newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: "", curDir: ".", newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: "", curDir: ".",
exeExt: ".tpp", extSep: ".", props: {ospNeedsPIC}), exeExt: ".tpp", extSep: ".", props: {ospNeedsPIC}),
(name: "Netware", (name: "Netware",
parDir: "..", dllFrmt: "$1.nlm", altDirSep: "/", objExt: "", parDir: "..", dllFrmt: "$1.nlm", altDirSep: "/", objExt: "",
newLine: "\x0D\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", newLine: "\x0D\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh",
curDir: ".", exeExt: ".nlm", extSep: ".", props: {ospCaseInsensitive}), curDir: ".", exeExt: ".nlm", extSep: ".", props: {ospCaseInsensitive}),
(name: "MacOS", parDir: "::", dllFrmt: "$1Lib", altDirSep: ":", (name: "MacOS", parDir: "::", dllFrmt: "$1Lib", altDirSep: ":",
objExt: ".o", newLine: "\x0D", pathSep: ",", dirSep: ":", scriptExt: "", objExt: ".o", newLine: "\x0D", pathSep: ",", dirSep: ":", scriptExt: "",
curDir: ":", exeExt: "", extSep: ".", props: {ospCaseInsensitive}), curDir: ":", exeExt: "", extSep: ".", props: {ospCaseInsensitive}),
(name: "MacOSX", parDir: "..", dllFrmt: "lib$1.dylib", altDirSep: ":", (name: "MacOSX", parDir: "..", dllFrmt: "lib$1.dylib", altDirSep: ":",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}), props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
(name: "Haiku", parDir: "..", dllFrmt: "lib$1.so", altDirSep: ":", (name: "Haiku", parDir: "..", dllFrmt: "lib$1.so", altDirSep: ":",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}), props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
(name: "VxWorks", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", (name: "VxWorks", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ";", dirSep: "\\", objExt: ".o", newLine: "\x0A", pathSep: ";", dirSep: "\\",
scriptExt: ".sh", curDir: ".", exeExt: ".vxe", extSep: ".", scriptExt: ".sh", curDir: ".", exeExt: ".vxe", extSep: ".",
props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}), props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
(name: "JS", parDir: "..", (name: "JS", parDir: "..",
dllFrmt: "lib$1.so", altDirSep: "/", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", objExt: ".o", newLine: "\x0A",
pathSep: ":", dirSep: "/", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", scriptExt: ".sh", curDir: ".",
exeExt: "", extSep: ".", props: {}), exeExt: "", extSep: ".", props: {}),
(name: "NimrodVM", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", (name: "NimrodVM", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", props: {}), scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", props: {}),
(name: "Standalone", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", (name: "Standalone", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {})] props: {})]
type type
TSystemCPU* = enum # Also add CPU for in initialization section and TSystemCPU* = enum # Also add CPU for in initialization section and
# alias conditionals to condsyms (end of module). # alias conditionals to condsyms (end of module).
cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64, cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64,
cpuSparc, cpuVm, cpuIa64, cpuAmd64, cpuMips, cpuArm, cpuSparc, cpuVm, cpuIa64, cpuAmd64, cpuMips, cpuArm,
cpuJS, cpuNimrodVM, cpuAVR cpuJS, cpuNimrodVM, cpuAVR
type type
TEndian* = enum TEndian* = enum
littleEndian, bigEndian littleEndian, bigEndian
TInfoCPU* = tuple[name: string, intSize: int, endian: TEndian, TInfoCPU* = tuple[name: string, intSize: int, endian: TEndian,
floatSize, bit: int] floatSize, bit: int]
const const
EndianToStr*: array[TEndian, string] = ["littleEndian", "bigEndian"] EndianToStr*: array[TEndian, string] = ["littleEndian", "bigEndian"]
CPU*: array[succ(low(TSystemCPU))..high(TSystemCPU), TInfoCPU] = [ CPU*: array[succ(low(TSystemCPU))..high(TSystemCPU), TInfoCPU] = [
(name: "i386", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32), (name: "i386", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
(name: "m68k", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32), (name: "m68k", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
(name: "alpha", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), (name: "alpha", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
(name: "powerpc", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32), (name: "powerpc", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
(name: "powerpc64", intSize: 64, endian: bigEndian, floatSize: 64,bit: 64), (name: "powerpc64", intSize: 64, endian: bigEndian, floatSize: 64,bit: 64),
(name: "sparc", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32), (name: "sparc", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
(name: "vm", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32), (name: "vm", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
(name: "ia64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), (name: "ia64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
(name: "amd64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), (name: "amd64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
(name: "mips", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32), (name: "mips", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
(name: "arm", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32), (name: "arm", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
(name: "js", intSize: 32, endian: bigEndian,floatSize: 64,bit: 32), (name: "js", intSize: 32, endian: bigEndian,floatSize: 64,bit: 32),
(name: "nimrodvm", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32), (name: "nimrodvm", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
(name: "avr", intSize: 16, endian: littleEndian, floatSize: 32, bit: 16)] (name: "avr", intSize: 16, endian: littleEndian, floatSize: 32, bit: 16)]
var var
targetCPU*, hostCPU*: TSystemCPU targetCPU*, hostCPU*: TSystemCPU
targetOS*, hostOS*: TSystemOS targetOS*, hostOS*: TSystemOS
proc nameToOS*(name: string): TSystemOS proc nameToOS*(name: string): TSystemOS
proc nameToCPU*(name: string): TSystemCPU proc nameToCPU*(name: string): TSystemCPU
var var
intSize*: int intSize*: int
floatSize*: int floatSize*: int
ptrSize*: int ptrSize*: int
tnl*: string # target newline tnl*: string # target newline
proc setTarget*(o: TSystemOS, c: TSystemCPU) = proc setTarget*(o: TSystemOS, c: TSystemCPU) =
assert(c != cpuNone) assert(c != cpuNone)
assert(o != osNone) assert(o != osNone)
#echo "new Target: OS: ", o, " CPU: ", c #echo "new Target: OS: ", o, " CPU: ", c
@ -209,15 +209,15 @@ proc setTarget*(o: TSystemOS, c: TSystemCPU) =
ptrSize = CPU[c].bit div 8 ptrSize = CPU[c].bit div 8
tnl = OS[o].newLine tnl = OS[o].newLine
proc nameToOS(name: string): TSystemOS = proc nameToOS(name: string): TSystemOS =
for i in countup(succ(osNone), high(TSystemOS)): for i in countup(succ(osNone), high(TSystemOS)):
if cmpIgnoreStyle(name, OS[i].name) == 0: if cmpIgnoreStyle(name, OS[i].name) == 0:
return i return i
result = osNone result = osNone
proc nameToCPU(name: string): TSystemCPU = proc nameToCPU(name: string): TSystemCPU =
for i in countup(succ(cpuNone), high(TSystemCPU)): for i in countup(succ(cpuNone), high(TSystemCPU)):
if cmpIgnoreStyle(name, CPU[i].name) == 0: if cmpIgnoreStyle(name, CPU[i].name) == 0:
return i return i
result = cpuNone result = cpuNone

View file

@ -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")

View 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