fewer ropes (#11037)

This commit is contained in:
Arne Döring 2019-04-19 09:05:31 +02:00 • committed by Andreas Rumpf
commit abb05ab645
8 changed files with 380 additions and 213 deletions

View file

@ -218,10 +218,12 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
genParamLoop(pl) genParamLoop(pl)
template genCallPattern {.dirty.} = template genCallPattern {.dirty.} =
lineF(p, cpsStmts, callPattern & ";$n", [rdLoc(op), pl, pl.addComma, rawProc]) if tfIterator in typ.flags:
lineF(p, cpsStmts, PatIter & ";$n", [rdLoc(op), pl, pl.addComma, rawProc])
else:
lineF(p, cpsStmts, PatProc & ";$n", [rdLoc(op), pl, pl.addComma, rawProc])
let rawProc = getRawProcType(p, typ) let rawProc = getRawProcType(p, typ)
let callPattern = if tfIterator in typ.flags: PatIter else: PatProc
if typ.sons[0] != nil: if typ.sons[0] != nil:
if isInvalidReturnType(p.config, typ.sons[0]): if isInvalidReturnType(p.config, typ.sons[0]):
if sonsLen(ri) > 1: add(pl, ~", ") if sonsLen(ri) > 1: add(pl, ~", ")
@ -246,7 +248,11 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
assert(d.t != nil) # generate an assignment to d: assert(d.t != nil) # generate an assignment to d:
var list: TLoc var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown) initLoc(list, locCall, d.lode, OnUnknown)
list.r = callPattern % [rdLoc(op), pl, pl.addComma, rawProc] if tfIterator in typ.flags:
list.r = PatIter % [rdLoc(op), pl, pl.addComma, rawProc]
else:
list.r = PatProc % [rdLoc(op), pl, pl.addComma, rawProc]
genAssignment(p, d, list, {}) # no need for deep copying genAssignment(p, d, list, {}) # no need for deep copying
else: else:
genCallPattern() genCallPattern()

View file

@ -99,17 +99,17 @@ proc bitSetToWord(s: TBitSet, size: int): BiggestInt =
if j < len(s): result = result or (ze64(s[j]) shl (j * 8)) if j < len(s): result = result or (ze64(s[j]) shl (j * 8))
proc genRawSetData(cs: TBitSet, size: int): Rope = proc genRawSetData(cs: TBitSet, size: int): Rope =
var frmt: FormatStr
if size > 8: if size > 8:
result = "{$n" % [] result = "{$n" % []
for i in countup(0, size - 1): for i in countup(0, size - 1):
if i < size - 1: if i < size - 1:
# not last iteration? # not last iteration?
if (i + 1) mod 8 == 0: frmt = "0x$1,$n" if (i + 1) mod 8 == 0:
else: frmt = "0x$1, " addf(result, "0x$1,$n", [rope(toHex(ze64(cs[i]), 2))])
else:
addf(result, "0x$1, ", [rope(toHex(ze64(cs[i]), 2))])
else: else:
frmt = "0x$1}$n" addf(result, "0x$1}$n", [rope(toHex(ze64(cs[i]), 2))])
addf(result, frmt, [rope(toHex(ze64(cs[i]), 2))])
else: else:
result = intLiteral(bitSetToWord(cs, size)) result = intLiteral(bitSetToWord(cs, size))
# result := rope('0x' + ToHex(bitSetToWord(cs, size), size * 2)) # result := rope('0x' + ToHex(bitSetToWord(cs, size), size * 2))
@ -510,10 +510,7 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
"mulInt64", "divInt64", "modInt64", "mulInt64", "divInt64", "modInt64",
"addInt64", "subInt64" "addInt64", "subInt64"
] ]
opr: array[mAddI..mPred, string] = [ 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)
@ -523,7 +520,7 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
# later via 'chckRange' # later via 'chckRange'
let t = e.typ.skipTypes(abstractRange) let t = e.typ.skipTypes(abstractRange)
if optOverflowCheck notin p.options: if optOverflowCheck notin p.options:
let res = opr[m] % [getTypeDesc(p.module, e.typ), rdLoc(a), rdLoc(b)] let res = "($1)($2 $3 $4)" % [getTypeDesc(p.module, e.typ), rdLoc(a), rope(opr[m]), rdLoc(b)]
putIntoDest(p, d, e, res) putIntoDest(p, d, e, res)
else: else:
let res = binaryArithOverflowRaw(p, t, a, b, let res = binaryArithOverflowRaw(p, t, a, b,
@ -531,11 +528,6 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
putIntoDest(p, d, e, "($#)($#)" % [getTypeDesc(p.module, e.typ), res]) putIntoDest(p, d, e, "($#)($#)" % [getTypeDesc(p.module, e.typ), res])
proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
const
opr: array[mUnaryMinusI..mAbsI, string] = [
mUnaryMinusI: "((NI$2)-($1))",
mUnaryMinusI64: "-($1)",
mAbsI: "($1 > 0? ($1) : -($1))"]
var var
a: TLoc a: TLoc
t: PType t: PType
@ -545,54 +537,17 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
if optOverflowCheck in p.options: if optOverflowCheck in p.options:
linefmt(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n", linefmt(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n",
[rdLoc(a), intLiteral(firstOrd(p.config, t))]) [rdLoc(a), intLiteral(firstOrd(p.config, t))])
putIntoDest(p, d, e, opr[m] % [rdLoc(a), rope(getSize(p.config, t) * 8)]) case m
of mUnaryMinusI:
putIntoDest(p, d, e, "((NI$2)-($1))" % [rdLoc(a), rope(getSize(p.config, t) * 8)])
of mUnaryMinusI64:
putIntoDest(p, d, e, "-($1)" % [rdLoc(a)])
of mAbsI:
putIntoDest(p, d, e, "($1 > 0? ($1) : -($1))" % [rdLoc(a)])
else:
assert(false, $m)
proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
const
binArithTab: array[mAddF64..mXor, string] = [
"(($4)($1) + ($4)($2))", # AddF64
"(($4)($1) - ($4)($2))", # SubF64
"(($4)($1) * ($4)($2))", # MulF64
"(($4)($1) / ($4)($2))", # DivF64
"($4)((NU$5)($1) >> (NU$3)($2))", # ShrI
"($4)((NU$3)($1) << (NU$3)($2))", # ShlI
"($4)((NI$3)($1) >> (NU$3)($2))", # AshrI
"($4)($1 & $2)", # BitandI
"($4)($1 | $2)", # BitorI
"($4)($1 ^ $2)", # BitxorI
"(($1 <= $2) ? $1 : $2)", # MinI
"(($1 >= $2) ? $1 : $2)", # MaxI
"(($1 <= $2) ? $1 : $2)", # MinF64
"(($1 >= $2) ? $1 : $2)", # MaxF64
"($4)((NU$3)($1) + (NU$3)($2))", # AddU
"($4)((NU$3)($1) - (NU$3)($2))", # SubU
"($4)((NU$3)($1) * (NU$3)($2))", # MulU
"($4)((NU$3)($1) / (NU$3)($2))", # DivU
"($4)((NU$3)($1) % (NU$3)($2))", # ModU
"($1 == $2)", # EqI
"($1 <= $2)", # LeI
"($1 < $2)", # LtI
"($1 == $2)", # EqF64
"($1 <= $2)", # LeF64
"($1 < $2)", # LtF64
"((NU$3)($1) <= (NU$3)($2))", # LeU
"((NU$3)($1) < (NU$3)($2))", # LtU
"((NU64)($1) <= (NU64)($2))", # LeU64
"((NU64)($1) < (NU64)($2))", # LtU64
"($1 == $2)", # EqEnum
"($1 <= $2)", # LeEnum
"($1 < $2)", # LtEnum
"((NU8)($1) == (NU8)($2))", # EqCh
"((NU8)($1) <= (NU8)($2))", # LeCh
"((NU8)($1) < (NU8)($2))", # LtCh
"($1 == $2)", # EqB
"($1 <= $2)", # LeB
"($1 < $2)", # LtB
"($1 == $2)", # EqRef
"($1 == $2)", # EqPtr
"($1 <= $2)", # LePtr
"($1 < $2)", # LtPtr
"($1 != $2)"] # Xor
var var
a, b: TLoc a, b: TLoc
s, k: BiggestInt s, k: BiggestInt
@ -603,9 +558,59 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
# BUGFIX: cannot use result-type here, as it may be a boolean # BUGFIX: cannot use result-type here, as it may be a boolean
s = max(getSize(p.config, a.t), getSize(p.config, b.t)) * 8 s = max(getSize(p.config, a.t), getSize(p.config, b.t)) * 8
k = getSize(p.config, a.t) * 8 k = getSize(p.config, a.t) * 8
putIntoDest(p, d, e,
binArithTab[op] % [rdLoc(a), rdLoc(b), rope(s), template applyFormat(frmt: untyped) =
getSimpleTypeDesc(p.module, e.typ), rope(k)]) putIntoDest(p, d, e, frmt % [
rdLoc(a), rdLoc(b), rope(s),
getSimpleTypeDesc(p.module, e.typ), rope(k)]
)
case op
of mAddF64: applyFormat("(($4)($1) + ($4)($2))")
of mSubF64: applyFormat("(($4)($1) - ($4)($2))")
of mMulF64: applyFormat("(($4)($1) * ($4)($2))")
of mDivF64: applyFormat("(($4)($1) / ($4)($2))")
of mShrI: applyFormat("($4)((NU$5)($1) >> (NU$3)($2))")
of mShlI: applyFormat("($4)((NU$3)($1) << (NU$3)($2))")
of mAshrI: applyFormat("($4)((NI$3)($1) >> (NU$3)($2))")
of mBitandI: applyFormat("($4)($1 & $2)")
of mBitorI: applyFormat("($4)($1 | $2)")
of mBitxorI: applyFormat("($4)($1 ^ $2)")
of mMinI: 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 mSubU: applyFormat("($4)((NU$3)($1) - (NU$3)($2))")
of mMulU: applyFormat("($4)((NU$3)($1) * (NU$3)($2))")
of mDivU: applyFormat("($4)((NU$3)($1) / (NU$3)($2))")
of mModU: applyFormat("($4)((NU$3)($1) % (NU$3)($2))")
of mEqI: applyFormat("($1 == $2)")
of mLeI: applyFormat("($1 <= $2)")
of mLtI: applyFormat("($1 < $2)")
of mEqF64: applyFormat("($1 == $2)")
of mLeF64: applyFormat("($1 <= $2)")
of mLtF64: applyFormat("($1 < $2)")
of mLeU: applyFormat("((NU$3)($1) <= (NU$3)($2))")
of mLtU: applyFormat("((NU$3)($1) < (NU$3)($2))")
of mLeU64: applyFormat("((NU64)($1) <= (NU64)($2))")
of mLtU64: applyFormat("((NU64)($1) < (NU64)($2))")
of mEqEnum: applyFormat("($1 == $2)")
of mLeEnum: applyFormat("($1 <= $2)")
of mLtEnum: applyFormat("($1 < $2)")
of mEqCh: applyFormat("((NU8)($1) == (NU8)($2))")
of mLeCh: applyFormat("((NU8)($1) <= (NU8)($2))")
of mLtCh: applyFormat("((NU8)($1) < (NU8)($2))")
of mEqB: applyFormat("($1 == $2)")
of mLeB: applyFormat("($1 <= $2)")
of mLtB: applyFormat("($1 < $2)")
of mEqRef: applyFormat("($1 == $2)")
of mEqUntracedRef: applyFormat("($1 == $2)")
of mLePtr: applyFormat("($1 <= $2)")
of mLtPtr: applyFormat("($1 < $2)")
of mXor: applyFormat("($1 != $2)")
else:
assert(false, $op)
proc genEqProc(p: BProc, e: PNode, d: var TLoc) = proc genEqProc(p: BProc, e: PNode, d: var TLoc) =
var a, b: TLoc var a, b: TLoc
@ -628,7 +633,8 @@ proc genIsNil(p: BProc, e: PNode, d: var TLoc) =
proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
const const
unArithTab: array[mNot..mToBiggestInt, string] = ["!($1)", # Not unArithTab: array[mNot..mToBiggestInt, string] = [
"!($1)", # Not
"$1", # UnaryPlusI "$1", # UnaryPlusI
"($3)((NU$2) ~($1))", # BitnotI "($3)((NU$2) ~($1))", # BitnotI
"$1", # UnaryPlusF64 "$1", # UnaryPlusF64
@ -654,10 +660,58 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
assert(e.sons[1].typ != nil) assert(e.sons[1].typ != nil)
initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[1], a)
t = skipTypes(e.typ, abstractRange) t = skipTypes(e.typ, abstractRange)
putIntoDest(p, d, e,
unArithTab[op] % [rdLoc(a), rope(getSize(p.config, t) * 8),
template applyFormat(frmt: untyped) =
putIntoDest(p, d, e, frmt % [rdLoc(a), rope(getSize(p.config, t) * 8),
getSimpleTypeDesc(p.module, e.typ)]) getSimpleTypeDesc(p.module, e.typ)])
case op
of mNot:
applyFormat("!($1)")
of mUnaryPlusI:
applyFormat("$1")
of mBitnotI:
applyFormat("($3)((NU$2) ~($1))")
of mUnaryPlusF64:
applyFormat("$1")
of mUnaryMinusF64:
applyFormat("-($1)")
of mAbsF64:
applyFormat("($1 < 0? -($1) : ($1))")
# BUGFIX: fabs() makes problems for Tiny C
of mZe8ToI:
applyFormat("(($3)(NU)(NU8)($1))")
of mZe8ToI64:
applyFormat("(($3)(NU64)(NU8)($1))")
of mZe16ToI:
applyFormat("(($3)(NU)(NU16)($1))")
of mZe16ToI64:
applyFormat("(($3)(NU64)(NU16)($1))")
of mZe32ToI64:
applyFormat("(($3)(NU64)(NU32)($1))")
of mZeIToI64:
applyFormat("(($3)(NU64)(NU)($1))")
of mToU8:
applyFormat("(($3)(NU8)(NU)($1))")
of mToU16:
applyFormat("(($3)(NU16)(NU)($1))")
of mToU32:
applyFormat("(($3)(NU32)(NU64)($1))")
of mToFloat:
applyFormat("((double) ($1))")
of mToBiggestFloat:
applyFormat("((double) ($1))")
of mToInt:
applyFormat("float64ToInt32($1)")
of mToBiggestInt:
applyFormat("float64ToInt64($1)")
else:
assert false, $op
proc isCppRef(p: BProc; typ: PType): bool {.inline.} = proc isCppRef(p: BProc; typ: PType): bool {.inline.} =
result = p.module.compileToCpp and result = p.module.compileToCpp and
skipTypes(typ, abstractInstOwned).kind == tyVar and skipTypes(typ, abstractInstOwned).kind == tyVar and
@ -1675,7 +1729,7 @@ proc fewCmps(conf: ConfigRef; s: PNode): bool =
else: else:
result = sonsLen(s) <= 8 # 8 seems to be a good value result = sonsLen(s) <= 8 # 8 seems to be a good value
proc binaryExprIn(p: BProc, e: PNode, a, b, d: var TLoc, frmt: string) = template binaryExprIn(p: BProc, e: PNode, a, b, d: var TLoc, frmt: string) =
putIntoDest(p, d, e, frmt % [rdLoc(a), rdSetElemLoc(p.config, b, a.t)]) putIntoDest(p, d, e, frmt % [rdLoc(a), rdSetElemLoc(p.config, b, a.t)])
proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) = proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) =
@ -1686,7 +1740,7 @@ proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) =
of 8: binaryExprIn(p, e, a, b, d, "(($1 &((NU64)1<<((NU)($2)&63U)))!=0)") of 8: binaryExprIn(p, e, a, b, d, "(($1 &((NU64)1<<((NU)($2)&63U)))!=0)")
else: binaryExprIn(p, e, a, b, d, "(($1[(NU)($2)>>3] &(1U<<((NU)($2)&7U)))!=0)") else: binaryExprIn(p, e, a, b, d, "(($1[(NU)($2)>>3] &(1U<<((NU)($2)&7U)))!=0)")
proc binaryStmtInExcl(p: BProc, e: PNode, d: var TLoc, frmt: string) = template binaryStmtInExcl(p: BProc, e: PNode, d: var TLoc, frmt: string) =
var a, b: TLoc var a, b: TLoc
assert(d.k == locNone) assert(d.k == locNone)
initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[1], a)
@ -1753,13 +1807,19 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of 1, 2, 4, 8: of 1, 2, 4, 8:
case op case op
of mIncl: of mIncl:
var ts = "NU" & $(size * 8) case size
binaryStmtInExcl(p, e, d, of 1: binaryStmtInExcl(p, e, d, "$1 |= ((NU8)1)<<(($2) & 7);$n")
"$1 |= ((" & ts & ")1)<<(($2)%(sizeof(" & ts & ")*8));$n") of 2: binaryStmtInExcl(p, e, d, "$1 |= ((NU16)1)<<(($2) & 15);$n")
of 4: binaryStmtInExcl(p, e, d, "$1 |= ((NU32)1)<<(($2) & 31);$n")
of 8: binaryStmtInExcl(p, e, d, "$1 |= ((NU64)1)<<(($2) & 63);$n")
else: assert(false, $size)
of mExcl: of mExcl:
var ts = "NU" & $(size * 8) case size
binaryStmtInExcl(p, e, d, "$1 &= ~(((" & ts & ")1) << (($2) % (sizeof(" & of 1: binaryStmtInExcl(p, e, d, "$1 &= ~(((NU8)1) << (($2) & 7));$n")
ts & ")*8)));$n") of 2: binaryStmtInExcl(p, e, d, "$1 &= ~(((NU16)1) << (($2) & 15));$n")
of 4: binaryStmtInExcl(p, e, d, "$1 &= ~(((NU32)1) << (($2) & 31));$n")
of 8: binaryStmtInExcl(p, e, d, "$1 &= ~(((NU64)1) << (($2) & 63));$n")
else: assert(false, $size)
of mCard: of mCard:
if size <= 4: unaryExprChar(p, e, d, "#countBits32($1)") if size <= 4: unaryExprChar(p, e, d, "#countBits32($1)")
else: unaryExprChar(p, e, d, "#countBits64($1)") else: unaryExprChar(p, e, d, "#countBits64($1)")
@ -2228,14 +2288,14 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, it.sons[0], a) initLocExpr(p, it.sons[0], a)
initLocExpr(p, it.sons[1], b) initLocExpr(p, it.sons[1], b)
lineF(p, cpsStmts, "for ($1 = $3; $1 <= $4; $1++) $n" & lineF(p, cpsStmts, "for ($1 = $3; $1 <= $4; $1++) $n" &
"$2 |=((" & ts & ")(1)<<(($1)%(sizeof(" & ts & ")*8)));$n", [ "$2 |=(($5)(1)<<(($1)%(sizeof($5)*8)));$n", [
rdLoc(idx), rdLoc(d), rdSetElemLoc(p.config, a, e.typ), rdLoc(idx), rdLoc(d), rdSetElemLoc(p.config, a, e.typ),
rdSetElemLoc(p.config, b, e.typ)]) rdSetElemLoc(p.config, b, e.typ), rope(ts)])
else: else:
initLocExpr(p, it, a) initLocExpr(p, it, a)
lineF(p, cpsStmts, lineF(p, cpsStmts,
"$1 |=((" & ts & ")(1)<<(($2)%(sizeof(" & ts & ")*8)));$n", "$1 |=(($3)(1)<<(($2)%(sizeof($3)*8)));$n",
[rdLoc(d), rdSetElemLoc(p.config, a, e.typ)]) [rdLoc(d), rdSetElemLoc(p.config, a, e.typ), rope(ts)])
proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) = proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) =
var rec: TLoc var rec: TLoc

View file

@ -1135,9 +1135,9 @@ proc genAsmStmt(p: BProc, t: PNode) =
# work: # work:
if p.prc == nil: if p.prc == nil:
# top level asm statement? # top level asm statement?
addf(p.module.s[cfsProcHeaders], CC[p.config.cCompiler].asmStmtFrmt, [s]) add(p.module.s[cfsProcHeaders], runtimeFormat(CC[p.config.cCompiler].asmStmtFrmt, [s]))
else: else:
lineF(p, cpsStmts, CC[p.config.cCompiler].asmStmtFrmt, [s]) add(p.s(cpsStmts), indentLine(p, runtimeFormat(CC[p.config.cCompiler].asmStmtFrmt, [s])))
proc determineSection(n: PNode): TCFileSection = proc determineSection(n: PNode): TCFileSection =
result = cfsProcHeaders result = cfsProcHeaders

View file

@ -338,12 +338,17 @@ proc getTypePre(m: BModule, typ: PType; sig: SigHash): Rope =
if result == nil: result = cacheGetType(m.typeCache, sig) if result == nil: result = cacheGetType(m.typeCache, sig)
proc structOrUnion(t: PType): Rope = proc structOrUnion(t: PType): Rope =
let cachedUnion {.global.} = rope("union")
let cachedStruct {.global.} = rope("struct")
let t = t.skipTypes({tyAlias, tySink}) let t = t.skipTypes({tyAlias, tySink})
(if tfUnion in t.flags: rope("union") else: rope("struct")) if tfUnion in t.flags: cachedUnion
else: cachedStruct
proc getForwardStructFormat(m: BModule): string = proc addForwardStructFormat(m: BModule, structOrUnion: Rope, typename: Rope) =
if m.compileToCpp: result = "$1 $2;$n" if m.compileToCpp:
else: result = "typedef $1 $2 $2;$n" m.s[cfsForwardTypes].addf "$1 $2;$n", [structOrUnion, typename]
else:
m.s[cfsForwardTypes].addf "typedef $1 $2 $2;$n", [structOrUnion, typename]
proc seqStar(m: BModule): string = proc seqStar(m: BModule): string =
if m.config.selectedGC == gcDestructors: result = "" if m.config.selectedGC == gcDestructors: result = ""
@ -360,8 +365,7 @@ proc getTypeForward(m: BModule, typ: PType; sig: SigHash): Rope =
result = getTypeName(m, typ, sig) result = getTypeName(m, typ, sig)
m.forwTypeCache[sig] = result m.forwTypeCache[sig] = result
if not isImportedType(concrete): if not isImportedType(concrete):
addf(m.s[cfsForwardTypes], getForwardStructFormat(m), addForwardStructFormat(m, structOrUnion(typ), result)
[structOrUnion(typ), result])
else: else:
pushType(m, concrete) pushType(m, concrete)
doAssert m.forwTypeCache[sig] == result doAssert m.forwTypeCache[sig] == result
@ -733,8 +737,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
if result == nil: if result == nil:
result = getTypeName(m, origTyp, sig) result = getTypeName(m, origTyp, sig)
if not isImportedType(t): if not isImportedType(t):
addf(m.s[cfsForwardTypes], getForwardStructFormat(m), addForwardStructFormat(m, structOrUnion(t), result)
[structOrUnion(t), result])
m.forwTypeCache[sig] = result m.forwTypeCache[sig] = result
assert(cacheGetType(m.typeCache, sig) == nil) assert(cacheGetType(m.typeCache, sig) == nil)
m.typeCache[sig] = result & seqStar(m) m.typeCache[sig] = result & seqStar(m)
@ -845,8 +848,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
result = getTypeName(m, origTyp, sig) result = getTypeName(m, origTyp, sig)
m.forwTypeCache[sig] = result m.forwTypeCache[sig] = result
if not isImportedType(t): if not isImportedType(t):
addf(m.s[cfsForwardTypes], getForwardStructFormat(m), addForwardStructFormat(m, structOrUnion(t), result)
[structOrUnion(t), result])
assert m.forwTypeCache[sig] == result assert m.forwTypeCache[sig] == result
m.typeCache[sig] = result # always call for sideeffects: m.typeCache[sig] = result # always call for sideeffects:
if not incompleteType(t): if not incompleteType(t):
@ -905,7 +907,8 @@ proc finishTypeDescriptions(m: BModule) =
discard getTypeDesc(m, m.typeStack[i]) discard getTypeDesc(m, m.typeStack[i])
inc(i) inc(i)
template cgDeclFrmt*(s: PSym): string = s.constraint.strVal template cgDeclFrmt*(s: PSym): string =
s.constraint.strVal
proc isReloadable(m: BModule, prc: PSym): bool = proc isReloadable(m: BModule, prc: PSym): bool =
return m.hcrOn and sfNonReloadable notin prc.flags return m.hcrOn and sfNonReloadable notin prc.flags
@ -943,7 +946,7 @@ proc genProcHeader(m: BModule, prc: PSym, asPtr: bool = false): Rope =
params]) params])
else: else:
let asPtrStr = if asPtr: (rope("(*") & name & ")") else: name let asPtrStr = if asPtr: (rope("(*") & name & ")") else: name
result = prc.cgDeclFrmt % [rettype, asPtrStr, params] result = runtimeFormat(prc.cgDeclFrmt, [rettype, asPtrStr, params])
# ------------------ type info generation ------------------------------------- # ------------------ type info generation -------------------------------------

View file

@ -206,15 +206,15 @@ proc indentLine(p: BProc, r: Rope): Rope =
prepend(result, "\t".rope) prepend(result, "\t".rope)
template appcg(m: BModule, c: var Rope, frmt: FormatStr, template appcg(m: BModule, c: var Rope, frmt: FormatStr,
args: varargs[untyped]) = args: untyped) =
add(c, ropecg(m, frmt, args)) add(c, ropecg(m, frmt, args))
template appcg(m: BModule, sec: TCFileSection, frmt: FormatStr, template appcg(m: BModule, sec: TCFileSection, frmt: FormatStr,
args: varargs[untyped]) = args: untyped) =
add(m.s[sec], ropecg(m, frmt, args)) add(m.s[sec], ropecg(m, frmt, args))
template appcg(p: BProc, sec: TCProcSection, frmt: FormatStr, template appcg(p: BProc, sec: TCProcSection, frmt: FormatStr,
args: varargs[untyped]) = args: untyped) =
add(p.s(sec), ropecg(p.module, frmt, args)) add(p.s(sec), ropecg(p.module, frmt, args))
template line(p: BProc, sec: TCProcSection, r: Rope) = template line(p: BProc, sec: TCProcSection, r: Rope) =
@ -224,7 +224,7 @@ template line(p: BProc, sec: TCProcSection, r: string) =
add(p.s(sec), indentLine(p, r.rope)) add(p.s(sec), indentLine(p, r.rope))
template lineF(p: BProc, sec: TCProcSection, frmt: FormatStr, template lineF(p: BProc, sec: TCProcSection, frmt: FormatStr,
args: openarray[Rope]) = args: untyped) =
add(p.s(sec), indentLine(p, frmt % args)) add(p.s(sec), indentLine(p, frmt % args))
template lineCg(p: BProc, sec: TCProcSection, frmt: FormatStr, template lineCg(p: BProc, sec: TCProcSection, frmt: FormatStr,
@ -484,7 +484,7 @@ proc localVarDecl(p: BProc; n: PNode): Rope =
add(result, " ") add(result, " ")
add(result, s.loc.r) add(result, s.loc.r)
else: else:
result = s.cgDeclFrmt % [result, s.loc.r] result = runtimeFormat(s.cgDeclFrmt, [result, s.loc.r])
proc assignLocalVar(p: BProc, n: PNode) = proc assignLocalVar(p: BProc, n: PNode) =
#assert(s.loc.k == locNone) # not yet assigned #assert(s.loc.k == locNone) # not yet assigned
@ -535,7 +535,7 @@ proc assignGlobalVar(p: BProc, n: PNode) =
if sfVolatile in s.flags: add(decl, " volatile") if sfVolatile in s.flags: add(decl, " volatile")
addf(decl, " $1;$n", [s.loc.r]) addf(decl, " $1;$n", [s.loc.r])
else: else:
decl = (s.cgDeclFrmt & ";$n") % [td, s.loc.r] decl = runtimeFormat(s.cgDeclFrmt & ";$n", [td, s.loc.r])
add(p.module.s[cfsVars], decl) add(p.module.s[cfsVars], decl)
if p.withinLoop > 0: if p.withinLoop > 0:
# fixes tests/run/tzeroarray: # fixes tests/run/tzeroarray:

View file

@ -172,7 +172,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
outExt, RelativeDir"htmldocs", false) outExt, RelativeDir"htmldocs", false)
result.thisDir = result.destFile.splitFile.dir result.thisDir = result.destFile.splitFile.dir
proc dispA(conf: ConfigRef; dest: var Rope, xml, tex: string, args: openArray[Rope]) = template dispA(conf: ConfigRef; dest: var Rope, xml, tex: string, args: openArray[Rope]) =
if conf.cmd != cmdRst2tex: addf(dest, xml, args) if conf.cmd != cmdRst2tex: addf(dest, xml, args)
else: addf(dest, tex, args) else: addf(dest, tex, args)

View file

@ -365,92 +365,92 @@ proc genOr(p: PProc, a, b: PNode, r: var TCompRes) =
line(p, "}") line(p, "}")
type type
TMagicFrmt = array[0..3, string] TMagicFrmt = array[0..1, string]
TMagicOps = array[mAddI..mStrToStr, TMagicFrmt] TMagicOps = array[mAddI..mStrToStr, TMagicFrmt]
const # magic checked op; magic unchecked op; checked op; unchecked op const # magic checked op; magic unchecked op;
jsOps: TMagicOps = [ jsMagics: TMagicOps = [
["addInt", "", "addInt($1, $2)", "($1 + $2)"], # AddI ["addInt", ""], # AddI
["subInt", "", "subInt($1, $2)", "($1 - $2)"], # SubI ["subInt", ""], # SubI
["mulInt", "", "mulInt($1, $2)", "($1 * $2)"], # MulI ["mulInt", ""], # MulI
["divInt", "", "divInt($1, $2)", "Math.trunc($1 / $2)"], # DivI ["divInt", ""], # DivI
["modInt", "", "modInt($1, $2)", "Math.trunc($1 % $2)"], # ModI ["modInt", ""], # ModI
["addInt", "", "addInt($1, $2)", "($1 + $2)"], # Succ ["addInt", ""], # Succ
["subInt", "", "subInt($1, $2)", "($1 - $2)"], # Pred ["subInt", ""], # Pred
["", "", "($1 + $2)", "($1 + $2)"], # AddF64 ["", ""], # AddF64
["", "", "($1 - $2)", "($1 - $2)"], # SubF64 ["", ""], # SubF64
["", "", "($1 * $2)", "($1 * $2)"], # MulF64 ["", ""], # MulF64
["", "", "($1 / $2)", "($1 / $2)"], # DivF64 ["", ""], # DivF64
["", "", "", ""], # ShrI ["", ""], # ShrI
["", "", "($1 << $2)", "($1 << $2)"], # ShlI ["", ""], # ShlI
["", "", "($1 >> $2)", "($1 >> $2)"], # AshrI ["", ""], # AshrI
["", "", "($1 & $2)", "($1 & $2)"], # BitandI ["", ""], # BitandI
["", "", "($1 | $2)", "($1 | $2)"], # BitorI ["", ""], # BitorI
["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI ["", ""], # BitxorI
["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinI ["nimMin", "nimMin"], # MinI
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI ["nimMax", "nimMax"], # MaxI
["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64 ["nimMin", "nimMin"], # MinF64
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64 ["nimMax", "nimMax"], # MaxF64
["", "", "", ""], # addU ["", ""], # addU
["", "", "", ""], # subU ["", ""], # subU
["", "", "", ""], # mulU ["", ""], # mulU
["", "", "", ""], # divU ["", ""], # divU
["", "", "($1 % $2)", "($1 % $2)"], # modU ["", ""], # modU
["", "", "($1 == $2)", "($1 == $2)"], # EqI ["", ""], # EqI
["", "", "($1 <= $2)", "($1 <= $2)"], # LeI ["", ""], # LeI
["", "", "($1 < $2)", "($1 < $2)"], # LtI ["", ""], # LtI
["", "", "($1 == $2)", "($1 == $2)"], # EqF64 ["", ""], # EqF64
["", "", "($1 <= $2)", "($1 <= $2)"], # LeF64 ["", ""], # LeF64
["", "", "($1 < $2)", "($1 < $2)"], # LtF64 ["", ""], # LtF64
["", "", "($1 <= $2)", "($1 <= $2)"], # leU ["", ""], # leU
["", "", "($1 < $2)", "($1 < $2)"], # ltU ["", ""], # ltU
["", "", "($1 <= $2)", "($1 <= $2)"], # leU64 ["", ""], # leU64
["", "", "($1 < $2)", "($1 < $2)"], # ltU64 ["", ""], # ltU64
["", "", "($1 == $2)", "($1 == $2)"], # EqEnum ["", ""], # EqEnum
["", "", "($1 <= $2)", "($1 <= $2)"], # LeEnum ["", ""], # LeEnum
["", "", "($1 < $2)", "($1 < $2)"], # LtEnum ["", ""], # LtEnum
["", "", "($1 == $2)", "($1 == $2)"], # EqCh ["", ""], # EqCh
["", "", "($1 <= $2)", "($1 <= $2)"], # LeCh ["", ""], # LeCh
["", "", "($1 < $2)", "($1 < $2)"], # LtCh ["", ""], # LtCh
["", "", "($1 == $2)", "($1 == $2)"], # EqB ["", ""], # EqB
["", "", "($1 <= $2)", "($1 <= $2)"], # LeB ["", ""], # LeB
["", "", "($1 < $2)", "($1 < $2)"], # LtB ["", ""], # LtB
["", "", "($1 == $2)", "($1 == $2)"], # EqRef ["", ""], # EqRef
["", "", "($1 == $2)", "($1 == $2)"], # EqUntracedRef ["", ""], # EqUntracedRef
["", "", "($1 <= $2)", "($1 <= $2)"], # LePtr ["", ""], # LePtr
["", "", "($1 < $2)", "($1 < $2)"], # LtPtr ["", ""], # LtPtr
["", "", "($1 != $2)", "($1 != $2)"], # Xor ["", ""], # Xor
["", "", "($1 == $2)", "($1 == $2)"], # EqCString ["", ""], # EqCString
["", "", "($1 == $2)", "($1 == $2)"], # EqProc ["", ""], # EqProc
["negInt", "", "negInt($1)", "-($1)"], # UnaryMinusI ["negInt", ""], # UnaryMinusI
["negInt64", "", "negInt64($1)", "-($1)"], # UnaryMinusI64 ["negInt64", ""], # UnaryMinusI64
["absInt", "", "absInt($1)", "Math.abs($1)"], # AbsI ["absInt", ""], # AbsI
["", "", "!($1)", "!($1)"], # Not ["", ""], # Not
["", "", "+($1)", "+($1)"], # UnaryPlusI ["", ""], # UnaryPlusI
["", "", "~($1)", "~($1)"], # BitnotI ["", ""], # BitnotI
["", "", "+($1)", "+($1)"], # UnaryPlusF64 ["", ""], # UnaryPlusF64
["", "", "-($1)", "-($1)"], # UnaryMinusF64 ["", ""], # UnaryMinusF64
["", "", "Math.abs($1)", "Math.abs($1)"], # AbsF64 ["", ""], # AbsF64
["Ze8ToI", "Ze8ToI", "Ze8ToI($1)", "Ze8ToI($1)"], # mZe8ToI ["Ze8ToI", "Ze8ToI"], # mZe8ToI
["Ze8ToI64", "Ze8ToI64", "Ze8ToI64($1)", "Ze8ToI64($1)"], # mZe8ToI64 ["Ze8ToI64", "Ze8ToI64"], # mZe8ToI64
["Ze16ToI", "Ze16ToI", "Ze16ToI($1)", "Ze16ToI($1)"], # mZe16ToI ["Ze16ToI", "Ze16ToI"], # mZe16ToI
["Ze16ToI64", "Ze16ToI64", "Ze16ToI64($1)", "Ze16ToI64($1)"], # mZe16ToI64 ["Ze16ToI64", "Ze16ToI64"], # mZe16ToI64
["Ze32ToI64", "Ze32ToI64", "Ze32ToI64($1)", "Ze32ToI64($1)"], # mZe32ToI64 ["Ze32ToI64", "Ze32ToI64"], # mZe32ToI64
["ZeIToI64", "ZeIToI64", "ZeIToI64($1)", "ZeIToI64($1)"], # mZeIToI64 ["ZeIToI64", "ZeIToI64"], # mZeIToI64
["toU8", "toU8", "toU8($1)", "toU8($1)"], # toU8 ["toU8", "toU8"], # toU8
["toU16", "toU16", "toU16($1)", "toU16($1)"], # toU16 ["toU16", "toU16"], # toU16
["toU32", "toU32", "toU32($1)", "toU32($1)"], # toU32 ["toU32", "toU32"], # toU32
["", "", "$1", "$1"], # ToFloat ["", ""], # ToFloat
["", "", "$1", "$1"], # ToBiggestFloat ["", ""], # ToBiggestFloat
["", "", "Math.trunc($1)", "Math.trunc($1)"], # ToInt ["", ""], # ToInt
["", "", "Math.trunc($1)", "Math.trunc($1)"], # ToBiggestInt ["", ""], # ToBiggestInt
["nimCharToStr", "nimCharToStr", "nimCharToStr($1)", "nimCharToStr($1)"], ["nimCharToStr", "nimCharToStr"],
["nimBoolToStr", "nimBoolToStr", "nimBoolToStr($1)", "nimBoolToStr($1)"], ["nimBoolToStr", "nimBoolToStr"],
["cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", "cstrToNimstr"],
["cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", "cstrToNimstr"],
["cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", "cstrToNimstr"],
["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"], ["cstrToNimstr", "cstrToNimstr"],
["", "", "$1", "$1"]] ["", ""]]
proc needsTemp(p: PProc; n: PNode): bool = proc needsTemp(p: PProc; n: PNode): bool =
# check if n contains a call to determine # check if n contains a call to determine
@ -478,7 +478,7 @@ proc maybeMakeTemp(p: PProc, n: PNode; x: TCompRes): tuple[a, tmp: Rope] =
else: else:
(a: a, tmp: b) (a: a, tmp: b)
proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = template binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
# $1 and $2 in the `frmt` string bind to lhs and rhs of the expr, # $1 and $2 in the `frmt` string bind to lhs and rhs of the expr,
# if $3 or $4 are present they will be substituted with temps for # if $3 or $4 are present they will be substituted with temps for
# lhs and rhs respectively # lhs and rhs respectively
@ -490,8 +490,8 @@ proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
var var
a, tmp = x.rdLoc a, tmp = x.rdLoc
b, tmp2 = y.rdLoc b, tmp2 = y.rdLoc
if "$3" in frmt: (a, tmp) = maybeMakeTemp(p, n[1], x) when "$3" in frmt: (a, tmp) = maybeMakeTemp(p, n[1], x)
if "$4" in frmt: (a, tmp) = maybeMakeTemp(p, n[1], x) when "$4" in frmt: (a, tmp) = maybeMakeTemp(p, n[1], x)
r.res = frmt % [a, b, tmp, tmp2] r.res = frmt % [a, b, tmp, tmp2]
r.kind = resExpr r.kind = resExpr
@ -520,7 +520,7 @@ proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string,
r.res = "(($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, trimmer] r.res = "(($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, trimmer]
r.kind = resExpr r.kind = resExpr
proc ternaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = template ternaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
var x, y, z: TCompRes var x, y, z: TCompRes
useMagic(p, magic) useMagic(p, magic)
gen(p, n.sons[1], x) gen(p, n.sons[1], x)
@ -529,7 +529,7 @@ proc ternaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
r.res = frmt % [x.rdLoc, y.rdLoc, z.rdLoc] r.res = frmt % [x.rdLoc, y.rdLoc, z.rdLoc]
r.kind = resExpr r.kind = resExpr
proc unaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = template unaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
# $1 binds to n[1], if $2 is present it will be substituted to a tmp of $1 # $1 binds to n[1], if $2 is present it will be substituted to a tmp of $1
useMagic(p, magic) useMagic(p, magic)
gen(p, n.sons[1], r) gen(p, n.sons[1], r)
@ -541,15 +541,108 @@ proc unaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) = proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
var var
x, y: TCompRes x, y: TCompRes
xLoc,yLoc: Rope
let i = ord(optOverflowCheck notin p.options) let i = ord(optOverflowCheck notin p.options)
useMagic(p, jsOps[op][i]) useMagic(p, jsMagics[op][i])
if sonsLen(n) > 2: if sonsLen(n) > 2:
gen(p, n.sons[1], x) gen(p, n.sons[1], x)
gen(p, n.sons[2], y) gen(p, n.sons[2], y)
r.res = jsOps[op][i + 2] % [x.rdLoc, y.rdLoc] xLoc = x.rdLoc
yLoc = y.rdLoc
else: else:
gen(p, n.sons[1], r) gen(p, n.sons[1], r)
r.res = jsOps[op][i + 2] % [r.rdLoc] xLoc = r.rdLoc
template applyFormat(frmtA, frmtB: string) =
if i == 0:
r.res = frmtA % [xLoc, yLoc]
else:
r.res = frmtB % [xLoc, yLoc]
case op:
of mAddI: applyFormat("addInt($1, $2)", "($1 + $2)")
of mSubI: applyFormat("subInt($1, $2)", "($1 - $2)")
of mMulI: applyFormat("mulInt($1, $2)", "($1 * $2)")
of mDivI: applyFormat("divInt($1, $2)", "Math.trunc($1 / $2)")
of mModI: applyFormat("modInt($1, $2)", "Math.trunc($1 % $2)")
of mSucc: applyFormat("addInt($1, $2)", "($1 + $2)")
of mPred: applyFormat("subInt($1, $2)", "($1 - $2)")
of mAddF64: applyFormat("($1 + $2)", "($1 + $2)")
of mSubF64: applyFormat("($1 - $2)", "($1 - $2)")
of mMulF64: applyFormat("($1 * $2)", "($1 * $2)")
of mDivF64: applyFormat("($1 / $2)", "($1 / $2)")
of mShrI: applyFormat("", "")
of mShlI: applyFormat("($1 << $2)", "($1 << $2)")
of mAshrI: applyFormat("($1 >> $2)", "($1 >> $2)")
of mBitandI: applyFormat("($1 & $2)", "($1 & $2)")
of mBitorI: applyFormat("($1 | $2)", "($1 | $2)")
of mBitxorI: applyFormat("($1 ^ $2)", "($1 ^ $2)")
of mMinI: applyFormat("nimMin($1, $2)", "nimMin($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 msubU: applyFormat("", "")
of mmulU: applyFormat("", "")
of mdivU: applyFormat("", "")
of mmodU: applyFormat("($1 % $2)", "($1 % $2)")
of mEqI: applyFormat("($1 == $2)", "($1 == $2)")
of mLeI: applyFormat("($1 <= $2)", "($1 <= $2)")
of mLtI: applyFormat("($1 < $2)", "($1 < $2)")
of mEqF64: applyFormat("($1 == $2)", "($1 == $2)")
of mLeF64: applyFormat("($1 <= $2)", "($1 <= $2)")
of mLtF64: applyFormat("($1 < $2)", "($1 < $2)")
of mleU: applyFormat("($1 <= $2)", "($1 <= $2)")
of mltU: applyFormat("($1 < $2)", "($1 < $2)")
of mleU64: applyFormat("($1 <= $2)", "($1 <= $2)")
of mltU64: applyFormat("($1 < $2)", "($1 < $2)")
of mEqEnum: applyFormat("($1 == $2)", "($1 == $2)")
of mLeEnum: applyFormat("($1 <= $2)", "($1 <= $2)")
of mLtEnum: applyFormat("($1 < $2)", "($1 < $2)")
of mEqCh: applyFormat("($1 == $2)", "($1 == $2)")
of mLeCh: applyFormat("($1 <= $2)", "($1 <= $2)")
of mLtCh: applyFormat("($1 < $2)", "($1 < $2)")
of mEqB: applyFormat("($1 == $2)", "($1 == $2)")
of mLeB: applyFormat("($1 <= $2)", "($1 <= $2)")
of mLtB: applyFormat("($1 < $2)", "($1 < $2)")
of mEqRef: applyFormat("($1 == $2)", "($1 == $2)")
of mEqUntracedRef: applyFormat("($1 == $2)", "($1 == $2)")
of mLePtr: applyFormat("($1 <= $2)", "($1 <= $2)")
of mLtPtr: applyFormat("($1 < $2)", "($1 < $2)")
of mXor: applyFormat("($1 != $2)", "($1 != $2)")
of mEqCString: applyFormat("($1 == $2)", "($1 == $2)")
of mEqProc: applyFormat("($1 == $2)", "($1 == $2)")
of mUnaryMinusI: applyFormat("negInt($1)", "-($1)")
of mUnaryMinusI64: applyFormat("negInt64($1)", "-($1)")
of mAbsI: applyFormat("absInt($1)", "Math.abs($1)")
of mNot: applyFormat("!($1)", "!($1)")
of mUnaryPlusI: applyFormat("+($1)", "+($1)")
of mBitnotI: applyFormat("~($1)", "~($1)")
of mUnaryPlusF64: applyFormat("+($1)", "+($1)")
of mUnaryMinusF64: applyFormat("-($1)", "-($1)")
of mAbsF64: applyFormat("Math.abs($1)", "Math.abs($1)")
of mZe8ToI: applyFormat("Ze8ToI($1)", "Ze8ToI($1)")
of mZe8ToI64: applyFormat("Ze8ToI64($1)", "Ze8ToI64($1)")
of mZe16ToI: applyFormat("Ze16ToI($1)", "Ze16ToI($1)")
of mZe16ToI64: applyFormat("Ze16ToI64($1)", "Ze16ToI64($1)")
of mZe32ToI64: applyFormat("Ze32ToI64($1)", "Ze32ToI64($1)")
of mZeIToI64: applyFormat("ZeIToI64($1)", "ZeIToI64($1)")
of mtoU8: applyFormat("toU8($1)", "toU8($1)")
of mtoU16: applyFormat("toU16($1)", "toU16($1)")
of mtoU32: applyFormat("toU32($1)", "toU32($1)")
of mToFloat: applyFormat("$1", "$1")
of mToBiggestFloat: applyFormat("$1", "$1")
of mToInt: applyFormat("Math.trunc($1)", "Math.trunc($1)")
of mToBiggestInt: applyFormat("Math.trunc($1)", "Math.trunc($1)")
of mCharToStr: applyFormat("nimCharToStr($1)", "nimCharToStr($1)")
of mBoolToStr: applyFormat("nimBoolToStr($1)", "nimBoolToStr($1)")
of mIntToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")
of mInt64ToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")
of mFloatToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")
of mCStrToStr: applyFormat("cstrToNimstr($1)", "cstrToNimstr($1)")
of mStrToStr: applyFormat("$1", "$1")
else:
assert false, $op
proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) = proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
case op case op
@ -1603,6 +1696,9 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) =
else: else:
varCode = "var $2" varCode = "var $2"
else: else:
# Is this really a thought through feature? this basically unused
# feature makes it impossible for almost all format strings in
# this function to be checked at compile time.
varCode = v.constraint.strVal varCode = v.constraint.strVal
if n.kind == nkEmpty: if n.kind == nkEmpty:
@ -1611,8 +1707,7 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) =
lineF(p, "var $1 = null;$n", [varName]) lineF(p, "var $1 = null;$n", [varName])
lineF(p, "var $1_Idx = 0;$n", [varName]) lineF(p, "var $1_Idx = 0;$n", [varName])
else: else:
lineF(p, varCode & " = $3;$n", line(p, runtimeFormat(varCode & " = $3;$n", [returnType, varName, createVar(p, v.typ, isIndirect(v))]))
[returnType, varName, createVar(p, v.typ, isIndirect(v))])
else: else:
gen(p, n, a) gen(p, n, a)
case mapType(p, v.typ) case mapType(p, v.typ)
@ -1626,29 +1721,29 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) =
let targetBaseIndex = {sfAddrTaken, sfGlobal} * v.flags == {} let targetBaseIndex = {sfAddrTaken, sfGlobal} * v.flags == {}
if a.typ == etyBaseIndex: if a.typ == etyBaseIndex:
if targetBaseIndex: if targetBaseIndex:
lineF(p, varCode & " = $3, $2_Idx = $4;$n", line(p, runtimeFormat(varCode & " = $3, $2_Idx = $4;$n",
[returnType, v.loc.r, a.address, a.res]) [returnType, v.loc.r, a.address, a.res]))
else: else:
if isIndirect(v): if isIndirect(v):
lineF(p, varCode & " = [[$3, $4]];$n", line(p, runtimeFormat(varCode & " = [[$3, $4]];$n",
[returnType, v.loc.r, a.address, a.res]) [returnType, v.loc.r, a.address, a.res]))
else: else:
lineF(p, varCode & " = [$3, $4];$n", line(p, runtimeFormat(varCode & " = [$3, $4];$n",
[returnType, v.loc.r, a.address, a.res]) [returnType, v.loc.r, a.address, a.res]))
else: else:
if targetBaseIndex: if targetBaseIndex:
let tmp = p.getTemp let tmp = p.getTemp
lineF(p, "var $1 = $2, $3 = $1[0], $3_Idx = $1[1];$n", lineF(p, "var $1 = $2, $3 = $1[0], $3_Idx = $1[1];$n",
[tmp, a.res, v.loc.r]) [tmp, a.res, v.loc.r])
else: else:
lineF(p, varCode & " = $3;$n", [returnType, v.loc.r, a.res]) line(p, runtimeFormat(varCode & " = $3;$n", [returnType, v.loc.r, a.res]))
return return
else: else:
s = a.res s = a.res
if isIndirect(v): if isIndirect(v):
lineF(p, varCode & " = [$3];$n", [returnType, v.loc.r, s]) line(p, runtimeFormat(varCode & " = [$3];$n", [returnType, v.loc.r, s]))
else: else:
lineF(p, varCode & " = $3;$n", [returnType, v.loc.r, s]) line(p, runtimeFormat(varCode & " = $3;$n", [returnType, v.loc.r, s]))
if useReloadingGuard: if useReloadingGuard:
dec p.extraIndent dec p.extraIndent
@ -2117,7 +2212,7 @@ proc genReturnStmt(p: PProc, n: PNode) =
lineF(p, "break BeforeRet;$n", []) lineF(p, "break BeforeRet;$n", [])
proc frameCreate(p: PProc; procname, filename: Rope): Rope = proc frameCreate(p: PProc; procname, filename: Rope): Rope =
let frameFmt = const frameFmt =
"var F={procname:$1,prev:framePtr,filename:$2,line:0};$n" "var F={procname:$1,prev:framePtr,filename:$2,line:0};$n"
result = p.indentLine(frameFmt % [procname, filename]) result = p.indentLine(frameFmt % [procname, filename])
@ -2185,7 +2280,7 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
var def: Rope var def: Rope
if not prc.constraint.isNil: if not prc.constraint.isNil:
def = (prc.constraint.strVal & " {$n$#$#$#$#$#") % def = runtimeFormat(prc.constraint.strVal & " {$n$#$#$#$#$#",
[ returnType, [ returnType,
name, name,
header, header,
@ -2193,7 +2288,7 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
optionalLine(p.locals), optionalLine(p.locals),
optionalLine(resultAsgn), optionalLine(resultAsgn),
optionalLine(genProcBody(p, prc)), optionalLine(genProcBody(p, prc)),
optionalLine(p.indentLine(returnStmt))] optionalLine(p.indentLine(returnStmt))])
else: else:
result = ~"\L" result = ~"\L"

View file

@ -211,7 +211,7 @@ proc ropeConcat*(a: varargs[Rope]): Rope =
proc prepend*(a: var Rope, b: Rope) = a = b & a proc prepend*(a: var Rope, b: Rope) = a = b & a
proc prepend*(a: var Rope, b: string) = a = b & a proc prepend*(a: var Rope, b: string) = a = b & a
proc `%`*(frmt: FormatStr, args: openArray[Rope]): Rope = proc runtimeFormat*(frmt: FormatStr, args: openArray[Rope]): Rope =
var i = 0 var i = 0
var length = len(frmt) var length = len(frmt)
result = nil result = nil
@ -269,7 +269,10 @@ proc `%`*(frmt: FormatStr, args: openArray[Rope]): Rope =
add(result, substr(frmt, start, i - 1)) add(result, substr(frmt, start, i - 1))
assert(ropeInvariant(result)) assert(ropeInvariant(result))
proc addf*(c: var Rope, frmt: FormatStr, args: openArray[Rope]) = proc `%`*(frmt: static[FormatStr], args: openArray[Rope]): Rope =
runtimeFormat(frmt, args)
template addf*(c: var Rope, frmt: FormatStr, args: openArray[Rope]) =
## shortcut for ``add(c, frmt % args)``. ## shortcut for ``add(c, frmt % args)``.
add(c, frmt % args) add(c, frmt % args)