disables the compile-time rope formatting during bootstrapping

This commit is contained in:
Zahary Karadjov 2012-11-21 23:23:37 +02:00
commit a42545ea3e
7 changed files with 223 additions and 208 deletions

View file

@ -185,13 +185,13 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
# lineF(p, cpsStmts, 'if ($1) nimGCunref($1);$n', [rdLoc(dest)]) # lineF(p, cpsStmts, 'if ($1) nimGCunref($1);$n', [rdLoc(dest)])
# lineF(p, cpsStmts, '$1 = $2;$n', [rdLoc(dest), rdLoc(src)]) # lineF(p, cpsStmts, '$1 = $2;$n', [rdLoc(dest), rdLoc(src)])
if canFormAcycle(dest.t): if canFormAcycle(dest.t):
lineCg2(p, cpsStmts, "#asgnRef((void**) $1, $2);$n", linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);$n",
addrLoc(dest), rdLoc(src)) addrLoc(dest), rdLoc(src))
else: else:
lineCg2(p, cpsStmts, "#asgnRefNoCycle((void**) $1, $2);$n", linefmt(p, cpsStmts, "#asgnRefNoCycle((void**) $1, $2);$n",
addrLoc(dest), rdLoc(src)) addrLoc(dest), rdLoc(src))
else: else:
lineCg2(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n", linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n",
addrLoc(dest), rdLoc(src)) addrLoc(dest), rdLoc(src))
if needToKeepAlive in flags: keepAlive(p, dest) if needToKeepAlive in flags: keepAlive(p, dest)
@ -205,15 +205,15 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
if needToCopy notin flags or if needToCopy notin flags or
tfShallow in skipTypes(dest.t, abstractVarRange).flags: tfShallow in skipTypes(dest.t, abstractVarRange).flags:
if dest.s == OnStack or optRefcGC notin gGlobalOptions: if dest.s == OnStack or optRefcGC notin gGlobalOptions:
lineCg2(p, cpsStmts, linefmt(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
addrLoc(dest), addrLoc(src), rdLoc(dest)) addrLoc(dest), addrLoc(src), rdLoc(dest))
if needToKeepAlive in flags: keepAlive(p, dest) if needToKeepAlive in flags: keepAlive(p, dest)
else: else:
lineCg2(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n", linefmt(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n",
addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)) addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
else: else:
lineCg2(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n", linefmt(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)) addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
@ -221,7 +221,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
# the assignment operation in C. # the assignment operation in C.
if src.t != nil and src.t.kind == tyPtr: if src.t != nil and src.t.kind == tyPtr:
# little HACK to support the new 'var T' as return type: # little HACK to support the new 'var T' as return type:
lineCg2(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
return return
var ty = skipTypes(dest.t, abstractRange) var ty = skipTypes(dest.t, abstractRange)
case ty.kind case ty.kind
@ -231,24 +231,24 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
if needToCopy notin flags: if needToCopy notin flags:
genRefAssign(p, dest, src, flags) genRefAssign(p, dest, src, flags)
else: else:
lineCg2(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n", linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t)) addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t))
of tyString: of tyString:
if needToCopy notin flags: if needToCopy notin flags:
genRefAssign(p, dest, src, flags) genRefAssign(p, dest, src, flags)
else: else:
if dest.s == OnStack or optRefcGC notin gGlobalOptions: if dest.s == OnStack or optRefcGC notin gGlobalOptions:
lineCg(p, cpsStmts, "$1 = #copyString($2);$n", [dest.rdLoc, src.rdLoc]) linefmt(p, cpsStmts, "$1 = #copyString($2);$n", dest.rdLoc, src.rdLoc)
if needToKeepAlive in flags: keepAlive(p, dest) if needToKeepAlive in flags: keepAlive(p, dest)
elif dest.s == OnHeap: elif dest.s == OnHeap:
# we use a temporary to care for the dreaded self assignment: # we use a temporary to care for the dreaded self assignment:
var tmp: TLoc var tmp: TLoc
getTemp(p, ty, tmp) getTemp(p, ty, tmp)
lineCg2(p, cpsStmts, "$3 = $1; $1 = #copyStringRC1($2);$n", linefmt(p, cpsStmts, "$3 = $1; $1 = #copyStringRC1($2);$n",
dest.rdLoc, src.rdLoc, tmp.rdLoc) dest.rdLoc, src.rdLoc, tmp.rdLoc)
lineCg(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", tmp.rdLoc) linefmt(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", tmp.rdLoc)
else: else:
lineCg2(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n", linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n",
addrLoc(dest), rdLoc(src)) addrLoc(dest), rdLoc(src))
if needToKeepAlive in flags: keepAlive(p, dest) if needToKeepAlive in flags: keepAlive(p, dest)
of tyTuple, tyObject, tyProc: of tyTuple, tyObject, tyProc:
@ -256,34 +256,34 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
if needsComplexAssignment(dest.t): if needsComplexAssignment(dest.t):
genGenericAsgn(p, dest, src, flags) genGenericAsgn(p, dest, src, flags)
else: else:
lineCg2(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
of tyArray, tyArrayConstr: of tyArray, tyArrayConstr:
if needsComplexAssignment(dest.t): if needsComplexAssignment(dest.t):
genGenericAsgn(p, dest, src, flags) genGenericAsgn(p, dest, src, flags)
else: else:
lineCg2(p, cpsStmts, linefmt(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1));$n", "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1));$n",
rdLoc(dest), rdLoc(src)) rdLoc(dest), rdLoc(src))
of tyOpenArray, tyVarargs: of tyOpenArray, tyVarargs:
# open arrays are always on the stack - really? What if a sequence is # open arrays are always on the stack - really? What if a sequence is
# passed to an open array? # passed to an open array?
if needsComplexAssignment(dest.t): if needsComplexAssignment(dest.t):
lineCg2(p, cpsStmts, # XXX: is this correct for arrays? linefmt(p, cpsStmts, # XXX: is this correct for arrays?
"#genericAssignOpenArray((void*)$1, (void*)$2, $1Len0, $3);$n", "#genericAssignOpenArray((void*)$1, (void*)$2, $1Len0, $3);$n",
addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)) addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
else: else:
lineCg2(p, cpsStmts, linefmt(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len0);$n", "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len0);$n",
rdLoc(dest), rdLoc(src)) rdLoc(dest), rdLoc(src))
of tySet: of tySet:
if mapType(ty) == ctArray: if mapType(ty) == ctArray:
lineCg2(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n", linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n",
rdLoc(dest), rdLoc(src), toRope(getSize(dest.t))) rdLoc(dest), rdLoc(src), toRope(getSize(dest.t)))
else: else:
lineCg2(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCString, of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCString,
tyInt..tyUInt64, tyRange, tyVar: tyInt..tyUInt64, tyRange, tyVar:
lineCg2(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
else: InternalError("genAssignment(" & $ty.kind & ')') else: InternalError("genAssignment(" & $ty.kind & ')')
proc expr(p: BProc, e: PNode, d: var TLoc) proc expr(p: BProc, e: PNode, d: var TLoc)
@ -387,12 +387,12 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
else: else:
storage = getTypeDesc(p.module, t) storage = getTypeDesc(p.module, t)
var tmp = getTempName() var tmp = getTempName()
lineCg(p, cpsLocals, "$1 $2;$n", [storage, tmp]) linefmt(p, cpsLocals, "$1 $2;$n", storage, tmp)
lineCg(p, cpsStmts, "$1 = #$2($3, $4);$n", [tmp, toRope(prc[m]), lineCg(p, cpsStmts, "$1 = #$2($3, $4);$n",
rdLoc(a), rdLoc(b)]) tmp, toRope(prc[m]), rdLoc(a), rdLoc(b))
if size < platform.IntSize or t.kind in {tyRange, tyEnum, tySet}: if size < platform.IntSize or t.kind in {tyRange, tyEnum, tySet}:
lineCg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n", linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
[tmp, intLiteral(firstOrd(t)), intLiteral(lastOrd(t))]) tmp, intLiteral(firstOrd(t)), intLiteral(lastOrd(t)))
putIntoDest(p, d, e.typ, ropef("(NI$1)($2)", [toRope(getSize(t)*8), tmp])) 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) =
@ -409,8 +409,8 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
InitLocExpr(p, e.sons[1], a) InitLocExpr(p, e.sons[1], a)
t = skipTypes(e.typ, abstractRange) t = skipTypes(e.typ, abstractRange)
if optOverflowCheck in p.options: if optOverflowCheck in p.options:
lineCg(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n", linefmt(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n",
[rdLoc(a), intLiteral(firstOrd(t))]) rdLoc(a), intLiteral(firstOrd(t)))
putIntoDest(p, d, e.typ, ropef(opr[m], [rdLoc(a), toRope(getSize(t) * 8)])) putIntoDest(p, d, e.typ, ropef(opr[m], [rdLoc(a), toRope(getSize(t) * 8)]))
proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
@ -655,14 +655,14 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
if id == gBackendId: strLit = getStrLit(p.module, field.name.s) if id == gBackendId: strLit = getStrLit(p.module, field.name.s)
else: strLit = con("TMP", toRope(id)) else: strLit = con("TMP", toRope(id))
if op.magic == mNot: if op.magic == mNot:
lineCg(p, cpsStmts, linefmt(p, cpsStmts,
"if ($1) #raiseFieldError(((#NimStringDesc*) &$2));$n", "if ($1) #raiseFieldError(((#NimStringDesc*) &$2));$n",
[rdLoc(test), strLit]) rdLoc(test), strLit)
else: else:
lineCg(p, cpsStmts, linefmt(p, cpsStmts,
"if (!($1)) #raiseFieldError(((#NimStringDesc*) &$2));$n", "if (!($1)) #raiseFieldError(((#NimStringDesc*) &$2));$n",
[rdLoc(test), strLit]) rdLoc(test), strLit)
appf(r, ".$1", [field.loc.r]) app(r, rfmt(nil, ".$1", field.loc.r))
putIntoDest(p, d, field.typ, r) putIntoDest(p, d, field.typ, r)
else: else:
genRecordField(p, e.sons[0], d) genRecordField(p, e.sons[0], d)
@ -679,18 +679,18 @@ proc genArrayElem(p: BProc, e: PNode, d: var TLoc) =
# semantic pass has already checked for const index expressions # semantic pass has already checked for const index expressions
if firstOrd(ty) == 0: if firstOrd(ty) == 0:
if (firstOrd(b.t) < firstOrd(ty)) or (lastOrd(b.t) > lastOrd(ty)): if (firstOrd(b.t) < firstOrd(ty)) or (lastOrd(b.t) > lastOrd(ty)):
lineCg(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError();$n", linefmt(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError();$n",
[rdCharLoc(b), intLiteral(lastOrd(ty))]) rdCharLoc(b), intLiteral(lastOrd(ty)))
else: else:
lineCg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n", linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n",
[rdCharLoc(b), first, intLiteral(lastOrd(ty))]) rdCharLoc(b), first, intLiteral(lastOrd(ty)))
else: else:
let idx = getOrdValue(e.sons[1]) let idx = getOrdValue(e.sons[1])
if idx < firstOrd(ty) or idx > lastOrd(ty): if idx < firstOrd(ty) or idx > lastOrd(ty):
localError(e.info, errIndexOutOfBounds) localError(e.info, errIndexOutOfBounds)
if d.k == locNone: d.s = a.s if d.k == locNone: d.s = a.s
putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)), putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
ropef("$1[($2)- $3]", [rdLoc(a), rdCharLoc(b), first])) rfmt(nil, "$1[($2)- $3]", rdLoc(a), rdCharLoc(b), first))
proc genCStringElem(p: BProc, e: PNode, d: var TLoc) = proc genCStringElem(p: BProc, e: PNode, d: var TLoc) =
var a, b: TLoc var a, b: TLoc
@ -699,18 +699,18 @@ proc genCStringElem(p: BProc, e: PNode, d: var TLoc) =
var ty = skipTypes(a.t, abstractVarRange) var ty = skipTypes(a.t, abstractVarRange)
if d.k == locNone: d.s = a.s if d.k == locNone: d.s = a.s
putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)), putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
ropef("$1[$2]", [rdLoc(a), rdCharLoc(b)])) rfmt(nil, "$1[$2]", rdLoc(a), rdCharLoc(b)))
proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) = proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) =
var a, b: TLoc var a, b: TLoc
initLocExpr(p, e.sons[0], a) initLocExpr(p, e.sons[0], a)
initLocExpr(p, e.sons[1], b) # emit range check: initLocExpr(p, e.sons[1], b) # emit range check:
if optBoundsCheck in p.options: if optBoundsCheck in p.options:
lineCg(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n", linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n",
[rdLoc(b), rdLoc(a)]) # BUGFIX: ``>=`` and not ``>``! rdLoc(b), rdLoc(a)) # BUGFIX: ``>=`` and not ``>``!
if d.k == locNone: d.s = a.s if d.k == locNone: d.s = a.s
putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)), putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)),
ropef("$1[$2]", [rdLoc(a), rdCharLoc(b)])) rfmt(nil, "$1[$2]", rdLoc(a), rdCharLoc(b)))
proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) = proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) =
var a, b: TLoc var a, b: TLoc
@ -721,18 +721,18 @@ proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) =
ty = skipTypes(ty.sons[0], abstractVarRange) # emit range check: ty = skipTypes(ty.sons[0], abstractVarRange) # emit range check:
if optBoundsCheck in p.options: if optBoundsCheck in p.options:
if ty.kind == tyString: if ty.kind == tyString:
lineCg(p, cpsStmts, linefmt(p, cpsStmts,
"if ((NU)($1) > (NU)($2->$3)) #raiseIndexError();$n", "if ((NU)($1) > (NU)($2->$3)) #raiseIndexError();$n",
[rdLoc(b), rdLoc(a), lenField()]) rdLoc(b), rdLoc(a), lenField())
else: else:
lineCg(p, cpsStmts, linefmt(p, cpsStmts,
"if ((NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n", "if ((NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n",
[rdLoc(b), rdLoc(a), lenField()]) rdLoc(b), rdLoc(a), lenField())
if d.k == locNone: d.s = OnHeap if d.k == locNone: d.s = OnHeap
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}: if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
a.r = ropef("(*$1)", [a.r]) a.r = rfmt(nil, "(*$1)", a.r)
putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)), putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)),
ropef("$1->data[$2]", [rdLoc(a), rdCharLoc(b)])) rfmt(nil, "$1->data[$2]", rdLoc(a), rdCharLoc(b)))
proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) = proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
# how to generate code? # how to generate code?
@ -818,8 +818,8 @@ proc genEcho(p: BProc, n: PNode) =
for i in countup(1, n.len-1): for i in countup(1, n.len-1):
initLocExpr(p, n.sons[i], a) initLocExpr(p, n.sons[i], a)
appf(args, ", ($1)->data", [rdLoc(a)]) appf(args, ", ($1)->data", [rdLoc(a)])
lineCg(p, cpsStmts, "printf($1$2);$n", [ linefmt(p, cpsStmts, "printf($1$2);$n",
makeCString(repeatStr(n.len-1, "%s") & tnl), args]) makeCString(repeatStr(n.len-1, "%s") & tnl), args)
include ccgcalls include ccgcalls
@ -850,14 +850,14 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e.sons[i + 1], a) initLocExpr(p, e.sons[i + 1], a)
if skipTypes(e.sons[i + 1].Typ, abstractVarRange).kind == tyChar: if skipTypes(e.sons[i + 1].Typ, abstractVarRange).kind == tyChar:
Inc(L) Inc(L)
appLineCg(p, appends, "#appendChar($1, $2);$n", [tmp.r, rdLoc(a)]) app(appends, rfmt(p.module, "#appendChar($1, $2);$n", tmp.r, rdLoc(a)))
else: else:
if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}: if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
Inc(L, len(e.sons[i + 1].strVal)) Inc(L, len(e.sons[i + 1].strVal))
else: else:
appf(lens, "$1->$2 + ", [rdLoc(a), lenField()]) appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
appLineCg(p, appends, "#appendString($1, $2);$n", [tmp.r, rdLoc(a)]) app(appends, rfmt(p.module, "#appendString($1, $2);$n", tmp.r, rdLoc(a)))
lineCg(p, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, toRope(L)]) linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", tmp.r, lens, toRope(L))
app(p.s(cpsStmts), appends) app(p.s(cpsStmts), appends)
if d.k == locNone: if d.k == locNone:
d = tmp d = tmp
@ -888,17 +888,17 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e.sons[i + 2], a) initLocExpr(p, e.sons[i + 2], a)
if skipTypes(e.sons[i + 2].Typ, abstractVarRange).kind == tyChar: if skipTypes(e.sons[i + 2].Typ, abstractVarRange).kind == tyChar:
Inc(L) Inc(L)
appLineCg(p, appends, "#appendChar($1, $2);$n", app(appends, rfmt(p.module, "#appendChar($1, $2);$n",
[rdLoc(dest), rdLoc(a)]) rdLoc(dest), rdLoc(a)))
else: else:
if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}: if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}:
Inc(L, len(e.sons[i + 2].strVal)) Inc(L, len(e.sons[i + 2].strVal))
else: else:
appf(lens, "$1->$2 + ", [rdLoc(a), lenField()]) appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
appLineCg(p, appends, "#appendString($1, $2);$n", app(appends, rfmt(p.module, "#appendString($1, $2);$n",
[rdLoc(dest), rdLoc(a)]) rdLoc(dest), rdLoc(a)))
lineCg(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n", linefmt(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
[rdLoc(dest), lens, toRope(L)]) rdLoc(dest), lens, toRope(L))
keepAlive(p, dest) keepAlive(p, dest)
app(p.s(cpsStmts), appends) app(p.s(cpsStmts), appends)
@ -920,14 +920,14 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
getTypeDesc(p.module, skipTypes(e.sons[2].Typ, abstractVar))]) getTypeDesc(p.module, skipTypes(e.sons[2].Typ, abstractVar))])
keepAlive(p, a) keepAlive(p, a)
initLoc(dest, locExpr, b.t, OnHeap) initLoc(dest, locExpr, b.t, OnHeap)
dest.r = ropef("$1->data[$1->$2-1]", [rdLoc(a), lenField()]) dest.r = rfmt(nil, "$1->data[$1->$2-1]", rdLoc(a), lenField())
genAssignment(p, dest, b, {needToCopy, afDestIsNil}) genAssignment(p, dest, b, {needToCopy, afDestIsNil})
proc genReset(p: BProc, n: PNode) = proc genReset(p: BProc, n: PNode) =
var a: TLoc var a: TLoc
InitLocExpr(p, n.sons[1], a) InitLocExpr(p, n.sons[1], a)
lineCg(p, cpsStmts, "#genericReset((void*)$1, $2);$n", linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
[addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, abstractVarRange))]) addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, abstractVarRange)))
proc genNew(p: BProc, e: PNode) = proc genNew(p: BProc, e: PNode) =
var var
@ -942,11 +942,11 @@ proc genNew(p: BProc, e: PNode) =
if a.s == OnHeap and optRefcGc in gGlobalOptions: if a.s == OnHeap and optRefcGc in gGlobalOptions:
# use newObjRC1 as an optimization; and we don't need 'keepAlive' either # use newObjRC1 as an optimization; and we don't need 'keepAlive' either
if canFormAcycle(a.t): if canFormAcycle(a.t):
lineCg(p, cpsStmts, "if ($1) #nimGCunref($1);$n", a.rdLoc) linefmt(p, cpsStmts, "if ($1) #nimGCunref($1);$n", a.rdLoc)
else: else:
lineCg(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", a.rdLoc) linefmt(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", a.rdLoc)
b.r = ropecg(p.module, "($1) #newObjRC1($2, sizeof($3))", args) b.r = ropecg(p.module, "($1) #newObjRC1($2, sizeof($3))", args)
lineCg(p, cpsStmts, "$1 = $2;$n", a.rdLoc, b.rdLoc) linefmt(p, cpsStmts, "$1 = $2;$n", a.rdLoc, b.rdLoc)
else: else:
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", args) b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", args)
genAssignment(p, a, b, {needToKeepAlive}) # set the object type: genAssignment(p, a, b, {needToKeepAlive}) # set the object type:
@ -960,9 +960,9 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: PRope) =
var call: TLoc var call: TLoc
initLoc(call, locExpr, dest.t, OnHeap) initLoc(call, locExpr, dest.t, OnHeap)
if dest.s == OnHeap and optRefcGc in gGlobalOptions: if dest.s == OnHeap and optRefcGc in gGlobalOptions:
lineCg(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", dest.rdLoc) linefmt(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", dest.rdLoc)
call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args) call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args)
lineCg(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc) linefmt(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)
else: else:
call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args) call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args)
genAssignment(p, dest, call, {needToKeepAlive}) genAssignment(p, dest, call, {needToKeepAlive})
@ -981,7 +981,7 @@ proc genSeqConstr(p: BProc, t: PNode, d: var TLoc) =
genNewSeqAux(p, d, intLiteral(sonsLen(t))) genNewSeqAux(p, d, intLiteral(sonsLen(t)))
for i in countup(0, sonsLen(t) - 1): for i in countup(0, sonsLen(t) - 1):
initLoc(arr, locExpr, elemType(skipTypes(t.typ, abstractInst)), OnHeap) initLoc(arr, locExpr, elemType(skipTypes(t.typ, abstractInst)), OnHeap)
arr.r = ropef("$1->data[$2]", [rdLoc(d), intLiteral(i)]) arr.r = rfmt(nil, "$1->data[$2]", rdLoc(d), intLiteral(i))
arr.s = OnHeap # we know that sequences are on the heap arr.s = OnHeap # we know that sequences are on the heap
expr(p, t.sons[i], arr) expr(p, t.sons[i], arr)
@ -1000,10 +1000,10 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
initLocExpr(p, t.sons[1], a) initLocExpr(p, t.sons[1], a)
for i in countup(0, L - 1): for i in countup(0, L - 1):
initLoc(elem, locExpr, elemType(skipTypes(t.typ, abstractInst)), OnHeap) initLoc(elem, locExpr, elemType(skipTypes(t.typ, abstractInst)), OnHeap)
elem.r = ropef("$1->data[$2]", [rdLoc(d), intLiteral(i)]) elem.r = rfmt(nil, "$1->data[$2]", rdLoc(d), intLiteral(i))
elem.s = OnHeap # we know that sequences are on the heap elem.s = OnHeap # we know that sequences are on the heap
initLoc(arr, locExpr, elemType(skipTypes(t.sons[1].typ, abstractInst)), a.s) initLoc(arr, locExpr, elemType(skipTypes(t.sons[1].typ, abstractInst)), a.s)
arr.r = ropef("$1[$2]", [rdLoc(a), intLiteral(i)]) arr.r = rfmt(nil, "$1[$2]", rdLoc(a), intLiteral(i))
genAssignment(p, elem, arr, {afDestIsNil, needToCopy}) genAssignment(p, elem, arr, {afDestIsNil, needToCopy})
proc genNewFinalize(p: BProc, e: PNode) = proc genNewFinalize(p: BProc, e: PNode) =
@ -1034,21 +1034,21 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
var t = skipTypes(a.t, abstractInst) var t = skipTypes(a.t, abstractInst)
while t.kind in {tyVar, tyPtr, tyRef}: while t.kind in {tyVar, tyPtr, tyRef}:
if t.kind != tyVar: nilCheck = r if t.kind != tyVar: nilCheck = r
r = ropef("(*$1)", [r]) r = rfmt(nil, "(*$1)", r)
t = skipTypes(t.sons[0], typedescInst) t = skipTypes(t.sons[0], typedescInst)
if gCmd != cmdCompileToCpp: if gCmd != cmdCompileToCpp:
while (t.kind == tyObject) and (t.sons[0] != nil): while (t.kind == tyObject) and (t.sons[0] != nil):
app(r, ".Sup") app(r, ~".Sup")
t = skipTypes(t.sons[0], typedescInst) t = skipTypes(t.sons[0], typedescInst)
if isObjLackingTypeField(t): if isObjLackingTypeField(t):
GlobalError(x.info, errGenerated, GlobalError(x.info, errGenerated,
"no 'of' operator available for pure objects") "no 'of' operator available for pure objects")
if nilCheck != nil: if nilCheck != nil:
r = ropecg(p.module, "(($1) && #isObj($2.m_type, $3))", r = rfmt(p.module, "(($1) && #isObj($2.m_type, $3))",
[nilCheck, r, genTypeInfo(p.module, dest)]) nilCheck, r, genTypeInfo(p.module, dest))
else: else:
r = ropecg(p.module, "#isObj($1.m_type, $2)", r = rfmt(p.module, "#isObj($1.m_type, $2)",
[r, genTypeInfo(p.module, dest)]) r, genTypeInfo(p.module, dest))
putIntoDest(p, d, getSysType(tyBool), r) putIntoDest(p, d, getSysType(tyBool), r)
proc genOf(p: BProc, n: PNode, d: var TLoc) = proc genOf(p: BProc, n: PNode, d: var TLoc) =
@ -1365,11 +1365,11 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""): elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""):
initLocExpr(p, e.sons[2], x) initLocExpr(p, e.sons[2], x)
putIntoDest(p, d, e.typ, putIntoDest(p, d, e.typ,
ropef("(($1) && ($1)->$2 == 0)", [rdLoc(x), lenField()])) rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField()))
elif (b.kind in {nkStrLit..nkTripleStrLit}) and (b.strVal == ""): elif (b.kind in {nkStrLit..nkTripleStrLit}) and (b.strVal == ""):
initLocExpr(p, e.sons[1], x) initLocExpr(p, e.sons[1], x)
putIntoDest(p, d, e.typ, putIntoDest(p, d, e.typ,
ropef("(($1) && ($1)->$2 == 0)", [rdLoc(x), lenField()])) rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField()))
else: else:
binaryExpr(p, e, d, "#eqStrings($1, $2)") binaryExpr(p, e, d, "#eqStrings($1, $2)")
@ -1381,12 +1381,12 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
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)
putIntoDest(p, d, e.typ, ropef("($2 $1 $3)", [ putIntoDest(p, d, e.typ, rfmt(nil, "($2 $1 $3)",
toRope(opr[m]), rdLoc(a), rdLoc(b)])) toRope(opr[m]), rdLoc(a), rdLoc(b)))
if optNanCheck in p.options: if optNanCheck in p.options:
lineCg(p, cpsStmts, "#nanCheck($1);$n", [rdLoc(d)]) linefmt(p, cpsStmts, "#nanCheck($1);$n", rdLoc(d))
if optInfCheck in p.options: if optInfCheck in p.options:
lineCg(p, cpsStmts, "#infCheck($1);$n", [rdLoc(d)]) linefmt(p, cpsStmts, "#infCheck($1);$n", rdLoc(d))
else: else:
binaryArith(p, e, d, m) binaryArith(p, e, d, m)
@ -1577,8 +1577,8 @@ proc genClosure(p: BProc, n: PNode, d: var TLoc) =
initLocExpr(p, n.sons[0], a) initLocExpr(p, n.sons[0], a)
initLocExpr(p, n.sons[1], b) initLocExpr(p, n.sons[1], b)
getTemp(p, n.typ, tmp) getTemp(p, n.typ, tmp)
lineCg(p, cpsStmts, "$1.ClPrc = $2; $1.ClEnv = $3;$n", linefmt(p, cpsStmts, "$1.ClPrc = $2; $1.ClEnv = $3;$n",
tmp.rdLoc, a.rdLoc, b.rdLoc) tmp.rdLoc, a.rdLoc, b.rdLoc)
putLocIntoDest(p, d, tmp) putLocIntoDest(p, d, tmp)
proc genArrayConstr(p: BProc, n: PNode, d: var TLoc) = proc genArrayConstr(p: BProc, n: PNode, d: var TLoc) =
@ -1617,11 +1617,11 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
app(r, ".Sup") app(r, ".Sup")
t = skipTypes(t.sons[0], abstractInst) t = skipTypes(t.sons[0], abstractInst)
if nilCheck != nil: if nilCheck != nil:
lineCg(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n", linefmt(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n",
[nilCheck, r, genTypeInfo(p.module, dest)]) nilCheck, r, genTypeInfo(p.module, dest))
else: else:
lineCg(p, cpsStmts, "#chckObj($1.m_type, $2);$n", linefmt(p, cpsStmts, "#chckObj($1.m_type, $2);$n",
[r, genTypeInfo(p.module, dest)]) r, genTypeInfo(p.module, dest))
if n.sons[0].typ.kind != tyObject: if n.sons[0].typ.kind != tyObject:
putIntoDest(p, d, n.typ, putIntoDest(p, d, n.typ,
ropef("(($1) ($2))", [getTypeDesc(p.module, n.typ), rdLoc(a)])) ropef("(($1) ($2))", [getTypeDesc(p.module, n.typ), rdLoc(a)]))

View file

@ -75,7 +75,7 @@ proc endBlock(p: BProc, blockEnd: PRope) =
proc endBlock(p: BProc) = proc endBlock(p: BProc) =
let topBlock = p.blocks.len - 1 let topBlock = p.blocks.len - 1
let blockEnd = if p.blocks[topBlock].label != nil: let blockEnd = if p.blocks[topBlock].label != nil:
ropef("} $1: ;$n", [p.blocks[topBlock].label]) rfmt(nil, "} $1: ;$n", p.blocks[topBlock].label)
else: else:
~"}$n" ~"}$n"
endBlock(p, blockEnd) endBlock(p, blockEnd)
@ -93,7 +93,7 @@ template preserveBreakIdx(body: stmt): stmt {.immediate.} =
proc genState(p: BProc, n: PNode) = proc genState(p: BProc, n: PNode) =
internalAssert n.len == 1 and n.sons[0].kind == nkIntLit internalAssert n.len == 1 and n.sons[0].kind == nkIntLit
let idx = n.sons[0].intVal let idx = n.sons[0].intVal
lineCg(p, cpsStmts, "STATE$1: ;$n", [idx.toRope]) linefmt(p, cpsStmts, "STATE$1: ;$n", idx.toRope)
proc genGotoState(p: BProc, n: PNode) = proc genGotoState(p: BProc, n: PNode) =
# we resist the temptation to translate it into duff's device as it later # we resist the temptation to translate it into duff's device as it later
@ -242,7 +242,7 @@ proc blockLeaveActions(p: BProc, howMany: int) =
if alreadyPoppedCnt > 0: if alreadyPoppedCnt > 0:
dec alreadyPoppedCnt dec alreadyPoppedCnt
else: else:
lineCg(p, cpsStmts, "#popSafePoint();$n", []) linefmt(p, cpsStmts, "#popSafePoint();$n")
var finallyStmt = lastSon(tryStmt) var finallyStmt = lastSon(tryStmt)
if finallyStmt.kind == nkFinally: if finallyStmt.kind == nkFinally:
genStmts(p, finallyStmt.sons[0]) genStmts(p, finallyStmt.sons[0])
@ -251,7 +251,7 @@ proc blockLeaveActions(p: BProc, howMany: int) =
p.nestedTryStmts.add(stack[i]) p.nestedTryStmts.add(stack[i])
if gCmd != cmdCompileToCpp: if gCmd != cmdCompileToCpp:
for i in countdown(p.inExceptBlock-1, 0): for i in countdown(p.inExceptBlock-1, 0):
lineCg(p, cpsStmts, "#popCurrentException();$n", []) linefmt(p, cpsStmts, "#popCurrentException();$n")
proc genReturnStmt(p: BProc, t: PNode) = proc genReturnStmt(p: BProc, t: PNode) =
p.beforeRetNeeded = true p.beforeRetNeeded = true
@ -281,7 +281,7 @@ proc genWhileStmt(p: BProc, t: PNode) =
if optProfiler in p.options: if optProfiler in p.options:
# invoke at loop body exit: # invoke at loop body exit:
lineCg(p, cpsStmts, "#nimProfile();$n") linefmt(p, cpsStmts, "#nimProfile();$n")
endBlock(p) endBlock(p)
dec(p.withinLoop) dec(p.withinLoop)
@ -369,9 +369,9 @@ proc genRaiseStmt(p: BProc, t: PNode) =
genLineDir(p, t) genLineDir(p, t)
# reraise the last exception: # reraise the last exception:
if gCmd == cmdCompileToCpp: if gCmd == cmdCompileToCpp:
lineCg(p, cpsStmts, "throw;$n") line(p, cpsStmts, ~"throw;$n")
else: else:
lineCg(p, cpsStmts, "#reraiseException();$n") linefmt(p, cpsStmts, "#reraiseException();$n")
proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc, proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
rangeFormat, eqFormat: TFormatStr, labl: TLabel) = rangeFormat, eqFormat: TFormatStr, labl: TLabel) =
@ -458,8 +458,8 @@ proc genStringCase(p: BProc, t: PNode) =
else: else:
# else statement: nothing to do yet # else statement: nothing to do yet
# but we reserved a label, which we use later # but we reserved a label, which we use later
lineCg(p, cpsStmts, "switch (#hashString($1) & $2) {$n", linefmt(p, cpsStmts, "switch (#hashString($1) & $2) {$n",
[rdLoc(a), toRope(bitMask)]) rdLoc(a), toRope(bitMask))
for j in countup(0, high(branches)): for j in countup(0, high(branches)):
when false: when false:
let interior = cast[int](interiorAllocatedPtr(addr(branches[0])))+ let interior = cast[int](interiorAllocatedPtr(addr(branches[0])))+
@ -598,7 +598,7 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
length = sonsLen(t) length = sonsLen(t)
endBlock(p, ropecg(p.module, "} catch (NimException& $1) {$n", [exc])) endBlock(p, ropecg(p.module, "} catch (NimException& $1) {$n", [exc]))
if optStackTrace in p.Options: if optStackTrace in p.Options:
lineCg(p, cpsStmts, "#setFrame((TFrame*)&F);$n") linefmt(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
inc p.inExceptBlock inc p.inExceptBlock
i = 1 i = 1
var catchAllPresent = false var catchAllPresent = false
@ -629,7 +629,7 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
var finallyBlock = t.lastSon var finallyBlock = t.lastSon
if finallyBlock.kind == nkFinally: if finallyBlock.kind == nkFinally:
genStmts(p, finallyBlock.sons[0]) genStmts(p, finallyBlock.sons[0])
lineCg(p, cpsStmts, "throw;$n") line(p, cpsStmts, ~"throw;$n")
endBlock(p) endBlock(p)
lineF(p, cpsStmts, "}$n") # end of catch block lineF(p, cpsStmts, "}$n") # end of catch block
@ -671,19 +671,19 @@ proc genTryStmt(p: BProc, t: PNode) =
genLineDir(p, t) genLineDir(p, t)
var safePoint = getTempName() var safePoint = getTempName()
discard cgsym(p.module, "E_Base") discard cgsym(p.module, "E_Base")
lineCg(p, cpsLocals, "#TSafePoint $1;$n", [safePoint]) linefmt(p, cpsLocals, "#TSafePoint $1;$n", safePoint)
lineCg(p, cpsStmts, "#pushSafePoint(&$1);$n", [safePoint]) linefmt(p, cpsStmts, "#pushSafePoint(&$1);$n", safePoint)
lineF(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint]) linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
startBlock(p, "if ($1.status == 0) {$n", [safePoint]) startBlock(p, "if ($1.status == 0) {$n", [safePoint])
var length = sonsLen(t) var length = sonsLen(t)
add(p.nestedTryStmts, t) add(p.nestedTryStmts, t)
genStmts(p, t.sons[0]) genStmts(p, t.sons[0])
linecg(p, cpsStmts, "#popSafePoint();$n") linefmt(p, cpsStmts, "#popSafePoint();$n")
endBlock(p) endBlock(p)
startBlock(p, "else {$n") startBlock(p, "else {$n")
lineCg(p, cpsStmts, "#popSafePoint();$n") linefmt(p, cpsStmts, "#popSafePoint();$n")
if optStackTrace in p.Options: if optStackTrace in p.Options:
lineCg(p, cpsStmts, "#setFrame((TFrame*)&F);$n") linefmt(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
inc p.inExceptBlock inc p.inExceptBlock
var i = 1 var i = 1
while (i < length) and (t.sons[i].kind == nkExceptBranch): while (i < length) and (t.sons[i].kind == nkExceptBranch):
@ -692,9 +692,9 @@ proc genTryStmt(p: BProc, t: PNode) =
# general except section: # general except section:
if i > 1: lineF(p, cpsStmts, "else") if i > 1: lineF(p, cpsStmts, "else")
startBlock(p) startBlock(p)
lineCg(p, cpsStmts, "$1.status = 0;$n", [safePoint]) linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
genStmts(p, t.sons[i].sons[0]) genStmts(p, t.sons[i].sons[0])
lineCg(p, cpsStmts, "#popCurrentException();$n") linefmt(p, cpsStmts, "#popCurrentException();$n")
endBlock(p) endBlock(p)
else: else:
var orExpr: PRope = nil var orExpr: PRope = nil
@ -706,9 +706,9 @@ proc genTryStmt(p: BProc, t: PNode) =
[genTypeInfo(p.module, t.sons[i].sons[j].typ)]) [genTypeInfo(p.module, t.sons[i].sons[j].typ)])
if i > 1: line(p, cpsStmts, "else ") if i > 1: line(p, cpsStmts, "else ")
startBlock(p, "if ($1) {$n", [orExpr]) startBlock(p, "if ($1) {$n", [orExpr])
lineCg(p, cpsStmts, "$1.status = 0;$n", [safePoint]) linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
genStmts(p, t.sons[i].sons[blen-1]) genStmts(p, t.sons[i].sons[blen-1])
lineCg(p, cpsStmts, "#popCurrentException();$n") linefmt(p, cpsStmts, "#popCurrentException();$n")
endBlock(p) endBlock(p)
inc(i) inc(i)
dec p.inExceptBlock dec p.inExceptBlock
@ -716,7 +716,7 @@ proc genTryStmt(p: BProc, t: PNode) =
endBlock(p) # end of else block endBlock(p) # end of else block
if i < length and t.sons[i].kind == nkFinally: if i < length and t.sons[i].kind == nkFinally:
genSimpleBlock(p, t.sons[i].sons[0]) genSimpleBlock(p, t.sons[i].sons[0])
lineCg(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint]) linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", safePoint)
proc genAsmOrEmitStmt(p: BProc, t: PNode): PRope = proc genAsmOrEmitStmt(p: BProc, t: PNode): PRope =
for i in countup(0, sonsLen(t) - 1): for i in countup(0, sonsLen(t) - 1):

View file

@ -65,9 +65,9 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
let arraySize = lengthOrd(typ.sons[0]) let arraySize = lengthOrd(typ.sons[0])
var i: TLoc var i: TLoc
getTemp(p, getSysType(tyInt), i) getTemp(p, getSysType(tyInt), i)
lineF(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n", linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
i.r, arraySize.toRope) i.r, arraySize.toRope)
genTraverseProc(c, ropef("$1[$2]", accessor, i.r), typ.sons[1]) genTraverseProc(c, rfmt(nil, "$1[$2]", accessor, i.r), typ.sons[1])
lineF(p, cpsStmts, "}$n") lineF(p, cpsStmts, "}$n")
of tyObject: of tyObject:
for i in countup(0, sonsLen(typ) - 1): for i in countup(0, sonsLen(typ) - 1):
@ -76,12 +76,12 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
of tyTuple: of tyTuple:
let typ = GetUniqueType(typ) let typ = GetUniqueType(typ)
for i in countup(0, sonsLen(typ) - 1): for i in countup(0, sonsLen(typ) - 1):
genTraverseProc(c, ropef("$1.Field$2", accessor, i.toRope), typ.sons[i]) genTraverseProc(c, rfmt(nil, "$1.Field$2", accessor, i.toRope), typ.sons[i])
of tyRef, tyString, tySequence: of tyRef, tyString, tySequence:
lineCg(p, cpsStmts, c.visitorFrmt, accessor) lineCg(p, cpsStmts, c.visitorFrmt, accessor)
of tyProc: of tyProc:
if typ.callConv == ccClosure: if typ.callConv == ccClosure:
lineCg(p, cpsStmts, c.visitorFrmt, ropef("$1.ClEnv", accessor)) lineCg(p, cpsStmts, c.visitorFrmt, rfmt(nil, "$1.ClEnv", accessor))
else: else:
nil nil

View file

@ -126,13 +126,13 @@ proc mangleName(s: PSym): PRope =
# These are not properly scoped now - we need to add blocks # These are not properly scoped now - we need to add blocks
# around for loops in transf # around for loops in transf
if keepOrigName: if keepOrigName:
result = s.name.s.mangle.toRope result = s.name.s.mangle.newRope
else: else:
app(result, toRope(mangle(s.name.s))) app(result, newRope(mangle(s.name.s)))
app(result, ~"_") app(result, ~"_")
app(result, toRope(s.id)) app(result, toRope(s.id))
else: else:
app(result, toRope(mangle(s.name.s))) app(result, newRope(mangle(s.name.s)))
app(result, ~"_") app(result, ~"_")
app(result, toRope(s.id)) app(result, toRope(s.id))
s.loc.r = result s.loc.r = result

View file

@ -133,73 +133,79 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope =
if i - 1 >= start: if i - 1 >= start:
app(result, substr(frmt, start, i - 1)) app(result, substr(frmt, start, i - 1))
import macros const compileTimeRopeFmt = not defined(booting)
type TFmtFragmentKind = enum when compileTimeRopeFmt:
ffSym, import macros
ffLit,
ffParam
type TFragment = object type TFmtFragmentKind = enum
case kind: TFmtFragmentKind ffSym,
of ffSym, ffLit: ffLit,
value: string ffParam
of ffParam:
intValue: int
iterator fmtStringFragments(s: string): tuple[kind: TFmtFragmentKind, type TFragment = object
value: string, case kind: TFmtFragmentKind
intValue: int] = of ffSym, ffLit:
# This is a bit less featured version of the ropecg's algorithm value: string
# (be careful when replacing ropecg calls) of ffParam:
var intValue: int
i = 0
length = s.len
while i < length: iterator fmtStringFragments(s: string): tuple[kind: TFmtFragmentKind,
var start = i value: string,
case s[i] intValue: int] =
of '$': # This is a bit less featured version of the ropecg's algorithm
let n = s[i+1] # (be careful when replacing ropecg calls)
case n var
of '$': i = 0
inc i, 2 length = s.len
of '0'..'9':
# XXX: use the new case object construction syntax when it's ready
yield (kind: ffParam, value: "", intValue: n.ord - ord('1'))
inc i, 2
start = i
else:
inc i
of '#':
inc i
var j = i
while s[i] in IdentChars: inc i
yield (kind: ffSym, value: substr(s, j, i-1), intValue: 0)
start = i
else: nil
while i < length: while i < length:
if s[i] != '$' and s[i] != '#': inc i var start = i
else: break case s[i]
of '$':
let n = s[i+1]
case n
of '$':
inc i, 2
of '0'..'9':
# XXX: use the new case object construction syntax when it's ready
yield (kind: ffParam, value: "", intValue: n.ord - ord('1'))
inc i, 2
start = i
else:
inc i
of '#':
inc i
var j = i
while s[i] in IdentChars: inc i
yield (kind: ffSym, value: substr(s, j, i-1), intValue: 0)
start = i
else: nil
if i - 1 >= start: while i < length:
yield (kind: ffLit, value: substr(s, start, i-1), intValue: 0) if s[i] != '$' and s[i] != '#': inc i
else: break
macro rfmt(m: BModule, fmt: expr[string], args: varargs[PRope]): expr = if i - 1 >= start:
## Experimental optimized rope-formatting operator yield (kind: ffLit, value: substr(s, start, i-1), intValue: 0)
## The run-time code it produces will be very fast, but will it speed up
## the compilation of nimrod itself or will the macro execution time macro rfmt(m: BModule, fmt: expr[string], args: varargs[PRope]): expr =
## offset the gains? ## Experimental optimized rope-formatting operator
result = newCall(bindSym"ropeConcat") ## The run-time code it produces will be very fast, but will it speed up
for frag in fmtStringFragments(fmt.strVal): ## the compilation of nimrod itself or will the macro execution time
case frag.kind ## offset the gains?
of ffSym: result = newCall(bindSym"ropeConcat")
result.add(newCall(bindSym"cgsym", m, newStrLitNode(frag.value))) for frag in fmtStringFragments(fmt.strVal):
of ffLit: case frag.kind
result.add(newCall(bindSym"~", newStrLitNode(frag.value))) of ffSym:
of ffParam: result.add(newCall(bindSym"cgsym", m, newStrLitNode(frag.value)))
result.add(args[frag.intValue]) of ffLit:
result.add(newCall(bindSym"~", newStrLitNode(frag.value)))
of ffParam:
result.add(args[frag.intValue])
else:
template rfmt(m: BModule, fmt: expr[string], args: varargs[PRope]): expr =
ropecg(m, fmt, args)
proc appcg(m: BModule, c: var PRope, frmt: TFormatStr, proc appcg(m: BModule, c: var PRope, frmt: TFormatStr,
args: varargs[PRope]) = args: varargs[PRope]) =
@ -232,9 +238,14 @@ proc lineCg(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: varargs[PRope]) = args: varargs[PRope]) =
app(p.s(s), indentLine(p, ropecg(p.module, frmt, args))) app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
template lineCg2(p: BProc, s: TCProcSection, frmt: TFormatStr, when compileTimeRopeFmt:
args: varargs[PRope]) = template linefmt(p: BProc, s: TCProcSection, frmt: TFormatStr,
line(p, s, rfmt(p.module, frmt, args)) args: varargs[PRope]) =
line(p, s, rfmt(p.module, frmt, args))
else:
proc linefmt(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: varargs[PRope]) =
app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
proc appLineCg(p: BProc, r: var PRope, frmt: TFormatStr, proc appLineCg(p: BProc, r: var PRope, frmt: TFormatStr,
args: varargs[PRope]) = args: varargs[PRope]) =
@ -263,7 +274,7 @@ 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):
lineCg(p, cpsStmts, "#endb($1);$n", [toRope(line)]) linefmt(p, cpsStmts, "#endb($1);$n", toRope(line))
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): (p.prc == nil or sfPure notin p.prc.flags):
@ -303,11 +314,11 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
while (s.kind == tyObject) and (s.sons[0] != nil): while (s.kind == tyObject) and (s.sons[0] != nil):
app(r, ".Sup") app(r, ".Sup")
s = skipTypes(s.sons[0], abstractInst) s = skipTypes(s.sons[0], abstractInst)
lineCg2(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t)) linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t))
of frEmbedded: of frEmbedded:
# worst case for performance: # worst case for performance:
var r = if takeAddr: addrLoc(a) else: rdLoc(a) var r = if takeAddr: addrLoc(a) else: rdLoc(a)
lineCg2(p, section, "#objectInit($1, $2);$n", r, genTypeInfo(p.module, t)) linefmt(p, section, "#objectInit($1, $2);$n", r, genTypeInfo(p.module, t))
type type
TAssignmentFlag = enum TAssignmentFlag = enum
@ -330,16 +341,16 @@ proc resetLoc(p: BProc, loc: var TLoc) =
nilLoc.r = toRope("NIM_NIL") nilLoc.r = toRope("NIM_NIL")
genRefAssign(p, loc, nilLoc, {afSrcIsNil}) genRefAssign(p, loc, nilLoc, {afSrcIsNil})
else: else:
lineCg2(p, cpsStmts, "$1 = 0;$n", rdLoc(loc)) linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc))
else: else:
if loc.s != OnStack: if loc.s != OnStack:
lineCg2(p, cpsStmts, "#genericReset((void*)$1, $2);$n", linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
addrLoc(loc), genTypeInfo(p.module, loc.t)) addrLoc(loc), genTypeInfo(p.module, loc.t))
# XXX: generated reset procs should not touch the m_type # XXX: generated reset procs should not touch the m_type
# field, so disabling this should be safe: # field, so disabling this should be safe:
genObjectInit(p, cpsStmts, loc.t, loc, true) genObjectInit(p, cpsStmts, loc.t, loc, true)
else: else:
lineCg2(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n",
addrLoc(loc), rdLoc(loc)) addrLoc(loc), rdLoc(loc))
# XXX: We can be extra clever here and call memset only # XXX: We can be extra clever here and call memset only
# on the bytes following the m_type field? # on the bytes following the m_type field?
@ -347,9 +358,9 @@ proc resetLoc(p: BProc, loc: var TLoc) =
proc constructLoc(p: BProc, loc: TLoc, section = cpsStmts) = proc constructLoc(p: BProc, loc: TLoc, section = cpsStmts) =
if not isComplexValueType(skipTypes(loc.t, abstractRange)): if not isComplexValueType(skipTypes(loc.t, abstractRange)):
lineCg2(p, section, "$1 = 0;$n", rdLoc(loc)) linefmt(p, section, "$1 = 0;$n", rdLoc(loc))
else: else:
lineCg2(p, section, "memset((void*)$1, 0, sizeof($2));$n", linefmt(p, section, "memset((void*)$1, 0, sizeof($2));$n",
addrLoc(loc), rdLoc(loc)) addrLoc(loc), rdLoc(loc))
genObjectInit(p, section, loc.t, loc, true) genObjectInit(p, section, loc.t, loc, true)
@ -377,7 +388,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) =
result.r = con("%LOC", toRope(p.labels)) result.r = con("%LOC", toRope(p.labels))
else: else:
result.r = con("LOC", toRope(p.labels)) result.r = con("LOC", toRope(p.labels))
lineCg2(p, cpsLocals, "$1 $2;$n", getTypeDesc(p.module, t), result.r) linefmt(p, cpsLocals, "$1 $2;$n", getTypeDesc(p.module, t), result.r)
result.k = locTemp result.k = locTemp
result.a = - 1 result.a = - 1
result.t = getUniqueType(t) result.t = getUniqueType(t)
@ -403,9 +414,9 @@ proc keepAlive(p: BProc, toKeepAlive: TLoc) =
result.flags = {} result.flags = {}
if not isComplexValueType(skipTypes(toKeepAlive.t, abstractVarRange)): if not isComplexValueType(skipTypes(toKeepAlive.t, abstractVarRange)):
lineCg2(p, cpsStmts, "$1 = $2;$n", rdLoc(result), rdLoc(toKeepAlive)) linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(result), rdLoc(toKeepAlive))
else: else:
lineCg2(p, cpsStmts, linefmt(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
addrLoc(result), addrLoc(toKeepAlive), rdLoc(result)) addrLoc(result), addrLoc(toKeepAlive), rdLoc(result))
@ -714,7 +725,7 @@ proc initFrame(p: BProc, procname, filename: PRope): PRope =
"\t#pushFrame((TFrame*)&F);$n", [procname, filename]) "\t#pushFrame((TFrame*)&F);$n", [procname, filename])
proc deinitFrame(p: BProc): PRope = proc deinitFrame(p: BProc): PRope =
result = ropecg(p.module, "\t#popFrame();$n") result = rfmt(p.module, "\t#popFrame();$n")
proc closureSetup(p: BProc, prc: PSym) = proc closureSetup(p: BProc, prc: PSym) =
if tfCapturesEnv notin prc.typ.flags: return if tfCapturesEnv notin prc.typ.flags: return
@ -726,8 +737,8 @@ proc closureSetup(p: BProc, prc: PSym) =
#echo "created environment: ", env.id, " for ", prc.name.s #echo "created environment: ", env.id, " for ", prc.name.s
assignLocalVar(p, env) assignLocalVar(p, env)
# generate cast assignment: # generate cast assignment:
lineCg(p, cpsStmts, "$1 = ($2) ClEnv;$n", rdLoc(env.loc), linefmt(p, cpsStmts, "$1 = ($2) ClEnv;$n",
getTypeDesc(p.module, env.typ)) rdLoc(env.loc), getTypeDesc(p.module, env.typ))
proc genProcAux(m: BModule, prc: PSym) = proc genProcAux(m: BModule, prc: PSym) =
var p = newProc(prc, m) var p = newProc(prc, m)
@ -741,7 +752,7 @@ proc genProcAux(m: BModule, prc: PSym) =
# declare the result symbol: # declare the result symbol:
assignLocalVar(p, res) assignLocalVar(p, res)
assert(res.loc.r != nil) assert(res.loc.r != nil)
returnStmt = ropeff("\treturn $1;$n", "ret $1$n", [rdLoc(res.loc)]) returnStmt = rfmt(nil, "\treturn $1;$n", rdLoc(res.loc))
initLocalVar(p, res, immediateAsgn=false) initLocalVar(p, res, immediateAsgn=false)
else: else:
fillResult(res) fillResult(res)
@ -757,10 +768,10 @@ proc genProcAux(m: BModule, prc: PSym) =
genStmts(p, prc.getBody) # modifies p.locals, p.init, etc. genStmts(p, prc.getBody) # modifies p.locals, p.init, etc.
var generatedProc: PRope var generatedProc: PRope
if sfPure in prc.flags: if sfPure in prc.flags:
generatedProc = ropeff("$N$1 {$n$2$3$4}$N$N", "define $1 {$n$2$3$4}$N", generatedProc = rfmt(nil, "$N$1 {$n$2$3$4}$N$N",
[header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)]) header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts))
else: else:
generatedProc = ropeff("$N$1 {$N", "$Ndefine $1 {$N", [header]) generatedProc = rfmt(nil, "$N$1 {$N", header)
app(generatedProc, initGCFrame(p)) app(generatedProc, initGCFrame(p))
if optStackTrace in prc.options: if optStackTrace in prc.options:
getFrameDecl(p) getFrameDecl(p)
@ -775,11 +786,11 @@ proc genProcAux(m: BModule, prc: PSym) =
appcg(p, cpsInit, "\t#nimProfile();$n", []) appcg(p, cpsInit, "\t#nimProfile();$n", [])
app(generatedProc, p.s(cpsInit)) app(generatedProc, p.s(cpsInit))
app(generatedProc, p.s(cpsStmts)) app(generatedProc, p.s(cpsStmts))
if p.beforeRetNeeded: appf(generatedProc, "\tBeforeRet: ;$n") if p.beforeRetNeeded: app(generatedProc, ~"\tBeforeRet: ;$n")
app(generatedProc, deinitGCFrame(p)) app(generatedProc, deinitGCFrame(p))
if optStackTrace in prc.options: app(generatedProc, deinitFrame(p)) if optStackTrace in prc.options: app(generatedProc, deinitFrame(p))
app(generatedProc, returnStmt) app(generatedProc, returnStmt)
appf(generatedProc, "}$N") app(generatedProc, ~"}$N")
app(m.s[cfsProcs], generatedProc) app(m.s[cfsProcs], generatedProc)
proc genProcPrototype(m: BModule, sym: PSym) = proc genProcPrototype(m: BModule, sym: PSym) =
@ -788,11 +799,11 @@ proc genProcPrototype(m: BModule, sym: PSym) =
if lfDynamicLib in sym.loc.Flags: if lfDynamicLib in sym.loc.Flags:
if getModule(sym).id != m.module.id and if getModule(sym).id != m.module.id and
not ContainsOrIncl(m.declaredThings, sym.id): not ContainsOrIncl(m.declaredThings, sym.id):
appf(m.s[cfsVars], "extern $1 $2;$n", app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
[getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)]) getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect) if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
elif not ContainsOrIncl(m.declaredProtos, sym.id): elif not ContainsOrIncl(m.declaredProtos, sym.id):
appf(m.s[cfsProcHeaders], "$1;$n", [genProcHeader(m, sym)]) app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", genProcHeader(m, sym)))
proc genProcNoForward(m: BModule, prc: PSym) = proc genProcNoForward(m: BModule, prc: PSym) =
fillProcLoc(prc) fillProcLoc(prc)

View file

@ -504,5 +504,6 @@ proc MainCommand =
echo "rope cache stats: " echo "rope cache stats: "
echo " tries : ", gCacheTries echo " tries : ", gCacheTries
echo " misses: ", gCacheMisses echo " misses: ", gCacheMisses
echo " int tries: ", gCacheIntTries
echo " efficiency: ", formatFloat(1-(gCacheMisses.float/gCacheTries.float), ffDecimal, 3) echo " efficiency: ", formatFloat(1-(gCacheMisses.float/gCacheTries.float), ffDecimal, 3)

View file

@ -96,7 +96,7 @@ proc ropeLen(a: PRope): int =
if a == nil: result = 0 if a == nil: result = 0
else: result = a.length else: result = a.length
proc newRope(data: string = nil): PRope = proc newRope*(data: string = nil): PRope =
new(result) new(result)
if data != nil: if data != nil:
result.length = len(data) result.length = len(data)
@ -129,6 +129,7 @@ proc RopeInvariant(r: PRope): bool =
var gCacheTries* = 0 var gCacheTries* = 0
var gCacheMisses* = 0 var gCacheMisses* = 0
var gCacheIntTries* = 0
proc insertInCache(s: string): PRope = proc insertInCache(s: string): PRope =
inc gCacheTries inc gCacheTries
@ -195,7 +196,9 @@ proc ropeConcat*(a: varargs[PRope]): PRope =
# not overloaded version of concat to speed-up `rfmt` a little bit # not overloaded version of concat to speed-up `rfmt` a little bit
for i in countup(0, high(a)): result = con(result, a[i]) for i in countup(0, high(a)): result = con(result, a[i])
proc toRope(i: BiggestInt): PRope = result = toRope($i) proc toRope(i: BiggestInt): PRope =
inc gCacheIntTries
result = toRope($i)
proc app(a: var PRope, b: PRope) = a = con(a, b) proc app(a: var PRope, b: PRope) = a = con(a, b)
proc app(a: var PRope, b: string) = a = con(a, b) proc app(a: var PRope, b: string) = a = con(a, b)