summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2012-11-21 23:23:37 +0200
committerZahary Karadjov <zahary@gmail.com>2012-11-28 01:15:14 +0200
commita42545ea3eecb57eea3d02c624b91c86bdaf90e6 (patch)
treecf300e37233d7cf8968396f92405f280f3c3739c
parente817d543696677e277260819d50549e11f570a19 (diff)
downloadNim-a42545ea3eecb57eea3d02c624b91c86bdaf90e6.tar.gz
disables the compile-time rope formatting during bootstrapping
-rwxr-xr-xcompiler/ccgexprs.nim180
-rwxr-xr-xcompiler/ccgstmts.nim44
-rw-r--r--compiler/ccgtrav.nim10
-rwxr-xr-xcompiler/ccgtypes.nim6
-rwxr-xr-xcompiler/cgen.nim191
-rwxr-xr-xcompiler/main.nim1
-rwxr-xr-xcompiler/ropes.nim7
7 files changed, 227 insertions, 212 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 5f8f2d5ae..ddc93d5a3 100755
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -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, '$1 = $2;$n', [rdLoc(dest), rdLoc(src)])
     if canFormAcycle(dest.t):
-      lineCg2(p, cpsStmts, "#asgnRef((void**) $1, $2);$n",
+      linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);$n",
               addrLoc(dest), rdLoc(src))
     else:
-      lineCg2(p, cpsStmts, "#asgnRefNoCycle((void**) $1, $2);$n",
+      linefmt(p, cpsStmts, "#asgnRefNoCycle((void**) $1, $2);$n",
               addrLoc(dest), rdLoc(src))
   else:
-    lineCg2(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n",
+    linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n",
             addrLoc(dest), rdLoc(src))
     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 
       tfShallow in skipTypes(dest.t, abstractVarRange).flags:
     if dest.s == OnStack or optRefcGC notin gGlobalOptions:
-      lineCg2(p, cpsStmts,
+      linefmt(p, cpsStmts,
            "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
            addrLoc(dest), addrLoc(src), rdLoc(dest))
       if needToKeepAlive in flags: keepAlive(p, dest)
     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))
   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))
 
 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.
   if src.t != nil and src.t.kind == tyPtr:
     # 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
   var ty = skipTypes(dest.t, abstractRange)
   case ty.kind
@@ -231,24 +231,24 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
     if needToCopy notin flags:
       genRefAssign(p, dest, src, flags)
     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))
   of tyString:
     if needToCopy notin flags:
       genRefAssign(p, dest, src, flags)
     else:
       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)
       elif dest.s == OnHeap:
         # we use a temporary to care for the dreaded self assignment:
         var tmp: TLoc
         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)
-        lineCg(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", tmp.rdLoc)
+        linefmt(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", tmp.rdLoc)
       else:
-        lineCg2(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n",
+        linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n",
                addrLoc(dest), rdLoc(src))
         if needToKeepAlive in flags: keepAlive(p, dest)
   of tyTuple, tyObject, tyProc:
@@ -256,34 +256,34 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
     if needsComplexAssignment(dest.t):
       genGenericAsgn(p, dest, src, flags)
     else:
-      lineCg2(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
+      linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
   of tyArray, tyArrayConstr:
     if needsComplexAssignment(dest.t):
       genGenericAsgn(p, dest, src, flags)
     else:
-      lineCg2(p, cpsStmts,
+      linefmt(p, cpsStmts,
            "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1));$n",
            rdLoc(dest), rdLoc(src))
   of tyOpenArray, tyVarargs:
     # open arrays are always on the stack - really? What if a sequence is
     # passed to an open array?
     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",
            addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
     else:
-      lineCg2(p, cpsStmts,
+      linefmt(p, cpsStmts,
            "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len0);$n",
            rdLoc(dest), rdLoc(src))
   of tySet:
     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)))
     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,
      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 & ')')
 
 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:
       storage = getTypeDesc(p.module, t)
     var tmp = getTempName()
-    lineCg(p, cpsLocals, "$1 $2;$n", [storage, tmp])
-    lineCg(p, cpsStmts, "$1 = #$2($3, $4);$n", [tmp, toRope(prc[m]), 
-                                             rdLoc(a), rdLoc(b)])
+    linefmt(p, cpsLocals, "$1 $2;$n", storage, tmp)
+    lineCg(p, cpsStmts, "$1 = #$2($3, $4);$n",
+                         tmp, toRope(prc[m]), rdLoc(a), rdLoc(b))
     if size < platform.IntSize or t.kind in {tyRange, tyEnum, tySet}:
-      lineCg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
-           [tmp, intLiteral(firstOrd(t)), intLiteral(lastOrd(t))])
+      linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
+              tmp, intLiteral(firstOrd(t)), intLiteral(lastOrd(t)))
     putIntoDest(p, d, e.typ, ropef("(NI$1)($2)", [toRope(getSize(t)*8), tmp]))
 
 proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
@@ -409,8 +409,8 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
   InitLocExpr(p, e.sons[1], a)
   t = skipTypes(e.typ, abstractRange)
   if optOverflowCheck in p.options:
-    lineCg(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n",
-         [rdLoc(a), intLiteral(firstOrd(t))])
+    linefmt(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n",
+            rdLoc(a), intLiteral(firstOrd(t)))
   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) =
@@ -655,14 +655,14 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
       if id == gBackendId: strLit = getStrLit(p.module, field.name.s)
       else: strLit = con("TMP", toRope(id))
       if op.magic == mNot:
-        lineCg(p, cpsStmts,
-             "if ($1) #raiseFieldError(((#NimStringDesc*) &$2));$n",
-             [rdLoc(test), strLit])
+        linefmt(p, cpsStmts,
+                "if ($1) #raiseFieldError(((#NimStringDesc*) &$2));$n",
+                rdLoc(test), strLit)
       else:
-        lineCg(p, cpsStmts,
-             "if (!($1)) #raiseFieldError(((#NimStringDesc*) &$2));$n",
-             [rdLoc(test), strLit])
-    appf(r, ".$1", [field.loc.r])
+        linefmt(p, cpsStmts,
+                "if (!($1)) #raiseFieldError(((#NimStringDesc*) &$2));$n",
+                rdLoc(test), strLit)
+    app(r, rfmt(nil, ".$1", field.loc.r))
     putIntoDest(p, d, field.typ, r)
   else:
     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
       if firstOrd(ty) == 0:
         if (firstOrd(b.t) < firstOrd(ty)) or (lastOrd(b.t) > lastOrd(ty)):
-          lineCg(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError();$n",
-               [rdCharLoc(b), intLiteral(lastOrd(ty))])
+          linefmt(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError();$n",
+                  rdCharLoc(b), intLiteral(lastOrd(ty)))
       else:
-        lineCg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n",
-             [rdCharLoc(b), first, intLiteral(lastOrd(ty))])
+        linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n",
+                rdCharLoc(b), first, intLiteral(lastOrd(ty)))
     else:
       let idx = getOrdValue(e.sons[1])
       if idx < firstOrd(ty) or idx > lastOrd(ty):
         localError(e.info, errIndexOutOfBounds)
   if d.k == locNone: d.s = a.s
   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) =
   var a, b: TLoc
@@ -699,18 +699,18 @@ proc genCStringElem(p: BProc, e: PNode, d: var TLoc) =
   var ty = skipTypes(a.t, abstractVarRange)
   if d.k == locNone: d.s = a.s
   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) =
   var a, b: TLoc
   initLocExpr(p, e.sons[0], a)
   initLocExpr(p, e.sons[1], b) # emit range check:
   if optBoundsCheck in p.options:
-    lineCg(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n",
-         [rdLoc(b), rdLoc(a)]) # BUGFIX: ``>=`` and not ``>``!
+    linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n",
+            rdLoc(b), rdLoc(a)) # BUGFIX: ``>=`` and not ``>``!
   if d.k == locNone: d.s = a.s
   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) =
   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:
   if optBoundsCheck in p.options:
     if ty.kind == tyString:
-      lineCg(p, cpsStmts,
+      linefmt(p, cpsStmts,
            "if ((NU)($1) > (NU)($2->$3)) #raiseIndexError();$n",
-           [rdLoc(b), rdLoc(a), lenField()])
+           rdLoc(b), rdLoc(a), lenField())
     else:
-      lineCg(p, cpsStmts,
+      linefmt(p, cpsStmts,
            "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 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)),
-              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) =
   # how to generate code?
@@ -818,8 +818,8 @@ proc genEcho(p: BProc, n: PNode) =
   for i in countup(1, n.len-1):
     initLocExpr(p, n.sons[i], a)
     appf(args, ", ($1)->data", [rdLoc(a)])
-  lineCg(p, cpsStmts, "printf($1$2);$n", [
-    makeCString(repeatStr(n.len-1, "%s") & tnl), args])
+  linefmt(p, cpsStmts, "printf($1$2);$n",
+          makeCString(repeatStr(n.len-1, "%s") & tnl), args)
 
 include ccgcalls
 
@@ -850,14 +850,14 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
     initLocExpr(p, e.sons[i + 1], a)
     if skipTypes(e.sons[i + 1].Typ, abstractVarRange).kind == tyChar:
       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:
       if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
         Inc(L, len(e.sons[i + 1].strVal))
       else:
         appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
-      appLineCg(p, appends, "#appendString($1, $2);$n", [tmp.r, rdLoc(a)])
-  lineCg(p, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, toRope(L)])
+      app(appends, rfmt(p.module, "#appendString($1, $2);$n", tmp.r, rdLoc(a)))
+  linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", tmp.r, lens, toRope(L))
   app(p.s(cpsStmts), appends)
   if d.k == locNone:
     d = tmp
@@ -888,17 +888,17 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
     initLocExpr(p, e.sons[i + 2], a)
     if skipTypes(e.sons[i + 2].Typ, abstractVarRange).kind == tyChar:
       Inc(L)
-      appLineCg(p, appends, "#appendChar($1, $2);$n",
-            [rdLoc(dest), rdLoc(a)])
+      app(appends, rfmt(p.module, "#appendChar($1, $2);$n",
+                        rdLoc(dest), rdLoc(a)))
     else:
       if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}:
         Inc(L, len(e.sons[i + 2].strVal))
       else:
         appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
-      appLineCg(p, appends, "#appendString($1, $2);$n",
-            [rdLoc(dest), rdLoc(a)])
-  lineCg(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
-       [rdLoc(dest), lens, toRope(L)])
+      app(appends, rfmt(p.module, "#appendString($1, $2);$n",
+                        rdLoc(dest), rdLoc(a)))
+  linefmt(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
+          rdLoc(dest), lens, toRope(L))
   keepAlive(p, dest)
   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))])
   keepAlive(p, a)
   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})
 
 proc genReset(p: BProc, n: PNode) = 
   var a: TLoc
   InitLocExpr(p, n.sons[1], a)
-  lineCg(p, cpsStmts, "#genericReset((void*)$1, $2);$n", 
-       [addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, abstractVarRange))])
+  linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
+          addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, abstractVarRange)))
 
 proc genNew(p: BProc, e: PNode) =
   var
@@ -942,11 +942,11 @@ proc genNew(p: BProc, e: PNode) =
   if a.s == OnHeap and optRefcGc in gGlobalOptions:
     # use newObjRC1 as an optimization; and we don't need 'keepAlive' either
     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:
-      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)
-    lineCg(p, cpsStmts, "$1 = $2;$n", a.rdLoc, b.rdLoc)
+    linefmt(p, cpsStmts, "$1 = $2;$n", a.rdLoc, b.rdLoc)
   else:
     b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", args)
     genAssignment(p, a, b, {needToKeepAlive})  # set the object type:
@@ -960,9 +960,9 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: PRope) =
   var call: TLoc
   initLoc(call, locExpr, dest.t, OnHeap)
   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)
-    lineCg(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)
+    linefmt(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)
   else:
     call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args)
     genAssignment(p, dest, call, {needToKeepAlive})
@@ -981,7 +981,7 @@ proc genSeqConstr(p: BProc, t: PNode, d: var TLoc) =
   genNewSeqAux(p, d, intLiteral(sonsLen(t)))
   for i in countup(0, sonsLen(t) - 1):
     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
     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)
   for i in countup(0, L - 1):
     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
     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})
   
 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)
   while t.kind in {tyVar, tyPtr, tyRef}:
     if t.kind != tyVar: nilCheck = r
-    r = ropef("(*$1)", [r])
+    r = rfmt(nil, "(*$1)", r)
     t = skipTypes(t.sons[0], typedescInst)
   if gCmd != cmdCompileToCpp:
     while (t.kind == tyObject) and (t.sons[0] != nil):
-      app(r, ".Sup")
+      app(r, ~".Sup")
       t = skipTypes(t.sons[0], typedescInst)
   if isObjLackingTypeField(t):
     GlobalError(x.info, errGenerated, 
       "no 'of' operator available for pure objects")
   if nilCheck != nil:
-    r = ropecg(p.module, "(($1) && #isObj($2.m_type, $3))",
-              [nilCheck, r, genTypeInfo(p.module, dest)])
+    r = rfmt(p.module, "(($1) && #isObj($2.m_type, $3))",
+             nilCheck, r, genTypeInfo(p.module, dest))
   else:
-    r = ropecg(p.module, "#isObj($1.m_type, $2)", 
-              [r, genTypeInfo(p.module, dest)])
+    r = rfmt(p.module, "#isObj($1.m_type, $2)",
+             r, genTypeInfo(p.module, dest))
   putIntoDest(p, d, getSysType(tyBool), r)
 
 proc genOf(p: BProc, n: PNode, d: var TLoc) =
@@ -1364,12 +1364,12 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
     binaryExpr(p, e, d, "($1 == $2)")
   elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""):
     initLocExpr(p, e.sons[2], x)
-    putIntoDest(p, d, e.typ, 
-      ropef("(($1) && ($1)->$2 == 0)", [rdLoc(x), lenField()]))
+    putIntoDest(p, d, e.typ,
+      rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField()))
   elif (b.kind in {nkStrLit..nkTripleStrLit}) and (b.strVal == ""):
     initLocExpr(p, e.sons[1], x)
-    putIntoDest(p, d, e.typ, 
-      ropef("(($1) && ($1)->$2 == 0)", [rdLoc(x), lenField()]))
+    putIntoDest(p, d, e.typ,
+      rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField()))
   else:
     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)
     InitLocExpr(p, e.sons[1], a)
     InitLocExpr(p, e.sons[2], b)
-    putIntoDest(p, d, e.typ, ropef("($2 $1 $3)", [
-                toRope(opr[m]), rdLoc(a), rdLoc(b)]))
+    putIntoDest(p, d, e.typ, rfmt(nil, "($2 $1 $3)",
+                                  toRope(opr[m]), rdLoc(a), rdLoc(b)))
     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:
-      lineCg(p, cpsStmts, "#infCheck($1);$n", [rdLoc(d)])
+      linefmt(p, cpsStmts, "#infCheck($1);$n", rdLoc(d))
   else:
     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[1], b)
     getTemp(p, n.typ, tmp)
-    lineCg(p, cpsStmts, "$1.ClPrc = $2; $1.ClEnv = $3;$n",
-          tmp.rdLoc, a.rdLoc, b.rdLoc)
+    linefmt(p, cpsStmts, "$1.ClPrc = $2; $1.ClEnv = $3;$n",
+            tmp.rdLoc, a.rdLoc, b.rdLoc)
     putLocIntoDest(p, d, tmp)
 
 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")
         t = skipTypes(t.sons[0], abstractInst)
     if nilCheck != nil:
-      lineCg(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n",
-           [nilCheck, r, genTypeInfo(p.module, dest)])
+      linefmt(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n",
+              nilCheck, r, genTypeInfo(p.module, dest))
     else:
-      lineCg(p, cpsStmts, "#chckObj($1.m_type, $2);$n",
-           [r, genTypeInfo(p.module, dest)])
+      linefmt(p, cpsStmts, "#chckObj($1.m_type, $2);$n",
+              r, genTypeInfo(p.module, dest))
   if n.sons[0].typ.kind != tyObject:
     putIntoDest(p, d, n.typ,
                 ropef("(($1) ($2))", [getTypeDesc(p.module, n.typ), rdLoc(a)]))
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 192a838e0..5927c6afd 100755
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -75,7 +75,7 @@ proc endBlock(p: BProc, blockEnd: PRope) =
 proc endBlock(p: BProc) =
   let topBlock = p.blocks.len - 1  
   let blockEnd = if p.blocks[topBlock].label != nil:
-      ropef("} $1: ;$n", [p.blocks[topBlock].label])
+      rfmt(nil, "} $1: ;$n", p.blocks[topBlock].label)
     else:
       ~"}$n"
   endBlock(p, blockEnd)
@@ -93,7 +93,7 @@ template preserveBreakIdx(body: stmt): stmt {.immediate.} =
 proc genState(p: BProc, n: PNode) =
   internalAssert n.len == 1 and n.sons[0].kind == nkIntLit
   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) =
   # 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:
         dec alreadyPoppedCnt
       else:
-        lineCg(p, cpsStmts, "#popSafePoint();$n", [])
+        linefmt(p, cpsStmts, "#popSafePoint();$n")
     var finallyStmt = lastSon(tryStmt)
     if finallyStmt.kind == nkFinally: 
       genStmts(p, finallyStmt.sons[0])
@@ -251,7 +251,7 @@ proc blockLeaveActions(p: BProc, howMany: int) =
     p.nestedTryStmts.add(stack[i])
   if gCmd != cmdCompileToCpp:
     for i in countdown(p.inExceptBlock-1, 0):
-      lineCg(p, cpsStmts, "#popCurrentException();$n", [])
+      linefmt(p, cpsStmts, "#popCurrentException();$n")
 
 proc genReturnStmt(p: BProc, t: PNode) =
   p.beforeRetNeeded = true
@@ -281,7 +281,7 @@ proc genWhileStmt(p: BProc, t: PNode) =
 
     if optProfiler in p.options:
       # invoke at loop body exit:
-      lineCg(p, cpsStmts, "#nimProfile();$n")
+      linefmt(p, cpsStmts, "#nimProfile();$n")
     endBlock(p)
 
   dec(p.withinLoop)
@@ -369,9 +369,9 @@ proc genRaiseStmt(p: BProc, t: PNode) =
     genLineDir(p, t)
     # reraise the last exception:
     if gCmd == cmdCompileToCpp:
-      lineCg(p, cpsStmts, "throw;$n")
+      line(p, cpsStmts, ~"throw;$n")
     else:
-      lineCg(p, cpsStmts, "#reraiseException();$n")
+      linefmt(p, cpsStmts, "#reraiseException();$n")
 
 proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc, 
                           rangeFormat, eqFormat: TFormatStr, labl: TLabel) = 
@@ -458,8 +458,8 @@ proc genStringCase(p: BProc, t: PNode) =
       else: 
         # else statement: nothing to do yet
         # but we reserved a label, which we use later
-    lineCg(p, cpsStmts, "switch (#hashString($1) & $2) {$n", 
-         [rdLoc(a), toRope(bitMask)])
+    linefmt(p, cpsStmts, "switch (#hashString($1) & $2) {$n", 
+            rdLoc(a), toRope(bitMask))
     for j in countup(0, high(branches)):
       when false:
         let interior = cast[int](interiorAllocatedPtr(addr(branches[0])))+
@@ -598,7 +598,7 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
   length = sonsLen(t)
   endBlock(p, ropecg(p.module, "} catch (NimException& $1) {$n", [exc]))
   if optStackTrace in p.Options:
-    lineCg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
+    linefmt(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
   inc p.inExceptBlock
   i = 1
   var catchAllPresent = false
@@ -629,7 +629,7 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
     var finallyBlock = t.lastSon
     if finallyBlock.kind == nkFinally:
       genStmts(p, finallyBlock.sons[0])
-    lineCg(p, cpsStmts, "throw;$n")
+    line(p, cpsStmts, ~"throw;$n")
     endBlock(p)
   
   lineF(p, cpsStmts, "}$n") # end of catch block
@@ -671,19 +671,19 @@ proc genTryStmt(p: BProc, t: PNode) =
   genLineDir(p, t)
   var safePoint = getTempName()
   discard cgsym(p.module, "E_Base")
-  lineCg(p, cpsLocals, "#TSafePoint $1;$n", [safePoint])
-  lineCg(p, cpsStmts, "#pushSafePoint(&$1);$n", [safePoint])
-  lineF(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint])
+  linefmt(p, cpsLocals, "#TSafePoint $1;$n", safePoint)
+  linefmt(p, cpsStmts, "#pushSafePoint(&$1);$n", safePoint)
+  linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
   startBlock(p, "if ($1.status == 0) {$n", [safePoint])
   var length = sonsLen(t)
   add(p.nestedTryStmts, t)
   genStmts(p, t.sons[0])
-  linecg(p, cpsStmts, "#popSafePoint();$n")
+  linefmt(p, cpsStmts, "#popSafePoint();$n")
   endBlock(p)
   startBlock(p, "else {$n")
-  lineCg(p, cpsStmts, "#popSafePoint();$n")
+  linefmt(p, cpsStmts, "#popSafePoint();$n")
   if optStackTrace in p.Options:
-    lineCg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
+    linefmt(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
   inc p.inExceptBlock
   var i = 1
   while (i < length) and (t.sons[i].kind == nkExceptBranch):
@@ -692,9 +692,9 @@ proc genTryStmt(p: BProc, t: PNode) =
       # general except section:
       if i > 1: lineF(p, cpsStmts, "else")
       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])
-      lineCg(p, cpsStmts, "#popCurrentException();$n")
+      linefmt(p, cpsStmts, "#popCurrentException();$n")
       endBlock(p)
     else:
       var orExpr: PRope = nil
@@ -706,9 +706,9 @@ proc genTryStmt(p: BProc, t: PNode) =
               [genTypeInfo(p.module, t.sons[i].sons[j].typ)])
       if i > 1: line(p, cpsStmts, "else ")
       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])
-      lineCg(p, cpsStmts, "#popCurrentException();$n")
+      linefmt(p, cpsStmts, "#popCurrentException();$n")
       endBlock(p)
     inc(i)
   dec p.inExceptBlock
@@ -716,7 +716,7 @@ proc genTryStmt(p: BProc, t: PNode) =
   endBlock(p) # end of else block
   if i < length and t.sons[i].kind == nkFinally:
     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 = 
   for i in countup(0, sonsLen(t) - 1): 
diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim
index 5f6f14548..938330f1c 100644
--- a/compiler/ccgtrav.nim
+++ b/compiler/ccgtrav.nim
@@ -65,9 +65,9 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
     let arraySize = lengthOrd(typ.sons[0])
     var i: TLoc
     getTemp(p, getSysType(tyInt), i)
-    lineF(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
-        i.r, arraySize.toRope)
-    genTraverseProc(c, ropef("$1[$2]", accessor, i.r), typ.sons[1])
+    linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
+            i.r, arraySize.toRope)
+    genTraverseProc(c, rfmt(nil, "$1[$2]", accessor, i.r), typ.sons[1])
     lineF(p, cpsStmts, "}$n")
   of tyObject:
     for i in countup(0, sonsLen(typ) - 1):
@@ -76,12 +76,12 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
   of tyTuple:
     let typ = GetUniqueType(typ)
     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:
     lineCg(p, cpsStmts, c.visitorFrmt, accessor)
   of tyProc:
     if typ.callConv == ccClosure:
-      lineCg(p, cpsStmts, c.visitorFrmt, ropef("$1.ClEnv", accessor))
+      lineCg(p, cpsStmts, c.visitorFrmt, rfmt(nil, "$1.ClEnv", accessor))
   else:
     nil
 
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 3a4906f2f..4d5985581 100755
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -126,13 +126,13 @@ proc mangleName(s: PSym): PRope =
       # These are not properly scoped now - we need to add blocks
       # around for loops in transf
       if keepOrigName:
-        result = s.name.s.mangle.toRope
+        result = s.name.s.mangle.newRope
       else:
-        app(result, toRope(mangle(s.name.s)))
+        app(result, newRope(mangle(s.name.s)))
         app(result, ~"_")
         app(result, toRope(s.id))
     else:
-      app(result, toRope(mangle(s.name.s)))
+      app(result, newRope(mangle(s.name.s)))
       app(result, ~"_")
       app(result, toRope(s.id))
     s.loc.r = result
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 728898ed9..c7b3662a0 100755
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -133,74 +133,80 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope =
     if i - 1 >= start: 
       app(result, substr(frmt, start, i - 1))
 
-import macros
-
-type TFmtFragmentKind = enum
-  ffSym,
-  ffLit,
-  ffParam
-
-type TFragment = object
-  case kind: TFmtFragmentKind
-  of ffSym, ffLit:
-    value: string
-  of ffParam:
-    intValue: int
-
-iterator fmtStringFragments(s: string): tuple[kind: TFmtFragmentKind,
-                                              value: string,
-                                              intValue: int] =
-  # This is a bit less featured version of the ropecg's algorithm
-  # (be careful when replacing ropecg calls)
-  var
-    i = 0
-    length = s.len
+const compileTimeRopeFmt = not defined(booting)
 
-  while i < length:
-    var start = i
-    case s[i]
-    of '$':
-      let n = s[i+1]
-      case n
+when compileTimeRopeFmt:
+  import macros
+
+  type TFmtFragmentKind = enum
+    ffSym,
+    ffLit,
+    ffParam
+
+  type TFragment = object
+    case kind: TFmtFragmentKind
+    of ffSym, ffLit:
+      value: string
+    of ffParam:
+      intValue: int
+
+  iterator fmtStringFragments(s: string): tuple[kind: TFmtFragmentKind,
+                                                value: string,
+                                                intValue: int] =
+    # This is a bit less featured version of the ropecg's algorithm
+    # (be careful when replacing ropecg calls)
+    var
+      i = 0
+      length = s.len
+
+    while i < length:
+      var start = i
+      case s[i]
       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:
+        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
-    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
+        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:
+        if s[i] != '$' and s[i] != '#': inc i
+        else: break
+
+      if i - 1 >= start:
+        yield (kind: ffLit, value: substr(s, start, i-1), intValue: 0)
+
+  macro rfmt(m: BModule, fmt: expr[string], args: varargs[PRope]): expr =
+    ## Experimental optimized rope-formatting operator
+    ## 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
+    ## offset the gains?
+    result = newCall(bindSym"ropeConcat")
+    for frag in fmtStringFragments(fmt.strVal):
+      case frag.kind
+      of ffSym:
+        result.add(newCall(bindSym"cgsym", m, newStrLitNode(frag.value)))
+      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)
 
-    while i < length:
-      if s[i] != '$' and s[i] != '#': inc i
-      else: break
-
-    if i - 1 >= start:
-      yield (kind: ffLit, value: substr(s, start, i-1), intValue: 0)
-
-macro rfmt(m: BModule, fmt: expr[string], args: varargs[PRope]): expr =
-  ## Experimental optimized rope-formatting operator
-  ## 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
-  ## offset the gains?
-  result = newCall(bindSym"ropeConcat")
-  for frag in fmtStringFragments(fmt.strVal):
-    case frag.kind
-    of ffSym:
-      result.add(newCall(bindSym"cgsym", m, newStrLitNode(frag.value)))
-    of ffLit:
-      result.add(newCall(bindSym"~", newStrLitNode(frag.value)))
-    of ffParam:
-      result.add(args[frag.intValue])
-  
 proc appcg(m: BModule, c: var PRope, frmt: TFormatStr, 
            args: varargs[PRope]) = 
   app(c, ropecg(m, frmt, args))
@@ -232,9 +238,14 @@ proc lineCg(p: BProc, s: TCProcSection, frmt: TFormatStr,
                args: varargs[PRope]) =
   app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
 
-template lineCg2(p: BProc, s: TCProcSection, frmt: TFormatStr,
-                 args: varargs[PRope]) =
-  line(p, s, rfmt(p.module, frmt, args))
+when compileTimeRopeFmt:
+  template linefmt(p: BProc, s: TCProcSection, frmt: TFormatStr,
+                   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,
                args: varargs[PRope]) =
@@ -263,7 +274,7 @@ proc genLineDir(p: BProc, t: PNode) =
   genCLineDir(p.s(cpsStmts), t.info.toFullPath, line)
   if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and
       (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 ==
       {optLineTrace, optStackTrace}) and
       (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):
         app(r, ".Sup")
         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:
     # worst case for performance:
     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
   TAssignmentFlag = enum
@@ -330,16 +341,16 @@ proc resetLoc(p: BProc, loc: var TLoc) =
       nilLoc.r = toRope("NIM_NIL")
       genRefAssign(p, loc, nilLoc, {afSrcIsNil})
     else:
-      lineCg2(p, cpsStmts, "$1 = 0;$n", rdLoc(loc))
+      linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc))
   else:
     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))
       # XXX: generated reset procs should not touch the m_type
       # field, so disabling this should be safe:
       genObjectInit(p, cpsStmts, loc.t, loc, true)
     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))
       # XXX: We can be extra clever here and call memset only 
       # 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) =
   if not isComplexValueType(skipTypes(loc.t, abstractRange)):
-    lineCg2(p, section, "$1 = 0;$n", rdLoc(loc))
+    linefmt(p, section, "$1 = 0;$n", rdLoc(loc))
   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))
     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))
   else: 
     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.a = - 1
   result.t = getUniqueType(t)
@@ -403,9 +414,9 @@ proc keepAlive(p: BProc, toKeepAlive: TLoc) =
     result.flags = {}
 
     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:
-      lineCg2(p, cpsStmts,
+      linefmt(p, cpsStmts,
            "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
            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])
 
 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) =
   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
   assignLocalVar(p, env)
   # generate cast assignment:
-  lineCg(p, cpsStmts, "$1 = ($2) ClEnv;$n", rdLoc(env.loc),
-         getTypeDesc(p.module, env.typ))
+  linefmt(p, cpsStmts, "$1 = ($2) ClEnv;$n",
+          rdLoc(env.loc), getTypeDesc(p.module, env.typ))
 
 proc genProcAux(m: BModule, prc: PSym) =
   var p = newProc(prc, m)
@@ -741,7 +752,7 @@ proc genProcAux(m: BModule, prc: PSym) =
       # declare the result symbol:
       assignLocalVar(p, res)
       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)
     else:
       fillResult(res)
@@ -757,10 +768,10 @@ proc genProcAux(m: BModule, prc: PSym) =
   genStmts(p, prc.getBody) # modifies p.locals, p.init, etc.
   var generatedProc: PRope
   if sfPure in prc.flags: 
-    generatedProc = ropeff("$N$1 {$n$2$3$4}$N$N", "define $1 {$n$2$3$4}$N",
-        [header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)])
+    generatedProc = rfmt(nil, "$N$1 {$n$2$3$4}$N$N",
+                         header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts))
   else:
-    generatedProc = ropeff("$N$1 {$N", "$Ndefine $1 {$N", [header])
+    generatedProc = rfmt(nil, "$N$1 {$N", header)
     app(generatedProc, initGCFrame(p))
     if optStackTrace in prc.options: 
       getFrameDecl(p)
@@ -775,11 +786,11 @@ proc genProcAux(m: BModule, prc: PSym) =
       appcg(p, cpsInit, "\t#nimProfile();$n", [])
     app(generatedProc, p.s(cpsInit))
     app(generatedProc, p.s(cpsStmts))
-    if p.beforeRetNeeded: appf(generatedProc, "\tBeforeRet: ;$n")
+    if p.beforeRetNeeded: app(generatedProc, ~"\tBeforeRet: ;$n")
     app(generatedProc, deinitGCFrame(p))
     if optStackTrace in prc.options: app(generatedProc, deinitFrame(p))
     app(generatedProc, returnStmt)
-    appf(generatedProc, "}$N")
+    app(generatedProc, ~"}$N")
   app(m.s[cfsProcs], generatedProc)
   
 proc genProcPrototype(m: BModule, sym: PSym) = 
@@ -788,11 +799,11 @@ proc genProcPrototype(m: BModule, sym: PSym) =
   if lfDynamicLib in sym.loc.Flags:
     if getModule(sym).id != m.module.id and
         not ContainsOrIncl(m.declaredThings, sym.id): 
-      appf(m.s[cfsVars], "extern $1 $2;$n", 
-           [getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)])
+      app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
+                        getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
       if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
   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) = 
   fillProcLoc(prc)
diff --git a/compiler/main.nim b/compiler/main.nim
index 96ebfc5ef..2ce47217b 100755
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -504,5 +504,6 @@ proc MainCommand =
   echo "rope cache stats: "
   echo "  tries : ", gCacheTries
   echo "  misses: ", gCacheMisses
+  echo "  int tries: ", gCacheIntTries
   echo "  efficiency: ", formatFloat(1-(gCacheMisses.float/gCacheTries.float), ffDecimal, 3)
 
diff --git a/compiler/ropes.nim b/compiler/ropes.nim
index a539418ca..d5472a53a 100755
--- a/compiler/ropes.nim
+++ b/compiler/ropes.nim
@@ -96,7 +96,7 @@ proc ropeLen(a: PRope): int =
   if a == nil: result = 0
   else: result = a.length
   
-proc newRope(data: string = nil): PRope = 
+proc newRope*(data: string = nil): PRope = 
   new(result)
   if data != nil: 
     result.length = len(data)
@@ -129,6 +129,7 @@ proc RopeInvariant(r: PRope): bool =
 
 var gCacheTries* = 0
 var gCacheMisses* = 0
+var gCacheIntTries* = 0
 
 proc insertInCache(s: string): PRope = 
   inc gCacheTries
@@ -195,7 +196,9 @@ proc ropeConcat*(a: varargs[PRope]): PRope =
   # not overloaded version of concat to speed-up `rfmt` a little bit
   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: string) = a = con(a, b)