diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgcalls.nim | 12 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 218 | ||||
-rw-r--r-- | compiler/ccgstmts.nim | 4 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 27 | ||||
-rw-r--r-- | compiler/cgen.nim | 12 | ||||
-rw-r--r-- | compiler/docgen.nim | 2 | ||||
-rw-r--r-- | compiler/jsgen.nim | 311 | ||||
-rw-r--r-- | compiler/ropes.nim | 7 |
8 files changed, 380 insertions, 213 deletions
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index e46e2c47d..fcdba2996 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -218,10 +218,12 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) = genParamLoop(pl) 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 callPattern = if tfIterator in typ.flags: PatIter else: PatProc if typ.sons[0] != nil: if isInvalidReturnType(p.config, typ.sons[0]): 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: var list: TLoc 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 else: genCallPattern() diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 9f4d57359..e6d22379f 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -99,17 +99,17 @@ proc bitSetToWord(s: TBitSet, size: int): BiggestInt = if j < len(s): result = result or (ze64(s[j]) shl (j * 8)) proc genRawSetData(cs: TBitSet, size: int): Rope = - var frmt: FormatStr if size > 8: result = "{$n" % [] for i in countup(0, size - 1): if i < size - 1: # not last iteration? - if (i + 1) mod 8 == 0: frmt = "0x$1,$n" - else: frmt = "0x$1, " + if (i + 1) mod 8 == 0: + addf(result, "0x$1,$n", [rope(toHex(ze64(cs[i]), 2))]) + else: + addf(result, "0x$1, ", [rope(toHex(ze64(cs[i]), 2))]) else: - frmt = "0x$1}$n" - addf(result, frmt, [rope(toHex(ze64(cs[i]), 2))]) + addf(result, "0x$1}$n", [rope(toHex(ze64(cs[i]), 2))]) else: result = intLiteral(bitSetToWord(cs, size)) # 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", "addInt64", "subInt64" ] - opr: array[mAddI..mPred, string] = [ - "($#)($# + $#)", "($#)($# - $#)", "($#)($# * $#)", - "($#)($# / $#)", "($#)($# % $#)", - "($#)($# + $#)", "($#)($# - $#)"] + opr: array[mAddI..mPred, string] = ["+", "-", "*", "/", "%", "+", "-"] var a, b: TLoc assert(e.sons[1].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' let t = e.typ.skipTypes(abstractRange) 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) else: 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]) 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 a: TLoc t: PType @@ -545,54 +537,17 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = if optOverflowCheck in p.options: linefmt(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n", [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) = - 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 a, b: TLoc 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 s = max(getSize(p.config, a.t), getSize(p.config, b.t)) * 8 k = getSize(p.config, a.t) * 8 - putIntoDest(p, d, e, - binArithTab[op] % [rdLoc(a), rdLoc(b), rope(s), - getSimpleTypeDesc(p.module, e.typ), rope(k)]) + + template applyFormat(frmt: untyped) = + 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) = 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) = const - unArithTab: array[mNot..mToBiggestInt, string] = ["!($1)", # Not + unArithTab: array[mNot..mToBiggestInt, string] = [ + "!($1)", # Not "$1", # UnaryPlusI "($3)((NU$2) ~($1))", # BitnotI "$1", # UnaryPlusF64 @@ -654,10 +660,58 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = assert(e.sons[1].typ != nil) initLocExpr(p, e.sons[1], a) 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)]) + + 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.} = result = p.module.compileToCpp and skipTypes(typ, abstractInstOwned).kind == tyVar and @@ -1675,7 +1729,7 @@ proc fewCmps(conf: ConfigRef; s: PNode): bool = else: 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)]) 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)") 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 assert(d.k == locNone) 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: case op of mIncl: - var ts = "NU" & $(size * 8) - binaryStmtInExcl(p, e, d, - "$1 |= ((" & ts & ")1)<<(($2)%(sizeof(" & ts & ")*8));$n") + case size + of 1: binaryStmtInExcl(p, e, d, "$1 |= ((NU8)1)<<(($2) & 7);$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: - var ts = "NU" & $(size * 8) - binaryStmtInExcl(p, e, d, "$1 &= ~(((" & ts & ")1) << (($2) % (sizeof(" & - ts & ")*8)));$n") + case size + of 1: binaryStmtInExcl(p, e, d, "$1 &= ~(((NU8)1) << (($2) & 7));$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: if size <= 4: unaryExprChar(p, e, d, "#countBits32($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[1], b) 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), - rdSetElemLoc(p.config, b, e.typ)]) + rdSetElemLoc(p.config, b, e.typ), rope(ts)]) else: initLocExpr(p, it, a) lineF(p, cpsStmts, - "$1 |=((" & ts & ")(1)<<(($2)%(sizeof(" & ts & ")*8)));$n", - [rdLoc(d), rdSetElemLoc(p.config, a, e.typ)]) + "$1 |=(($3)(1)<<(($2)%(sizeof($3)*8)));$n", + [rdLoc(d), rdSetElemLoc(p.config, a, e.typ), rope(ts)]) proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) = var rec: TLoc diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 386bedae9..25bcdf65e 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -1135,9 +1135,9 @@ proc genAsmStmt(p: BProc, t: PNode) = # work: if p.prc == nil: # 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: - 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 = result = cfsProcHeaders diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 7d5a761bc..facd8b3d4 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -338,12 +338,17 @@ proc getTypePre(m: BModule, typ: PType; sig: SigHash): Rope = if result == nil: result = cacheGetType(m.typeCache, sig) proc structOrUnion(t: PType): Rope = + let cachedUnion {.global.} = rope("union") + let cachedStruct {.global.} = rope("struct") 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 = - if m.compileToCpp: result = "$1 $2;$n" - else: result = "typedef $1 $2 $2;$n" +proc addForwardStructFormat(m: BModule, structOrUnion: Rope, typename: Rope) = + if m.compileToCpp: + 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 = if m.config.selectedGC == gcDestructors: result = "" @@ -360,8 +365,7 @@ proc getTypeForward(m: BModule, typ: PType; sig: SigHash): Rope = result = getTypeName(m, typ, sig) m.forwTypeCache[sig] = result if not isImportedType(concrete): - addf(m.s[cfsForwardTypes], getForwardStructFormat(m), - [structOrUnion(typ), result]) + addForwardStructFormat(m, structOrUnion(typ), result) else: pushType(m, concrete) doAssert m.forwTypeCache[sig] == result @@ -733,8 +737,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope = if result == nil: result = getTypeName(m, origTyp, sig) if not isImportedType(t): - addf(m.s[cfsForwardTypes], getForwardStructFormat(m), - [structOrUnion(t), result]) + addForwardStructFormat(m, structOrUnion(t), result) m.forwTypeCache[sig] = result assert(cacheGetType(m.typeCache, sig) == nil) 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) m.forwTypeCache[sig] = result if not isImportedType(t): - addf(m.s[cfsForwardTypes], getForwardStructFormat(m), - [structOrUnion(t), result]) + addForwardStructFormat(m, structOrUnion(t), result) assert m.forwTypeCache[sig] == result m.typeCache[sig] = result # always call for sideeffects: if not incompleteType(t): @@ -905,7 +907,8 @@ proc finishTypeDescriptions(m: BModule) = discard getTypeDesc(m, m.typeStack[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 = return m.hcrOn and sfNonReloadable notin prc.flags @@ -943,7 +946,7 @@ proc genProcHeader(m: BModule, prc: PSym, asPtr: bool = false): Rope = params]) else: let asPtrStr = if asPtr: (rope("(*") & name & ")") else: name - result = prc.cgDeclFrmt % [rettype, asPtrStr, params] + result = runtimeFormat(prc.cgDeclFrmt, [rettype, asPtrStr, params]) # ------------------ type info generation ------------------------------------- diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 92cc3819b..e87f512c8 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -206,15 +206,15 @@ proc indentLine(p: BProc, r: Rope): Rope = prepend(result, "\t".rope) template appcg(m: BModule, c: var Rope, frmt: FormatStr, - args: varargs[untyped]) = + args: untyped) = add(c, ropecg(m, frmt, args)) template appcg(m: BModule, sec: TCFileSection, frmt: FormatStr, - args: varargs[untyped]) = + args: untyped) = add(m.s[sec], ropecg(m, frmt, args)) template appcg(p: BProc, sec: TCProcSection, frmt: FormatStr, - args: varargs[untyped]) = + args: untyped) = add(p.s(sec), ropecg(p.module, frmt, args)) 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)) template lineF(p: BProc, sec: TCProcSection, frmt: FormatStr, - args: openarray[Rope]) = + args: untyped) = add(p.s(sec), indentLine(p, frmt % args)) template lineCg(p: BProc, sec: TCProcSection, frmt: FormatStr, @@ -484,7 +484,7 @@ proc localVarDecl(p: BProc; n: PNode): Rope = add(result, " ") add(result, s.loc.r) else: - result = s.cgDeclFrmt % [result, s.loc.r] + result = runtimeFormat(s.cgDeclFrmt, [result, s.loc.r]) proc assignLocalVar(p: BProc, n: PNode) = #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") addf(decl, " $1;$n", [s.loc.r]) else: - decl = (s.cgDeclFrmt & ";$n") % [td, s.loc.r] + decl = runtimeFormat(s.cgDeclFrmt & ";$n", [td, s.loc.r]) add(p.module.s[cfsVars], decl) if p.withinLoop > 0: # fixes tests/run/tzeroarray: diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 93efef526..014f757db 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -172,7 +172,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef, outExt, RelativeDir"htmldocs", false) 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) else: addf(dest, tex, args) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 5f93cbbbd..750d7c2c2 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -32,9 +32,9 @@ import ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options, nversion, nimsets, msgs, std / sha1, bitsets, idents, types, os, tables, times, ropes, math, passes, ccgutils, wordrecg, renderer, - intsets, cgmeth, lowerings, sighashes, modulegraphs, lineinfos, rodutils, + intsets, cgmeth, lowerings, sighashes, modulegraphs, lineinfos, rodutils, pathutils, transf - + from modulegraphs import ModuleGraph, PPassContext @@ -365,92 +365,92 @@ proc genOr(p: PProc, a, b: PNode, r: var TCompRes) = line(p, "}") type - TMagicFrmt = array[0..3, string] + TMagicFrmt = array[0..1, string] TMagicOps = array[mAddI..mStrToStr, TMagicFrmt] -const # magic checked op; magic unchecked op; checked op; unchecked op - jsOps: TMagicOps = [ - ["addInt", "", "addInt($1, $2)", "($1 + $2)"], # AddI - ["subInt", "", "subInt($1, $2)", "($1 - $2)"], # SubI - ["mulInt", "", "mulInt($1, $2)", "($1 * $2)"], # MulI - ["divInt", "", "divInt($1, $2)", "Math.trunc($1 / $2)"], # DivI - ["modInt", "", "modInt($1, $2)", "Math.trunc($1 % $2)"], # ModI - ["addInt", "", "addInt($1, $2)", "($1 + $2)"], # Succ - ["subInt", "", "subInt($1, $2)", "($1 - $2)"], # Pred - ["", "", "($1 + $2)", "($1 + $2)"], # AddF64 - ["", "", "($1 - $2)", "($1 - $2)"], # SubF64 - ["", "", "($1 * $2)", "($1 * $2)"], # MulF64 - ["", "", "($1 / $2)", "($1 / $2)"], # DivF64 - ["", "", "", ""], # ShrI - ["", "", "($1 << $2)", "($1 << $2)"], # ShlI - ["", "", "($1 >> $2)", "($1 >> $2)"], # AshrI - ["", "", "($1 & $2)", "($1 & $2)"], # BitandI - ["", "", "($1 | $2)", "($1 | $2)"], # BitorI - ["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI - ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinI - ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI - ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64 - ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64 - ["", "", "", ""], # addU - ["", "", "", ""], # subU - ["", "", "", ""], # mulU - ["", "", "", ""], # divU - ["", "", "($1 % $2)", "($1 % $2)"], # modU - ["", "", "($1 == $2)", "($1 == $2)"], # EqI - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeI - ["", "", "($1 < $2)", "($1 < $2)"], # LtI - ["", "", "($1 == $2)", "($1 == $2)"], # EqF64 - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeF64 - ["", "", "($1 < $2)", "($1 < $2)"], # LtF64 - ["", "", "($1 <= $2)", "($1 <= $2)"], # leU - ["", "", "($1 < $2)", "($1 < $2)"], # ltU - ["", "", "($1 <= $2)", "($1 <= $2)"], # leU64 - ["", "", "($1 < $2)", "($1 < $2)"], # ltU64 - ["", "", "($1 == $2)", "($1 == $2)"], # EqEnum - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeEnum - ["", "", "($1 < $2)", "($1 < $2)"], # LtEnum - ["", "", "($1 == $2)", "($1 == $2)"], # EqCh - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeCh - ["", "", "($1 < $2)", "($1 < $2)"], # LtCh - ["", "", "($1 == $2)", "($1 == $2)"], # EqB - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeB - ["", "", "($1 < $2)", "($1 < $2)"], # LtB - ["", "", "($1 == $2)", "($1 == $2)"], # EqRef - ["", "", "($1 == $2)", "($1 == $2)"], # EqUntracedRef - ["", "", "($1 <= $2)", "($1 <= $2)"], # LePtr - ["", "", "($1 < $2)", "($1 < $2)"], # LtPtr - ["", "", "($1 != $2)", "($1 != $2)"], # Xor - ["", "", "($1 == $2)", "($1 == $2)"], # EqCString - ["", "", "($1 == $2)", "($1 == $2)"], # EqProc - ["negInt", "", "negInt($1)", "-($1)"], # UnaryMinusI - ["negInt64", "", "negInt64($1)", "-($1)"], # UnaryMinusI64 - ["absInt", "", "absInt($1)", "Math.abs($1)"], # AbsI - ["", "", "!($1)", "!($1)"], # Not - ["", "", "+($1)", "+($1)"], # UnaryPlusI - ["", "", "~($1)", "~($1)"], # BitnotI - ["", "", "+($1)", "+($1)"], # UnaryPlusF64 - ["", "", "-($1)", "-($1)"], # UnaryMinusF64 - ["", "", "Math.abs($1)", "Math.abs($1)"], # AbsF64 - ["Ze8ToI", "Ze8ToI", "Ze8ToI($1)", "Ze8ToI($1)"], # mZe8ToI - ["Ze8ToI64", "Ze8ToI64", "Ze8ToI64($1)", "Ze8ToI64($1)"], # mZe8ToI64 - ["Ze16ToI", "Ze16ToI", "Ze16ToI($1)", "Ze16ToI($1)"], # mZe16ToI - ["Ze16ToI64", "Ze16ToI64", "Ze16ToI64($1)", "Ze16ToI64($1)"], # mZe16ToI64 - ["Ze32ToI64", "Ze32ToI64", "Ze32ToI64($1)", "Ze32ToI64($1)"], # mZe32ToI64 - ["ZeIToI64", "ZeIToI64", "ZeIToI64($1)", "ZeIToI64($1)"], # mZeIToI64 - ["toU8", "toU8", "toU8($1)", "toU8($1)"], # toU8 - ["toU16", "toU16", "toU16($1)", "toU16($1)"], # toU16 - ["toU32", "toU32", "toU32($1)", "toU32($1)"], # toU32 - ["", "", "$1", "$1"], # ToFloat - ["", "", "$1", "$1"], # ToBiggestFloat - ["", "", "Math.trunc($1)", "Math.trunc($1)"], # ToInt - ["", "", "Math.trunc($1)", "Math.trunc($1)"], # ToBiggestInt - ["nimCharToStr", "nimCharToStr", "nimCharToStr($1)", "nimCharToStr($1)"], - ["nimBoolToStr", "nimBoolToStr", "nimBoolToStr($1)", "nimBoolToStr($1)"], - ["cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"], - ["cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"], - ["cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"], - ["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"], - ["", "", "$1", "$1"]] +const # magic checked op; magic unchecked op; + jsMagics: TMagicOps = [ + ["addInt", ""], # AddI + ["subInt", ""], # SubI + ["mulInt", ""], # MulI + ["divInt", ""], # DivI + ["modInt", ""], # ModI + ["addInt", ""], # Succ + ["subInt", ""], # Pred + ["", ""], # AddF64 + ["", ""], # SubF64 + ["", ""], # MulF64 + ["", ""], # DivF64 + ["", ""], # ShrI + ["", ""], # ShlI + ["", ""], # AshrI + ["", ""], # BitandI + ["", ""], # BitorI + ["", ""], # BitxorI + ["nimMin", "nimMin"], # MinI + ["nimMax", "nimMax"], # MaxI + ["nimMin", "nimMin"], # MinF64 + ["nimMax", "nimMax"], # MaxF64 + ["", ""], # addU + ["", ""], # subU + ["", ""], # mulU + ["", ""], # divU + ["", ""], # modU + ["", ""], # EqI + ["", ""], # LeI + ["", ""], # LtI + ["", ""], # EqF64 + ["", ""], # LeF64 + ["", ""], # LtF64 + ["", ""], # leU + ["", ""], # ltU + ["", ""], # leU64 + ["", ""], # ltU64 + ["", ""], # EqEnum + ["", ""], # LeEnum + ["", ""], # LtEnum + ["", ""], # EqCh + ["", ""], # LeCh + ["", ""], # LtCh + ["", ""], # EqB + ["", ""], # LeB + ["", ""], # LtB + ["", ""], # EqRef + ["", ""], # EqUntracedRef + ["", ""], # LePtr + ["", ""], # LtPtr + ["", ""], # Xor + ["", ""], # EqCString + ["", ""], # EqProc + ["negInt", ""], # UnaryMinusI + ["negInt64", ""], # UnaryMinusI64 + ["absInt", ""], # AbsI + ["", ""], # Not + ["", ""], # UnaryPlusI + ["", ""], # BitnotI + ["", ""], # UnaryPlusF64 + ["", ""], # UnaryMinusF64 + ["", ""], # AbsF64 + ["Ze8ToI", "Ze8ToI"], # mZe8ToI + ["Ze8ToI64", "Ze8ToI64"], # mZe8ToI64 + ["Ze16ToI", "Ze16ToI"], # mZe16ToI + ["Ze16ToI64", "Ze16ToI64"], # mZe16ToI64 + ["Ze32ToI64", "Ze32ToI64"], # mZe32ToI64 + ["ZeIToI64", "ZeIToI64"], # mZeIToI64 + ["toU8", "toU8"], # toU8 + ["toU16", "toU16"], # toU16 + ["toU32", "toU32"], # toU32 + ["", ""], # ToFloat + ["", ""], # ToBiggestFloat + ["", ""], # ToInt + ["", ""], # ToBiggestInt + ["nimCharToStr", "nimCharToStr"], + ["nimBoolToStr", "nimBoolToStr"], + ["cstrToNimstr", "cstrToNimstr"], + ["cstrToNimstr", "cstrToNimstr"], + ["cstrToNimstr", "cstrToNimstr"], + ["cstrToNimstr", "cstrToNimstr"], + ["", ""]] proc needsTemp(p: PProc; n: PNode): bool = # 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: (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, # if $3 or $4 are present they will be substituted with temps for # lhs and rhs respectively @@ -490,8 +490,8 @@ proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = var a, tmp = x.rdLoc b, tmp2 = y.rdLoc - if "$3" in frmt: (a, tmp) = maybeMakeTemp(p, n[1], x) - if "$4" in frmt: (a, tmp) = maybeMakeTemp(p, n[1], x) + when "$3" 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.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.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 useMagic(p, magic) 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.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 useMagic(p, magic) 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) = var x, y: TCompRes + xLoc,yLoc: Rope let i = ord(optOverflowCheck notin p.options) - useMagic(p, jsOps[op][i]) + useMagic(p, jsMagics[op][i]) if sonsLen(n) > 2: gen(p, n.sons[1], x) gen(p, n.sons[2], y) - r.res = jsOps[op][i + 2] % [x.rdLoc, y.rdLoc] + xLoc = x.rdLoc + yLoc = y.rdLoc else: 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) = case op @@ -1603,6 +1696,9 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) = else: varCode = "var $2" 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 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_Idx = 0;$n", [varName]) else: - lineF(p, varCode & " = $3;$n", - [returnType, varName, createVar(p, v.typ, isIndirect(v))]) + line(p, runtimeFormat(varCode & " = $3;$n", [returnType, varName, createVar(p, v.typ, isIndirect(v))])) else: gen(p, n, a) case mapType(p, v.typ) @@ -1626,29 +1721,29 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) = let targetBaseIndex = {sfAddrTaken, sfGlobal} * v.flags == {} if a.typ == etyBaseIndex: if targetBaseIndex: - lineF(p, varCode & " = $3, $2_Idx = $4;$n", - [returnType, v.loc.r, a.address, a.res]) + line(p, runtimeFormat(varCode & " = $3, $2_Idx = $4;$n", + [returnType, v.loc.r, a.address, a.res])) else: if isIndirect(v): - lineF(p, varCode & " = [[$3, $4]];$n", - [returnType, v.loc.r, a.address, a.res]) + line(p, runtimeFormat(varCode & " = [[$3, $4]];$n", + [returnType, v.loc.r, a.address, a.res])) else: - lineF(p, varCode & " = [$3, $4];$n", - [returnType, v.loc.r, a.address, a.res]) + line(p, runtimeFormat(varCode & " = [$3, $4];$n", + [returnType, v.loc.r, a.address, a.res])) else: if targetBaseIndex: let tmp = p.getTemp lineF(p, "var $1 = $2, $3 = $1[0], $3_Idx = $1[1];$n", [tmp, a.res, v.loc.r]) 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 else: s = a.res 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: - lineF(p, varCode & " = $3;$n", [returnType, v.loc.r, s]) + line(p, runtimeFormat(varCode & " = $3;$n", [returnType, v.loc.r, s])) if useReloadingGuard: dec p.extraIndent @@ -2117,7 +2212,7 @@ proc genReturnStmt(p: PProc, n: PNode) = lineF(p, "break BeforeRet;$n", []) proc frameCreate(p: PProc; procname, filename: Rope): Rope = - let frameFmt = + const frameFmt = "var F={procname:$1,prev:framePtr,filename:$2,line:0};$n" result = p.indentLine(frameFmt % [procname, filename]) @@ -2185,7 +2280,7 @@ proc genProc(oldProc: PProc, prc: PSym): Rope = var def: Rope if not prc.constraint.isNil: - def = (prc.constraint.strVal & " {$n$#$#$#$#$#") % + def = runtimeFormat(prc.constraint.strVal & " {$n$#$#$#$#$#", [ returnType, name, header, @@ -2193,7 +2288,7 @@ proc genProc(oldProc: PProc, prc: PSym): Rope = optionalLine(p.locals), optionalLine(resultAsgn), optionalLine(genProcBody(p, prc)), - optionalLine(p.indentLine(returnStmt))] + optionalLine(p.indentLine(returnStmt))]) else: result = ~"\L" diff --git a/compiler/ropes.nim b/compiler/ropes.nim index 2071ab46a..87026025f 100644 --- a/compiler/ropes.nim +++ b/compiler/ropes.nim @@ -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: string) = a = b & a -proc `%`*(frmt: FormatStr, args: openArray[Rope]): Rope = +proc runtimeFormat*(frmt: FormatStr, args: openArray[Rope]): Rope = var i = 0 var length = len(frmt) result = nil @@ -269,7 +269,10 @@ proc `%`*(frmt: FormatStr, args: openArray[Rope]): Rope = add(result, substr(frmt, start, i - 1)) 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)``. add(c, frmt % args) |