summary refs log tree commit diff stats
path: root/rod
diff options
context:
space:
mode:
Diffstat (limited to 'rod')
-rwxr-xr-xrod/c2nim/cparse.nim46
-rwxr-xr-x[-rw-r--r--]rod/c2nim/manual.txt0
-rwxr-xr-x[-rw-r--r--]rod/c2nim/tests/systest.c0
-rwxr-xr-x[-rw-r--r--]rod/c2nim/tests/systest2.c0
-rwxr-xr-xrod/ccgexprs.nim360
-rwxr-xr-xrod/ccgstmts.nim59
-rwxr-xr-xrod/ccgtypes.nim37
-rwxr-xr-xrod/cgen.nim169
-rwxr-xr-xrod/magicsys.nim5
-rwxr-xr-xrod/nimrod.ini5
-rwxr-xr-xrod/pragmas.nim30
-rwxr-xr-xrod/semstmts.nim6
-rwxr-xr-xrod/wordrecg.nim8
13 files changed, 352 insertions, 373 deletions
diff --git a/rod/c2nim/cparse.nim b/rod/c2nim/cparse.nim
index 5da9f3015..28cad2805 100755
--- a/rod/c2nim/cparse.nim
+++ b/rod/c2nim/cparse.nim
@@ -530,11 +530,10 @@ proc structPragmas(p: TParser, name: PNode, origName: string): PNode =
   result = newNodeP(nkPragmaExpr, p)
   addson(result, exportSym(p, name))
   var pragmas = newNodep(nkPragma, p)
-  addSon(pragmas, newIdentNodeP("pure", p))
-  addSon(pragmas, newIdentNodeP("final", p))
+  addSon(pragmas, newIdentNodeP("pure", p), newIdentNodeP("final", p))
   if p.options.header.len > 0:
-    addSon(pragmas, newIdentStrLitPair("importc", origName, p))
-    addSon(pragmas, newIdentStrLitPair("header", p.options.header, p))
+    addSon(pragmas, newIdentStrLitPair("importc", origName, p),
+                    newIdentStrLitPair("header", p.options.header, p))
   addSon(result, pragmas)
 
 proc enumPragmas(p: TParser, name: PNode): PNode =
@@ -542,15 +541,13 @@ proc enumPragmas(p: TParser, name: PNode): PNode =
   addson(result, name)
   var pragmas = newNodep(nkPragma, p)
   var e = newNodeP(nkExprColonExpr, p)
-  addSon(e, newIdentNodeP("size", p))
-  addSon(e, newIntNodeP(nkIntLit, 4, p))
+  addSon(e, newIdentNodeP("size", p), newIntNodeP(nkIntLit, 4, p))
   addSon(pragmas, e)
   addSon(result, pragmas)
 
 proc parseStruct(p: var TParser, isUnion: bool): PNode = 
   result = newNodeP(nkObjectTy, p)
-  addSon(result, nil) # no pragmas
-  addSon(result, nil) # no inheritance
+  addSon(result, nil, nil) # no pragmas, no inheritance 
   if p.tok.xkind == pxCurlyLe:
     addSon(result, parseStructBody(p, isUnion))
   else: 
@@ -569,8 +566,7 @@ proc parseParam(p: var TParser, params: PNode) =
     name = newIdentNodeP("a" & $idx, p)
   typ = parseTypeSuffix(p, typ)
   var x = newNodeP(nkIdentDefs, p)
-  addSon(x, name)
-  addSon(x, typ)
+  addSon(x, name, typ)
   if p.tok.xkind == pxAsgn: 
     # we support default parameters for C++:
     getTok(p, x)
@@ -621,15 +617,11 @@ proc parseFunctionPointerDecl(p: var TParser, rettyp: PNode): PNode =
   if p.inTypeDef == 0:
     result = newNodeP(nkVarSection, p)
     var def = newNodeP(nkIdentDefs, p)
-    addSon(def, name)
-    addSon(def, procType)
-    addSon(def, nil)
+    addSon(def, name, procType, nil)
     addSon(result, def)    
   else:
     result = newNodeP(nkTypeDef, p)
-    addSon(result, name)
-    addSon(result, nil) # no generics
-    addSon(result, procType)
+    addSon(result, name, nil, procType)
   
 proc addTypeDef(section, name, t: PNode) = 
   var def = newNodeI(nkTypeDef, name.info)
@@ -674,8 +666,7 @@ proc enumFields(p: var TParser): PNode =
       var c = constantExpression(p)
       var a = e
       e = newNodeP(nkEnumFieldDef, p)
-      addSon(e, a)
-      addSon(e, c)
+      addSon(e, a, c)
       skipCom(p, e)
     
     addSon(result, e)
@@ -871,10 +862,8 @@ proc declaration(p: var TParser): PNode =
       addSon(pragmas, newIdentNodeP("cdecl", p))
     elif pfStdcall in p.options.flags:
       addSon(pragmas, newIdentNodeP("stdcall", p))
-    addSon(result, exportSym(p, name))
-    addSon(result, nil) # no generics
-    addSon(result, params)
-    addSon(result, pragmas)
+    addSon(result, exportSym(p, name), nil) # no generics
+    addSon(result, params, pragmas)
     case p.tok.xkind 
     of pxSemicolon: 
       getTok(p)
@@ -1175,17 +1164,14 @@ proc asgnExpr(p: var TParser, opr: string, a: PNode): PNode =
   getTok(p, a)
   var b = assignmentExpression(p)
   result = newNodeP(nkAsgn, p)
-  addSon(result, a)
-  addSon(result, newBinary(opr, copyTree(a), b, p))
+  addSon(result, a, newBinary(opr, copyTree(a), b, p))
   
 proc incdec(p: var TParser, opr: string, a: PNode): PNode =
   closeContext(p)
   getTok(p, a)
   var b = assignmentExpression(p)
   result = newNodeP(nkCall, p)
-  addSon(result, newIdentNodeP(getIdent(opr), p))
-  addSon(result, a)
-  addSon(result, b)
+  addSon(result, newIdentNodeP(getIdent(opr), p), a, b)
   
 proc assignmentExpression(p: var TParser): PNode = 
   saveContext(p)
@@ -1196,8 +1182,7 @@ proc assignmentExpression(p: var TParser): PNode =
     getTok(p, a)
     var b = assignmentExpression(p)
     result = newNodeP(nkAsgn, p)
-    addSon(result, a)
-    addSon(result, b)
+    addSon(result, a, b)
   of pxPlusAsgn: result = incDec(p, "inc", a)    
   of pxMinusAsgn: result = incDec(p, "dec", a)
   of pxStarAsgn: result = asgnExpr(p, "*", a)
@@ -1291,8 +1276,7 @@ proc conditionalExpression(p: var TParser): PNode =
     var c = conditionalExpression(p)
     result = newNodeP(nkIfExpr, p)
     var branch = newNodeP(nkElifExpr, p)
-    addSon(branch, a)
-    addSon(branch, b)
+    addSon(branch, a, b)
     addSon(result, branch)
     branch = newNodeP(nkElseExpr, p)
     addSon(branch, c)
diff --git a/rod/c2nim/manual.txt b/rod/c2nim/manual.txt
index bb89c9567..bb89c9567 100644..100755
--- a/rod/c2nim/manual.txt
+++ b/rod/c2nim/manual.txt
diff --git a/rod/c2nim/tests/systest.c b/rod/c2nim/tests/systest.c
index b2b7646bb..b2b7646bb 100644..100755
--- a/rod/c2nim/tests/systest.c
+++ b/rod/c2nim/tests/systest.c
diff --git a/rod/c2nim/tests/systest2.c b/rod/c2nim/tests/systest2.c
index bf3027cfc..bf3027cfc 100644..100755
--- a/rod/c2nim/tests/systest2.c
+++ b/rod/c2nim/tests/systest2.c
diff --git a/rod/ccgexprs.nim b/rod/ccgexprs.nim
index 1e39508d9..88599f8f4 100755
--- a/rod/ccgexprs.nim
+++ b/rod/ccgexprs.nim
@@ -1,7 +1,7 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2010 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -33,7 +33,7 @@ proc genHexLiteral(v: PNode): PRope =
   result = intLiteral(v.intVal)
 
 proc getStrLit(m: BModule, s: string): PRope =
-  useMagic(m, "TGenericSeq")
+  discard cgsym(m, "TGenericSeq")
   result = con("TMP", toRope(getID()))
   appf(m.s[cfsData], "STRING_LITERAL($1, $2, $3);$n",
        [result, makeCString(s), ToRope(len(s))])
@@ -69,10 +69,10 @@ proc genLiteral(p: BProc, v: PNode, ty: PType): PRope =
       var id = NodeTableTestOrSet(p.module.dataCache, v, gid)
       if id == gid:
         # string literal not found in the cache:
-        useMagic(p.module, "NimStringDesc")
-        result = ropef("((NimStringDesc*) &$1)", [getStrLit(p.module, v.strVal)])
+        result = ropecg(p.module, "((#NimStringDesc*) &$1)", 
+                        [getStrLit(p.module, v.strVal)])
       else:
-        result = ropef("((NimStringDesc*) &TMP$1)", [toRope(id)])
+        result = ropecg(p.module, "((#NimStringDesc*) &TMP$1)", [toRope(id)])
     else:
       result = makeCString(v.strVal)
   of nkFloatLit..nkFloat64Lit:
@@ -119,13 +119,11 @@ proc genRawSetData(cs: TBitSet, size: int): PRope =
     #  result := toRope('0x' + ToHex(bitSetToWord(cs, size), size * 2))
 
 proc genSetNode(p: BProc, n: PNode): PRope =
-  var
-    cs: TBitSet
-    size, id: int
-  size = int(getSize(n.typ))
+  var cs: TBitSet
+  var size = int(getSize(n.typ))
   toBitSet(n, cs)
   if size > 8:
-    id = NodeTableTestOrSet(p.module.dataCache, n, gid)
+    var id = NodeTableTestOrSet(p.module.dataCache, n, gid)
     result = con("TMP", toRope(id))
     if id == gid:
       # not found in cache:
@@ -201,16 +199,13 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
     #    end;
     #    appf(p.s[cpsStmts], '$1 = $2;$n', [rdLoc(dest), rdLoc(src)]);
     if canFormAcycle(dest.t):
-      UseMagic(p.module, "asgnRef")
-      appf(p.s[cpsStmts], "asgnRef((void**) $1, $2);$n",
+      appcg(p.module, p.s[cpsStmts], "#asgnRef((void**) $1, $2);$n",
            [addrLoc(dest), rdLoc(src)])
     else:
-      UseMagic(p.module, "asgnRefNoCycle")
-      appf(p.s[cpsStmts], "asgnRefNoCycle((void**) $1, $2);$n",
+      appcg(p.module, p.s[cpsStmts], "#asgnRefNoCycle((void**) $1, $2);$n",
            [addrLoc(dest), rdLoc(src)])
   else:
-    UseMagic(p.module, "unsureAsgnRef")
-    appf(p.s[cpsStmts], "unsureAsgnRef((void**) $1, $2);$n",
+    appcg(p.module, p.s[cpsStmts], "#unsureAsgnRef((void**) $1, $2);$n",
          [addrLoc(dest), rdLoc(src)])
 
 proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
@@ -224,70 +219,60 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
     if not (needToCopy in flags):
       genRefAssign(p, dest, src, flags)
     else:
-      useMagic(p.module, "genericSeqAssign") # BUGFIX
-      appf(p.s[cpsStmts], "genericSeqAssign($1, $2, $3);$n",
+      appcg(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
            [addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t)])
   of tyString:
     if not (needToCopy in flags):
       genRefAssign(p, dest, src, flags)
     else:
-      useMagic(p.module, "copyString")
       if (dest.s == OnStack) or not (optRefcGC in gGlobalOptions):
-        appf(p.s[cpsStmts], "$1 = copyString($2);$n", [rdLoc(dest), rdLoc(src)])
+        appcg(p, cpsStmts, "$1 = #copyString($2);$n", [rdLoc(dest), rdLoc(src)])
       elif dest.s == OnHeap:
-        useMagic(p.module, "asgnRefNoCycle")
-        useMagic(p.module, "copyString") # BUGFIX
-        appf(p.s[cpsStmts], "asgnRefNoCycle((void**) $1, copyString($2));$n",
+        appcg(p, cpsStmts, "#asgnRefNoCycle((void**) $1, #copyString($2));$n",
              [addrLoc(dest), rdLoc(src)])
       else:
-        useMagic(p.module, "unsureAsgnRef")
-        useMagic(p.module, "copyString") # BUGFIX
-        appf(p.s[cpsStmts], "unsureAsgnRef((void**) $1, copyString($2));$n",
+        appcg(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n",
              [addrLoc(dest), rdLoc(src)])
   of tyTuple:
     if needsComplexAssignment(dest.t):
-      useMagic(p.module, "genericAssign")
-      appf(p.s[cpsStmts], "genericAssign((void*)$1, (void*)$2, $3);$n",
+      appcg(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
            [addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)])
     else:
-      appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
+      appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
   of tyArray, tyArrayConstr:
     if needsComplexAssignment(dest.t):
-      useMagic(p.module, "genericAssign")
-      appf(p.s[cpsStmts], "genericAssign((void*)$1, (void*)$2, $3);$n",
+      appcg(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
            [addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)])
     else:
-      appf(p.s[cpsStmts],
+      appcg(p, cpsStmts,
            "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1));$n",
            [rdLoc(dest), rdLoc(src)])
   of tyObject:                # XXX: check for subtyping?
     if needsComplexAssignment(dest.t):
-      useMagic(p.module, "genericAssign")
-      appf(p.s[cpsStmts], "genericAssign((void*)$1, (void*)$2, $3);$n",
+      appcg(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
            [addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)])
     else:
-      appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
+      appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
   of tyOpenArray:
     # open arrays are always on the stack - really? What if a sequence is
     # passed to an open array?
     if needsComplexAssignment(dest.t):
-      useMagic(p.module, "genericAssignOpenArray")
-      appf(p.s[cpsStmts],     # XXX: is this correct for arrays?
+      appcg(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:
-      appf(p.s[cpsStmts],
+      appcg(p, cpsStmts,
            "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len0);$n",
            [rdLoc(dest), rdLoc(src)])
   of tySet:
     if mapType(ty) == ctArray:
-      appf(p.s[cpsStmts], "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n",
+      appcg(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n",
            [rdLoc(dest), rdLoc(src), toRope(getSize(dest.t))])
     else:
-      appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
+      appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
   of tyPtr, tyPointer, tyChar, tyBool, tyProc, tyEnum, tyCString,
      tyInt..tyFloat128, tyRange:
-    appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
+    appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
   else: InternalError("genAssignment(" & $ty.kind & ')')
 
 proc expr(p: BProc, e: PNode, d: var TLoc)
@@ -303,7 +288,7 @@ proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc) =
     if lfNoDeepCopy in d.flags: genAssignment(p, d, s, {})
     else: genAssignment(p, d, s, {needToCopy})
   else:
-    d = s                     # ``d`` is free, so fill it with ``s``
+    d = s # ``d`` is free, so fill it with ``s``
 
 proc putIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) =
   var a: TLoc
@@ -319,60 +304,53 @@ proc putIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) =
     d.k = locExpr
     d.t = getUniqueType(t)
     d.r = r
-    d.a = - 1
+    d.a = -1
 
-proc binaryStmt(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) =
+proc binaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a, b: TLoc
-  if (d.k != locNone): InternalError(e.info, "binaryStmt")
-  if magic != "": useMagic(p.module, magic)
+  if d.k != locNone: InternalError(e.info, "binaryStmt")
   InitLocExpr(p, e.sons[1], a)
   InitLocExpr(p, e.sons[2], b)
-  appf(p.s[cpsStmts], frmt, [rdLoc(a), rdLoc(b)])
+  appcg(p, cpsStmts, frmt, [rdLoc(a), rdLoc(b)])
 
-proc unaryStmt(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) =
+proc unaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a: TLoc
   if (d.k != locNone): InternalError(e.info, "unaryStmt")
-  if magic != "": useMagic(p.module, magic)
   InitLocExpr(p, e.sons[1], a)
-  appf(p.s[cpsStmts], frmt, [rdLoc(a)])
+  appcg(p, cpsStmts, frmt, [rdLoc(a)])
 
-proc binaryStmtChar(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) =
+proc binaryStmtChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a, b: TLoc
   if (d.k != locNone): InternalError(e.info, "binaryStmtChar")
-  if magic != "": useMagic(p.module, magic)
   InitLocExpr(p, e.sons[1], a)
   InitLocExpr(p, e.sons[2], b)
-  appf(p.s[cpsStmts], frmt, [rdCharLoc(a), rdCharLoc(b)])
+  appcg(p, cpsStmts, frmt, [rdCharLoc(a), rdCharLoc(b)])
 
-proc binaryExpr(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) =
+proc binaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a, b: TLoc
-  if magic != "": useMagic(p.module, magic)
   assert(e.sons[1].typ != nil)
   assert(e.sons[2].typ != nil)
   InitLocExpr(p, e.sons[1], a)
   InitLocExpr(p, e.sons[2], b)
-  putIntoDest(p, d, e.typ, ropef(frmt, [rdLoc(a), rdLoc(b)]))
+  putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdLoc(a), rdLoc(b)]))
 
-proc binaryExprChar(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) =
+proc binaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a, b: TLoc
-  if magic != "": useMagic(p.module, magic)
   assert(e.sons[1].typ != nil)
   assert(e.sons[2].typ != nil)
   InitLocExpr(p, e.sons[1], a)
   InitLocExpr(p, e.sons[2], b)
-  putIntoDest(p, d, e.typ, ropef(frmt, [rdCharLoc(a), rdCharLoc(b)]))
+  putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdCharLoc(a), rdCharLoc(b)]))
 
-proc unaryExpr(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) =
+proc unaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a: TLoc
-  if magic != "": useMagic(p.module, magic)
   InitLocExpr(p, e.sons[1], a)
-  putIntoDest(p, d, e.typ, ropef(frmt, [rdLoc(a)]))
+  putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdLoc(a)]))
 
-proc unaryExprChar(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) =
+proc unaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a: TLoc
-  if magic != "": useMagic(p.module, magic)
   InitLocExpr(p, e.sons[1], a)
-  putIntoDest(p, d, e.typ, ropef(frmt, [rdCharLoc(a)]))
+  putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdCharLoc(a)]))
 
 proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
   const
@@ -389,22 +367,19 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
   var t = skipTypes(e.typ, abstractRange)
   if getSize(t) >= platform.IntSize:
     if optOverflowCheck in p.options:
-      useMagic(p.module, prc[m])
-      putIntoDest(p, d, e.typ,
-                  ropef("$1($2, $3)", [toRope(prc[m]), rdLoc(a), rdLoc(b)]))
+      putIntoDest(p, d, e.typ, ropecg(p.module, 
+                  "#$1($2, $3)", [toRope(prc[m]), rdLoc(a), rdLoc(b)]))
     else:
       putIntoDest(p, d, e.typ, ropef("(NI$4)($2 $1 $3)", [toRope(opr[m]),
           rdLoc(a), rdLoc(b), toRope(getSize(t) * 8)]))
   else:
     if optOverflowCheck in p.options:
-      useMagic(p.module, "raiseOverflow")
       if (m == mModI) or (m == mDivI):
-        useMagic(p.module, "raiseDivByZero")
-        appf(p.s[cpsStmts], "if (!$1) raiseDivByZero();$n", [rdLoc(b)])
+        appcg(p, cpsStmts, "if (!$1) #raiseDivByZero();$n", [rdLoc(b)])
       a.r = ropef("((NI)($2) $1 (NI)($3))", [toRope(opr[m]), rdLoc(a), rdLoc(b)])
       if d.k == locNone: getTemp(p, getSysType(tyInt), d)
       genAssignment(p, d, a, {})
-      appf(p.s[cpsStmts], "if ($1 < $2 || $1 > $3) raiseOverflow();$n",
+      appcg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
            [rdLoc(d), intLiteral(firstOrd(t)), intLiteral(lastOrd(t))])
       d.t = e.typ
       d.r = ropef("(NI$1)($2)", [toRope(getSize(t) * 8), rdLoc(d)])
@@ -425,8 +400,7 @@ 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:
-    useMagic(p.module, "raiseOverflow")
-    appf(p.s[cpsStmts], "if ($1 == $2) raiseOverflow();$n",
+    appcg(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)]))
 
@@ -623,8 +597,6 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
     id: int
     it: PNode
   if optFieldCheck in p.options:
-    useMagic(p.module, "raiseFieldError")
-    useMagic(p.module, "NimStringDesc")
     ty = genRecordFieldAux(p, e.sons[0], d, a)
     r = rdLoc(a)
     f = e.sons[0].sons[1].sym
@@ -655,12 +627,12 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
       if id == gid: strLit = getStrLit(p.module, field.name.s)
       else: strLit = con("TMP", toRope(id))
       if op.magic == mNot:
-        appf(p.s[cpsStmts],
-             "if ($1) raiseFieldError(((NimStringDesc*) &$2));$n",
+        appcg(p, cpsStmts,
+             "if ($1) #raiseFieldError(((#NimStringDesc*) &$2));$n",
              [rdLoc(test), strLit])
       else:
-        appf(p.s[cpsStmts],
-             "if (!($1)) raiseFieldError(((NimStringDesc*) &$2));$n",
+        appcg(p, cpsStmts,
+             "if (!($1)) #raiseFieldError(((#NimStringDesc*) &$2));$n",
              [rdLoc(test), strLit])
     appf(r, ".$1", [field.loc.r])
     putIntoDest(p, d, field.typ, r)
@@ -677,13 +649,12 @@ proc genArrayElem(p: BProc, e: PNode, d: var TLoc) =
   if (optBoundsCheck in p.options):
     if not isConstExpr(e.sons[1]):
       # semantic pass has already checked for const index expressions
-      useMagic(p.module, "raiseIndexError")
       if firstOrd(ty) == 0:
         if (firstOrd(b.t) < firstOrd(ty)) or (lastOrd(b.t) > lastOrd(ty)):
-          appf(p.s[cpsStmts], "if ((NU)($1) > (NU)($2)) raiseIndexError();$n",
+          appcg(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError();$n",
                [rdCharLoc(b), intLiteral(lastOrd(ty))])
       else:
-        appf(p.s[cpsStmts], "if ($1 < $2 || $1 > $3) raiseIndexError();$n",
+        appcg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n",
              [rdCharLoc(b), first, intLiteral(lastOrd(ty))])
   if d.k == locNone: d.s = a.s
   putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
@@ -703,8 +674,7 @@ proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) =
   initLocExpr(p, e.sons[0], a)
   initLocExpr(p, e.sons[1], b) # emit range check:
   if (optBoundsCheck in p.options):
-    useMagic(p.module, "raiseIndexError")
-    appf(p.s[cpsStmts], "if ((NU)($1) >= (NU)($2Len0)) raiseIndexError();$n",
+    appcg(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)),
@@ -718,14 +688,13 @@ proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) =
   if ty.kind in {tyRef, tyPtr}:
     ty = skipTypes(ty.sons[0], abstractVarRange) # emit range check:
   if (optBoundsCheck in p.options):
-    useMagic(p.module, "raiseIndexError")
     if ty.kind == tyString:
-      appf(p.s[cpsStmts],
-           "if ((NU)($1) > (NU)($2->Sup.len)) raiseIndexError();$n",
+      appcg(p, cpsStmts,
+           "if ((NU)($1) > (NU)($2->Sup.len)) #raiseIndexError();$n",
            [rdLoc(b), rdLoc(a)])
     else:
-      appf(p.s[cpsStmts],
-           "if ((NU)($1) >= (NU)($2->Sup.len)) raiseIndexError();$n",
+      appcg(p, cpsStmts,
+           "if ((NU)($1) >= (NU)($2->Sup.len)) #raiseIndexError();$n",
            [rdLoc(b), rdLoc(a)])
   if d.k == locNone: d.s = OnHeap
   if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
@@ -811,12 +780,10 @@ proc genIfExpr(p: BProc, n: PNode, d: var TLoc) =
 
 proc genEcho(p: BProc, n: PNode) =
   var a: TLoc
-  useMagic(p.module, "rawEcho")
-  useMagic(p.module, "rawEchoNL")
   for i in countup(1, sonsLen(n) - 1):
     initLocExpr(p, n.sons[i], a)
-    appf(p.s[cpsStmts], "rawEcho($1);$n", [rdLoc(a)])
-  app(p.s[cpsStmts], "rawEchoNL();" & tnl)
+    appcg(p, cpsStmts, "#rawEcho($1);$n", [rdLoc(a)])
+  appcg(p, cpsStmts, "#rawEchoNL();$n")
 
 proc genCall(p: BProc, t: PNode, d: var TLoc) =
   var
@@ -879,7 +846,6 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
   #    asgn(s, tmp0);
   #  }
   var a, tmp: TLoc
-  useMagic(p.module, "rawNewString")
   getTemp(p, e.typ, tmp)
   var L = 0
   var appends: PRope = nil
@@ -889,16 +855,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)
-      useMagic(p.module, "appendChar")
-      appf(appends, "appendChar($1, $2);$n", [tmp.r, rdLoc(a)])
+      appcg(p.module, appends, "#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->Sup.len + ", [rdLoc(a)])
-      useMagic(p.module, "appendString")
-      appf(appends, "appendString($1, $2);$n", [tmp.r, rdLoc(a)])
-  appf(p.s[cpsStmts], "$1 = rawNewString($2$3);$n", [tmp.r, lens, toRope(L)])
+      appcg(p.module, appends, "#appendString($1, $2);$n", [tmp.r, rdLoc(a)])
+  appcg(p, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, toRope(L)])
   app(p.s[cpsStmts], appends)
   if d.k == locNone:
     d = tmp
@@ -922,7 +886,6 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
     L: int
     appends, lens: PRope
   assert(d.k == locNone)
-  useMagic(p.module, "resizeString")
   L = 0
   appends = nil
   lens = nil
@@ -932,16 +895,16 @@ 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)
-      useMagic(p.module, "appendChar")
-      appf(appends, "appendChar($1, $2);$n", [rdLoc(dest), rdLoc(a)])
+      appcg(p.module, appends, "#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->Sup.len + ", [rdLoc(a)])
-      useMagic(p.module, "appendString")
-      appf(appends, "appendString($1, $2);$n", [rdLoc(dest), rdLoc(a)])
-  appf(p.s[cpsStmts], "$1 = resizeString($1, $2$3);$n",
+      appcg(p.module, appends, "#appendString($1, $2);$n",
+            [rdLoc(dest), rdLoc(a)])
+  appcg(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
        [rdLoc(dest), lens, toRope(L)])
   app(p.s[cpsStmts], appends)
 
@@ -950,10 +913,10 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
   #    seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x));
   #    seq->data[seq->len-1] = x;
   var a, b, dest: TLoc
-  useMagic(p.module, "incrSeq")
   InitLocExpr(p, e.sons[1], a)
   InitLocExpr(p, e.sons[2], b)
-  appf(p.s[cpsStmts], "$1 = ($2) incrSeq(&($1)->Sup, sizeof($3));$n", [rdLoc(a),
+  appcg(p, cpsStmts, "$1 = ($2) #incrSeq(&($1)->Sup, sizeof($3));$n", [
+      rdLoc(a),
       getTypeDesc(p.module, skipTypes(e.sons[1].typ, abstractVar)),
       getTypeDesc(p.module, skipTypes(e.sons[2].Typ, abstractVar))])
   initLoc(dest, locExpr, b.t, OnHeap)
@@ -977,20 +940,19 @@ proc genObjectInit(p: BProc, t: PType, a: TLoc, takeAddr: bool) =
     appf(p.s[cpsStmts], "$1.m_type = $2;$n", [r, genTypeInfo(p.module, t)])
   of frEmbedded:
     # worst case for performance:
-    useMagic(p.module, "objectInit")
     if takeAddr: r = addrLoc(a)
     else: r = rdLoc(a)
-    appf(p.s[cpsStmts], "objectInit($1, $2);$n", [r, genTypeInfo(p.module, t)])
+    appcg(p, cpsStmts, "#objectInit($1, $2);$n", [r, genTypeInfo(p.module, t)])
 
 proc genNew(p: BProc, e: PNode) =
   var
     a, b: TLoc
     reftype, bt: PType
-  useMagic(p.module, "newObj")
   refType = skipTypes(e.sons[1].typ, abstractVarRange)
   InitLocExpr(p, e.sons[1], a)
   initLoc(b, locExpr, a.t, OnHeap)
-  b.r = ropef("($1) newObj($2, sizeof($3))", [getTypeDesc(p.module, reftype),
+  b.r = ropecg(p.module,
+      "($1) #newObj($2, sizeof($3))", [getTypeDesc(p.module, reftype),
       genTypeInfo(p.module, refType),
       getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))])
   genAssignment(p, a, b, {})  # set the object type:
@@ -1001,13 +963,13 @@ proc genNewSeq(p: BProc, e: PNode) =
   var
     a, b, c: TLoc
     seqtype: PType
-  useMagic(p.module, "newSeq")
   seqType = skipTypes(e.sons[1].typ, abstractVarRange)
   InitLocExpr(p, e.sons[1], a)
   InitLocExpr(p, e.sons[2], b)
   initLoc(c, locExpr, a.t, OnHeap)
-  c.r = ropef("($1) newSeq($2, $3)", [getTypeDesc(p.module, seqtype),
-                                      genTypeInfo(p.module, seqType), rdLoc(b)])
+  c.r = ropecg(p.module, "($1) #newSeq($2, $3)", [
+               getTypeDesc(p.module, seqtype),
+               genTypeInfo(p.module, seqType), rdLoc(b)])
   genAssignment(p, a, c, {})
 
 proc genIs(p: BProc, x: PNode, typ: PType, d: var TLoc) =
@@ -1017,7 +979,6 @@ proc genIs(p: BProc, x: PNode, typ: PType, d: var TLoc) =
     r, nilcheck: PRope
   initLocExpr(p, x, a)
   dest = skipTypes(typ, abstractPtrs)
-  useMagic(p.module, "isObj")
   r = rdLoc(a)
   nilCheck = nil
   t = skipTypes(a.t, abstractInst)
@@ -1030,10 +991,10 @@ proc genIs(p: BProc, x: PNode, typ: PType, d: var TLoc) =
       app(r, ".Sup")
       t = skipTypes(t.sons[0], abstractInst)
   if nilCheck != nil:
-    r = ropef("(($1) && isObj($2.m_type, $3))",
+    r = ropecg(p.module, "(($1) && #isObj($2.m_type, $3))",
               [nilCheck, r, genTypeInfo(p.module, dest)])
   else:
-    r = ropef("isObj($1.m_type, $2)", [r, genTypeInfo(p.module, dest)])
+    r = ropecg(p.module, "#isObj($1.m_type, $2)", [r, genTypeInfo(p.module, dest)])
   putIntoDest(p, d, getSysType(tyBool), r)
 
 proc genIs(p: BProc, n: PNode, d: var TLoc) =
@@ -1045,7 +1006,6 @@ proc genNewFinalize(p: BProc, e: PNode) =
     refType, bt: PType
     ti: PRope
     oldModule: BModule
-  useMagic(p.module, "newObj")
   refType = skipTypes(e.sons[1].typ, abstractVarRange)
   InitLocExpr(p, e.sons[1], a)
   # This is a little hack:
@@ -1057,7 +1017,8 @@ proc genNewFinalize(p: BProc, e: PNode) =
   initLoc(b, locExpr, a.t, OnHeap)
   ti = genTypeInfo(p.module, refType)
   appf(gNimDat.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
-  b.r = ropef("($1) newObj($2, sizeof($3))", [getTypeDesc(p.module, refType),
+  b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
+      getTypeDesc(p.module, refType),
       ti, getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))])
   genAssignment(p, a, b, {})  # set the object type:
   bt = skipTypes(refType.sons[0], abstractRange)
@@ -1069,30 +1030,23 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
   var t = skipTypes(e.sons[1].typ, abstractVarRange)
   case t.kind
   of tyInt..tyInt64:
-    UseMagic(p.module, "reprInt")
-    putIntoDest(p, d, e.typ, ropef("reprInt($1)", [rdLoc(a)]))
+    putIntoDest(p, d, e.typ, ropecg(p.module, "#reprInt($1)", [rdLoc(a)]))
   of tyFloat..tyFloat128:
-    UseMagic(p.module, "reprFloat")
-    putIntoDest(p, d, e.typ, ropef("reprFloat($1)", [rdLoc(a)]))
+    putIntoDest(p, d, e.typ, ropecg(p.module, "#reprFloat($1)", [rdLoc(a)]))
   of tyBool:
-    UseMagic(p.module, "reprBool")
-    putIntoDest(p, d, e.typ, ropef("reprBool($1)", [rdLoc(a)]))
+    putIntoDest(p, d, e.typ, ropecg(p.module, "#reprBool($1)", [rdLoc(a)]))
   of tyChar:
-    UseMagic(p.module, "reprChar")
-    putIntoDest(p, d, e.typ, ropef("reprChar($1)", [rdLoc(a)]))
+    putIntoDest(p, d, e.typ, ropecg(p.module, "#reprChar($1)", [rdLoc(a)]))
   of tyEnum, tyOrdinal:
-    UseMagic(p.module, "reprEnum")
     putIntoDest(p, d, e.typ,
-                ropef("reprEnum($1, $2)", [rdLoc(a), genTypeInfo(p.module, t)]))
+                ropecg(p.module, "#reprEnum($1, $2)", [
+                rdLoc(a), genTypeInfo(p.module, t)]))
   of tyString:
-    UseMagic(p.module, "reprStr")
-    putIntoDest(p, d, e.typ, ropef("reprStr($1)", [rdLoc(a)]))
+    putIntoDest(p, d, e.typ, ropecg(p.module, "#reprStr($1)", [rdLoc(a)]))
   of tySet:
-    useMagic(p.module, "reprSet")
-    putIntoDest(p, d, e.typ,
-                ropef("reprSet($1, $2)", [rdLoc(a), genTypeInfo(p.module, t)]))
+    putIntoDest(p, d, e.typ, ropecg(p.module, "#reprSet($1, $2)", [
+                rdLoc(a), genTypeInfo(p.module, t)]))
   of tyOpenArray:
-    useMagic(p.module, "reprOpenArray")
     var b: TLoc
     case a.t.kind
     of tyOpenArray: putIntoDest(p, b, e.typ, rdLoc(a))
@@ -1102,23 +1056,22 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
       putIntoDest(p, b, e.typ,
                   ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
     else: InternalError(e.sons[0].info, "genRepr()")
-    putIntoDest(p, d, e.typ, ropef("reprOpenArray($1, $2)", [rdLoc(b),
+    putIntoDest(p, d, e.typ, 
+        ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b),
         genTypeInfo(p.module, elemType(t))]))
   of tyCString, tyArray, tyArrayConstr, tyRef, tyPtr, tyPointer, tyNil,
      tySequence:
-    useMagic(p.module, "reprAny")
     putIntoDest(p, d, e.typ,
-                ropef("reprAny($1, $2)", [rdLoc(a), genTypeInfo(p.module, t)]))
+                ropecg(p.module, "#reprAny($1, $2)", [
+                rdLoc(a), genTypeInfo(p.module, t)]))
   else:
-    useMagic(p.module, "reprAny")
-    putIntoDest(p, d, e.typ, ropef("reprAny($1, $2)",
+    putIntoDest(p, d, e.typ, ropecg(p.module, "#reprAny($1, $2)",
                                    [addrLoc(a), genTypeInfo(p.module, t)]))
 
-proc genDollar(p: BProc, n: PNode, d: var TLoc, magic, frmt: string) =
+proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
   var a: TLoc
   InitLocExpr(p, n.sons[1], a)
-  UseMagic(p.module, magic)
-  a.r = ropef(frmt, [rdLoc(a)])
+  a.r = ropecg(p.module, frmt, [rdLoc(a)])
   if d.k == locNone: getTemp(p, n.typ, d)
   genAssignment(p, d, a, {})
 
@@ -1127,14 +1080,14 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   case typ.kind
   of tyOpenArray:
     while e.sons[1].kind == nkPassAsOpenArray: e.sons[1] = e.sons[1].sons[0]
-    if op == mHigh: unaryExpr(p, e, d, "", "($1Len0-1)")
-    else: unaryExpr(p, e, d, "", "$1Len0")
+    if op == mHigh: unaryExpr(p, e, d, "($1Len0-1)")
+    else: unaryExpr(p, e, d, "$1Len0")
   of tyCstring:
-    if op == mHigh: unaryExpr(p, e, d, "", "(strlen($1)-1)")
-    else: unaryExpr(p, e, d, "", "strlen($1)")
+    if op == mHigh: unaryExpr(p, e, d, "(strlen($1)-1)")
+    else: unaryExpr(p, e, d, "strlen($1)")
   of tyString, tySequence:
-    if op == mHigh: unaryExpr(p, e, d, "", "($1->Sup.len-1)")
-    else: unaryExpr(p, e, d, "", "$1->Sup.len")
+    if op == mHigh: unaryExpr(p, e, d, "($1->Sup.len-1)")
+    else: unaryExpr(p, e, d, "$1->Sup.len")
   of tyArray, tyArrayConstr:
     # YYY: length(sideeffect) is optimized away incorrectly?
     if op == mHigh: putIntoDest(p, d, e.typ, toRope(lastOrd(Typ)))
@@ -1144,16 +1097,15 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
 proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
   var a, b: TLoc
   assert(d.k == locNone)
-  useMagic(p.module, "setLengthSeq")
   InitLocExpr(p, e.sons[1], a)
   InitLocExpr(p, e.sons[2], b)
   var t = skipTypes(e.sons[1].typ, abstractVar)
-  appf(p.s[cpsStmts], "$1 = ($3) setLengthSeq(&($1)->Sup, sizeof($4), $2);$n", [
+  appcg(p, cpsStmts, "$1 = ($3) #setLengthSeq(&($1)->Sup, sizeof($4), $2);$n", [
       rdLoc(a), rdLoc(b), getTypeDesc(p.module, t),
       getTypeDesc(p.module, t.sons[0])])
 
 proc genSetLengthStr(p: BProc, e: PNode, d: var TLoc) =
-  binaryStmt(p, e, d, "setLengthStr", "$1 = setLengthStr($1, $2);$n")
+  binaryStmt(p, e, d, "$1 = #setLengthStr($1, $2);$n")
 
 proc genSwap(p: BProc, e: PNode, d: var TLoc) =
   # swap(a, b) -->
@@ -1257,15 +1209,15 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
       binaryStmtInExcl(p, e, d, "$1 &= ~(1 << ((" & ts & ")($2) % (sizeof(" &
           ts & ")*8)));$n")
     of mCard:
-      if size <= 4: unaryExprChar(p, e, d, "countBits32", "countBits32($1)")
-      else: unaryExprChar(p, e, d, "countBits64", "countBits64($1)")
-    of mLtSet: binaryExprChar(p, e, d, "", "(($1 & ~ $2 ==0)&&($1 != $2))")
-    of mLeSet: binaryExprChar(p, e, d, "", "(($1 & ~ $2)==0)")
-    of mEqSet: binaryExpr(p, e, d, "", "($1 == $2)")
-    of mMulSet: binaryExpr(p, e, d, "", "($1 & $2)")
-    of mPlusSet: binaryExpr(p, e, d, "", "($1 | $2)")
-    of mMinusSet: binaryExpr(p, e, d, "", "($1 & ~ $2)")
-    of mSymDiffSet: binaryExpr(p, e, d, "", "($1 ^ $2)")
+      if size <= 4: unaryExprChar(p, e, d, "#countBits32($1)")
+      else: unaryExprChar(p, e, d, "#countBits64($1)")
+    of mLtSet: binaryExprChar(p, e, d, "(($1 & ~ $2 ==0)&&($1 != $2))")
+    of mLeSet: binaryExprChar(p, e, d, "(($1 & ~ $2)==0)")
+    of mEqSet: binaryExpr(p, e, d, "($1 == $2)")
+    of mMulSet: binaryExpr(p, e, d, "($1 & $2)")
+    of mPlusSet: binaryExpr(p, e, d, "($1 | $2)")
+    of mMinusSet: binaryExpr(p, e, d, "($1 & ~ $2)")
+    of mSymDiffSet: binaryExpr(p, e, d, "($1 ^ $2)")
     of mInSet:
       genInOp(p, e, d)
     else: internalError(e.info, "genSetOp()")
@@ -1273,7 +1225,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
     case op
     of mIncl: binaryStmtInExcl(p, e, d, "$1[$2/8] |=(1<<($2%8));$n")
     of mExcl: binaryStmtInExcl(p, e, d, "$1[$2/8] &= ~(1<<($2%8));$n")
-    of mCard: unaryExprChar(p, e, d, "cardSet", "cardSet($1, " & $size & ')')
+    of mCard: unaryExprChar(p, e, d, "#cardSet($1, " & $size & ')')
     of mLtSet, mLeSet:
       getTemp(p, getSysType(tyInt), i) # our counter
       initLocExpr(p, e.sons[1], a)
@@ -1282,7 +1234,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
       appf(p.s[cpsStmts], lookupOpr[op],
            [rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b)])
     of mEqSet:
-      binaryExprChar(p, e, d, "", "(memcmp($1, $2, " & $(size) & ")==0)")
+      binaryExprChar(p, e, d, "(memcmp($1, $2, " & $(size) & ")==0)")
     of mMulSet, mPlusSet, mMinusSet, mSymDiffSet:
       # we inline the simple for loop for better code generation:
       getTemp(p, getSysType(tyInt), i) # our counter
@@ -1297,7 +1249,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
     else: internalError(e.info, "genSetOp")
 
 proc genOrd(p: BProc, e: PNode, d: var TLoc) =
-  unaryExprChar(p, e, d, "", "$1")
+  unaryExprChar(p, e, d, "$1")
 
 proc genCast(p: BProc, e: PNode, d: var TLoc) =
   const
@@ -1317,14 +1269,13 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) =
 proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
   var a: TLoc
   var dest = skipTypes(n.typ, abstractVar)
-  if not (optRangeCheck in p.options):
+  if optRangeCheck notin p.options:
     InitLocExpr(p, n.sons[0], a)
     putIntoDest(p, d, n.typ, ropef("(($1) ($2))",
                                    [getTypeDesc(p.module, dest), rdCharLoc(a)]))
   else:
     InitLocExpr(p, n.sons[0], a)
-    useMagic(p.module, magic)
-    putIntoDest(p, d, dest, ropef("(($1)$5($2, $3, $4))", [
+    putIntoDest(p, d, dest, ropecg(p.module, "(($1)#$5($2, $3, $4))", [
         getTypeDesc(p.module, dest), rdCharLoc(a),
         genLiteral(p, n.sons[1], dest), genLiteral(p, n.sons[2], dest),
         toRope(magic)]))
@@ -1356,17 +1307,16 @@ proc convStrToCStr(p: BProc, n: PNode, d: var TLoc) =
 
 proc convCStrToStr(p: BProc, n: PNode, d: var TLoc) =
   var a: TLoc
-  useMagic(p.module, "cstrToNimstr")
   initLocExpr(p, n.sons[0], a)
   putIntoDest(p, d, skipTypes(n.typ, abstractVar),
-              ropef("cstrToNimstr($1)", [rdLoc(a)]))
+              ropecg(p.module, "#cstrToNimstr($1)", [rdLoc(a)]))
 
 proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
   var x: TLoc
   var a = e.sons[1]
   var b = e.sons[2]
   if (a.kind == nkNilLit) or (b.kind == nkNilLit):
-    binaryExpr(p, e, d, "", "($1 == $2)")
+    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)->Sup.len == 0)", [rdLoc(x)]))
@@ -1374,16 +1324,16 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
     initLocExpr(p, e.sons[1], x)
     putIntoDest(p, d, e.typ, ropef("(($1) && ($1)->Sup.len == 0)", [rdLoc(x)]))
   else:
-    binaryExpr(p, e, d, "eqStrings", "eqStrings($1, $2)")
+    binaryExpr(p, e, d, "#eqStrings($1, $2)")
 
 proc genSeqConstr(p: BProc, t: PNode, d: var TLoc) =
   var newSeq, arr: TLoc
-  useMagic(p.module, "newSeq")
   if d.k == locNone:
     getTemp(p, t.typ, d)
   # generate call to newSeq before adding the elements per hand:
   initLoc(newSeq, locExpr, t.typ, OnHeap)
-  newSeq.r = ropef("($1) newSeq($2, $3)", [getTypeDesc(p.module, t.typ),
+  newSeq.r = ropecg(p.module, "($1) #newSeq($2, $3)", 
+      [getTypeDesc(p.module, t.typ),
       genTypeInfo(p.module, t.typ), intLiteral(sonsLen(t))])
   genAssignment(p, d, newSeq, {afSrcIsNotNil})
   for i in countup(0, sonsLen(t) - 1):
@@ -1398,13 +1348,13 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
     t.sons[1].typ = t.typ
     genSeqConstr(p, t.sons[1], d)
     return
-  useMagic(p.module, "newSeq")
   if d.k == locNone:
     getTemp(p, t.typ, d)
   # generate call to newSeq before adding the elements per hand:
   var L = int(lengthOrd(t.sons[1].typ))
   initLoc(newSeq, locExpr, t.typ, OnHeap)
-  newSeq.r = ropef("($1) newSeq($2, $3)", [getTypeDesc(p.module, t.typ),
+  newSeq.r = ropecg(p.module, "($1) #newSeq($2, $3)", 
+      [getTypeDesc(p.module, t.typ),
       genTypeInfo(p.module, t.typ), intLiteral(L)])
   genAssignment(p, d, newSeq, {afSrcIsNotNil})
   initLocExpr(p, t.sons[1], a)
@@ -1427,11 +1377,9 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
     putIntoDest(p, d, e.typ, ropef("($2 $1 $3)", [
                 toRope(opr[m]), rdLoc(a), rdLoc(b)]))
     if optNanCheck in p.options:
-      useMagic(p.module, "nanCheck")
-      appf(p.s[cpsStmts], "nanCheck($1);$n", [rdLoc(d)])
+      appcg(p, cpsStmts, "#nanCheck($1);$n", [rdLoc(d)])
     if optInfCheck in p.options:
-      useMagic(p.module, "infCheck")
-      appf(p.s[cpsStmts], "infCheck($1);$n", [rdLoc(d)])
+      appcg(p, cpsStmts, "#infCheck($1);$n", [rdLoc(d)])
   else:
     binaryArith(p, e, d, m)
 
@@ -1448,49 +1396,48 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mSwap: genSwap(p, e, d)
   of mPred:
     # XXX: range checking?
-    if not (optOverflowCheck in p.Options): binaryExpr(p, e, d, "", "$1 - $2")
-    else: binaryExpr(p, e, d, "subInt", "subInt($1, $2)")
+    if not (optOverflowCheck in p.Options): binaryExpr(p, e, d, "$1 - $2")
+    else: binaryExpr(p, e, d, "#subInt($1, $2)")
   of mSucc:
     # XXX: range checking?
-    if not (optOverflowCheck in p.Options): binaryExpr(p, e, d, "", "$1 + $2")
-    else: binaryExpr(p, e, d, "addInt", "addInt($1, $2)")
+    if not (optOverflowCheck in p.Options): binaryExpr(p, e, d, "$1 + $2")
+    else: binaryExpr(p, e, d, "#addInt($1, $2)")
   of mInc:
     if not (optOverflowCheck in p.Options):
-      binaryStmt(p, e, d, "", "$1 += $2;$n")
+      binaryStmt(p, e, d, "$1 += $2;$n")
     elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64:
-      binaryStmt(p, e, d, "addInt64", "$1 = addInt64($1, $2);$n")
+      binaryStmt(p, e, d, "$1 = #addInt64($1, $2);$n")
     else:
-      binaryStmt(p, e, d, "addInt", "$1 = addInt($1, $2);$n")
+      binaryStmt(p, e, d, "$1 = #addInt($1, $2);$n")
   of ast.mDec:
     if not (optOverflowCheck in p.Options):
-      binaryStmt(p, e, d, "", "$1 -= $2;$n")
+      binaryStmt(p, e, d, "$1 -= $2;$n")
     elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64:
-      binaryStmt(p, e, d, "subInt64", "$1 = subInt64($1, $2);$n")
+      binaryStmt(p, e, d, "$1 = #subInt64($1, $2);$n")
     else:
-      binaryStmt(p, e, d, "subInt", "$1 = subInt($1, $2);$n")
+      binaryStmt(p, e, d, "$1 = #subInt($1, $2);$n")
   of mConStrStr: genStrConcat(p, e, d)
-  of mAppendStrCh: binaryStmt(p, e, d, "addChar", "$1 = addChar($1, $2);$n")
+  of mAppendStrCh: binaryStmt(p, e, d, "$1 = #addChar($1, $2);$n")
   of mAppendStrStr: genStrAppend(p, e, d)
   of mAppendSeqElem: genSeqElemAppend(p, e, d)
   of mEqStr: genStrEquals(p, e, d)
-  of mLeStr: binaryExpr(p, e, d, "cmpStrings", "(cmpStrings($1, $2) <= 0)")
-  of mLtStr: binaryExpr(p, e, d, "cmpStrings", "(cmpStrings($1, $2) < 0)")
-  of mIsNil: unaryExpr(p, e, d, "", "$1 == 0")
-  of mIntToStr: genDollar(p, e, d, "nimIntToStr", "nimIntToStr($1)")
-  of mInt64ToStr: genDollar(p, e, d, "nimInt64ToStr", "nimInt64ToStr($1)")
-  of mBoolToStr: genDollar(p, e, d, "nimBoolToStr", "nimBoolToStr($1)")
-  of mCharToStr: genDollar(p, e, d, "nimCharToStr", "nimCharToStr($1)")
-  of mFloatToStr: genDollar(p, e, d, "nimFloatToStr", "nimFloatToStr($1)")
-  of mCStrToStr: genDollar(p, e, d, "cstrToNimstr", "cstrToNimstr($1)")
+  of mLeStr: binaryExpr(p, e, d, "(#cmpStrings($1, $2) <= 0)")
+  of mLtStr: binaryExpr(p, e, d, "(#cmpStrings($1, $2) < 0)")
+  of mIsNil: unaryExpr(p, e, d, "$1 == 0")
+  of mIntToStr: genDollar(p, e, d, "#nimIntToStr($1)")
+  of mInt64ToStr: genDollar(p, e, d, "#nimInt64ToStr($1)")
+  of mBoolToStr: genDollar(p, e, d, "#nimBoolToStr($1)")
+  of mCharToStr: genDollar(p, e, d, "#nimCharToStr($1)")
+  of mFloatToStr: genDollar(p, e, d, "#nimFloatToStr($1)")
+  of mCStrToStr: genDollar(p, e, d, "#cstrToNimstr($1)")
   of mStrToStr: expr(p, e.sons[1], d)
   of mEnumToStr: genRepr(p, e, d)
   of mAssert:
     if (optAssert in p.Options):
-      useMagic(p.module, "internalAssert")
       expr(p, e.sons[1], d)
       line = toRope(toLinenumber(e.info))
       filen = makeCString(ToFilename(e.info))
-      appf(p.s[cpsStmts], "internalAssert($1, $2, $3);$n",
+      appcg(p, cpsStmts, "#internalAssert($1, $2, $3);$n",
            [filen, line, rdLoc(d)])
   of mIs: genIs(p, e, d)
   of mNew: genNew(p, e)
@@ -1503,8 +1450,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mOrd: genOrd(p, e, d)
   of mLengthArray, mHigh, mLengthStr, mLengthSeq, mLengthOpenArray:
     genArrayLen(p, e, d, op)
-  of mGCref: unaryStmt(p, e, d, "nimGCref", "nimGCref($1);$n")
-  of mGCunref: unaryStmt(p, e, d, "nimGCunref", "nimGCunref($1);$n")
+  of mGCref: unaryStmt(p, e, d, "#nimGCref($1);$n")
+  of mGCunref: unaryStmt(p, e, d, "#nimGCunref($1);$n")
   of mSetLengthStr: genSetLengthStr(p, e, d)
   of mSetLengthSeq: genSetLengthSeq(p, e, d)
   of mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet,
@@ -1632,7 +1579,6 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
   initLocExpr(p, n.sons[0], a)
   dest = skipTypes(n.typ, abstractPtrs)
   if (optObjCheck in p.options) and not (isPureObject(dest)):
-    useMagic(p.module, "chckObj")
     r = rdLoc(a)
     nilCheck = nil
     t = skipTypes(a.t, abstractInst)
@@ -1645,10 +1591,10 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
         app(r, ".Sup")
         t = skipTypes(t.sons[0], abstractInst)
     if nilCheck != nil:
-      appf(p.s[cpsStmts], "if ($1) chckObj($2.m_type, $3);$n",
+      appcg(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n",
            [nilCheck, r, genTypeInfo(p.module, dest)])
     else:
-      appf(p.s[cpsStmts], "chckObj($1.m_type, $2);$n",
+      appcg(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,
diff --git a/rod/ccgstmts.nim b/rod/ccgstmts.nim
index 78ef4f24f..9171b5fb8 100755
--- a/rod/ccgstmts.nim
+++ b/rod/ccgstmts.nim
@@ -1,7 +1,7 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2010 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -20,9 +20,7 @@ proc genLineDir(p: BProc, t: PNode) =
           [toRope(toFilename(t.info)), toRope(line)])
   if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and
       ((p.prc == nil) or not (sfPure in p.prc.flags)): 
-    useMagic(p.module, "endb") # new: endb support
-    appff(p.s[cpsStmts], "endb($1);$n", "call void @endb(%NI $1)$n", 
-          [toRope(line)])
+    appcg(p, cpsStmts, "#endb($1);$n", [toRope(line)])
   elif ({optLineTrace, optStackTrace} * p.Options ==
       {optLineTrace, optStackTrace}) and
       ((p.prc == nil) or not (sfPure in p.prc.flags)): 
@@ -262,27 +260,24 @@ proc genAsmStmt(p: BProc, t: PNode) =
 
 proc getRaiseFrmt(p: BProc): string = 
   if gCmd == cmdCompileToCpp: 
-    result = "throw nimException($1, $2);$n"
+    result = "throw #nimException($1, $2);$n"
   else: 
-    useMagic(p.module, "E_Base")
-    result = "raiseException((E_Base*)$1, $2);$n"
+    result = "#raiseException((#E_Base*)$1, $2);$n"
 
 proc genRaiseStmt(p: BProc, t: PNode) = 
   genLineDir(p, t)
   if t.sons[0] != nil: 
-    if gCmd != cmdCompileToCpp: useMagic(p.module, "raiseException")
     var a: TLoc
     InitLocExpr(p, t.sons[0], a)
     var e = rdLoc(a)
     var typ = skipTypes(t.sons[0].typ, abstractPtrs)
-    appf(p.s[cpsStmts], getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)])
+    appcg(p, cpsStmts, getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)])
   else: 
     # reraise the last exception:
     if gCmd == cmdCompileToCpp: 
-      app(p.s[cpsStmts], "throw;" & tnl)
+      appcg(p, cpsStmts, "throw;" & tnl)
     else: 
-      useMagic(p.module, "reraiseException")
-      app(p.s[cpsStmts], "reraiseException();" & tnl)
+      appcg(p, cpsStmts, "#reraiseException();" & tnl)
 
 const 
   stringCaseThreshold = 100000 
@@ -300,11 +295,11 @@ proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
     if b.sons[i].kind == nkRange: 
       initLocExpr(p, b.sons[i].sons[0], x)
       initLocExpr(p, b.sons[i].sons[1], y)
-      appf(p.s[cpsStmts], rangeFormat, 
+      appcg(p, cpsStmts, rangeFormat, 
            [rdCharLoc(e), rdCharLoc(x), rdCharLoc(y), labl])
     else: 
       initLocExpr(p, b.sons[i], x)
-      appf(p.s[cpsStmts], eqFormat, [rdCharLoc(e), rdCharLoc(x), labl])
+      appcg(p, cpsStmts, eqFormat, [rdCharLoc(e), rdCharLoc(x), labl])
 
 proc genCaseSecondPass(p: BProc, t: PNode, labId: int) = 
   var Lend = getLabel(p)
@@ -373,7 +368,7 @@ proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel,
     initLocExpr(p, b.sons[i], x)
     assert(b.sons[i].kind in {nkStrLit..nkTripleStrLit})
     j = int(hashString(b.sons[i].strVal) and high(branches))
-    appf(branches[j], "if (eqStrings($1, $2)) goto $3;$n", 
+    appcg(p.module, branches[j], "if (#eqStrings($1, $2)) goto $3;$n", 
          [rdLoc(e), rdLoc(x), labl])
 
 proc genStringCase(p: BProc, t: PNode) = 
@@ -381,13 +376,11 @@ proc genStringCase(p: BProc, t: PNode) =
     strings, bitMask, labId: int
     a: TLoc
     branches: TRopeSeq
-  useMagic(p.module, "eqStrings") 
   # count how many constant strings there are in the case:
   strings = 0
   for i in countup(1, sonsLen(t) - 1): 
     if t.sons[i].kind == nkOfBranch: inc(strings, sonsLen(t.sons[i]) - 1)
   if strings > stringCaseThreshold: 
-    useMagic(p.module, "hashString")
     bitMask = math.nextPowerOfTwo(strings) - 1
     newSeq(branches, bitMask + 1)
     initLocExpr(p, t.sons[0], a) # fist pass: gnerate ifs+goto:
@@ -400,7 +393,7 @@ proc genStringCase(p: BProc, t: PNode) =
       else: 
         # else statement: nothing to do yet
         # but we reserved a label, which we use later
-    appf(p.s[cpsStmts], "switch (hashString($1) & $2) {$n", 
+    appcg(p, cpsStmts, "switch (#hashString($1) & $2) {$n", 
          [rdLoc(a), toRope(bitMask)])
     for j in countup(0, high(branches)): 
       if branches[j] != nil: 
@@ -412,7 +405,7 @@ proc genStringCase(p: BProc, t: PNode) =
     # third pass: generate statements
     genCaseSecondPass(p, t, labId)
   else: 
-    genCaseGeneric(p, t, "", "if (eqStrings($1, $2)) goto $3;$n")
+    genCaseGeneric(p, t, "", "if (#eqStrings($1, $2)) goto $3;$n")
   
 proc branchHasTooBigRange(b: PNode): bool = 
   for i in countup(0, sonsLen(b) - 2): 
@@ -588,11 +581,9 @@ proc genTryStmt(p: BProc, t: PNode) =
   #    longjmp(excHandler->context, sp.status);
   genLineDir(p, t)
   var safePoint = getTempName()
-  useMagic(p.module, "TSafePoint")
-  useMagic(p.module, "E_Base")
-  useMagic(p.module, "excHandler")
-  appf(p.s[cpsLocals], "TSafePoint $1;$n", [safePoint])
-  appf(p.s[cpsStmts], "$1.prev = excHandler;$n" & "excHandler = &$1;$n" &
+  discard cgsym(p.module, "E_Base")
+  appcg(p, cpsLocals, "#TSafePoint $1;$n", [safePoint])
+  appcg(p, cpsStmts, "$1.prev = #excHandler;$n" & "excHandler = &$1;$n" &
       "$1.status = setjmp($1.context);$n", [safePoint])
   if optStackTrace in p.Options: 
     app(p.s[cpsStmts], "framePtr = (TFrame*)&F;" & tnl)
@@ -627,9 +618,8 @@ proc genTryStmt(p: BProc, t: PNode) =
   dec(p.nestedTryStmts)
   if (i < length) and (t.sons[i].kind == nkFinally): 
     genStmts(p, t.sons[i].sons[0])
-  useMagic(p.module, "raiseException")
-  appf(p.s[cpsStmts], "if ($1.status != 0) { " &
-      "raiseException($1.exc, $1.exc->name); }$n", [safePoint])
+  appcg(p, cpsStmts, "if ($1.status != 0) { " &
+      "#raiseException($1.exc, $1.exc->name); }$n", [safePoint])
 
 var 
   breakPointId: int = 0
@@ -643,21 +633,17 @@ proc genBreakPoint(p: BProc, t: PNode) =
       name = normalize(t.sons[1].strVal)
     else: 
       inc(breakPointId)
-      name = "bp" & $(breakPointId)
+      name = "bp" & $breakPointId
     genLineDir(p, t)          # BUGFIX
-    appf(gBreakpoints, 
-         "dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [
+    appcg(p.module, gBreakpoints, 
+         "#dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [
         toRope(toLinenumber(t.info)), makeCString(toFilename(t.info)), 
         makeCString(name)])
 
 proc genPragma(p: BProc, n: PNode) = 
   for i in countup(0, sonsLen(n) - 1): 
     var it = n.sons[i]
-    var key: PNode
-    if it.kind == nkExprColonExpr: 
-      key = it.sons[0]
-    else: 
-      key = it
+    var key = if it.kind == nkExprColonExpr: it.sons[0] else: it
     if key.kind == nkIdent: 
       case whichKeyword(key.ident)
       of wBreakpoint: 
@@ -667,8 +653,7 @@ proc genPragma(p: BProc, n: PNode) =
           # we need to keep track of ``deadCodeElim`` pragma
           if (sfDeadCodeElim in p.module.module.flags): 
             addPendingModule(p.module)
-      else: 
-        nil
+      else: nil
   
 proc genAsgn(p: BProc, e: PNode) = 
   var a: TLoc
diff --git a/rod/ccgtypes.nim b/rod/ccgtypes.nim
index 5034bf67b..ca5b3990e 100755
--- a/rod/ccgtypes.nim
+++ b/rod/ccgtypes.nim
@@ -248,7 +248,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): PRope =
         internalError(typ.sym.info, "getSimpleTypeDesc: " & $(getSize(typ)))
         result = nil
   of tyString: 
-    useMagic(m, "NimStringDesc")
+    discard cgsym(m, "NimStringDesc")
     result = typeNameOrLiteral(typ, "NimStringDesc*")
   of tyCstring: result = typeNameOrLiteral(typ, "NCSTRING")
   of tyBool: result = typeNameOrLiteral(typ, "NIM_BOOL")
@@ -342,20 +342,19 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope,
   # declare the record:
   var hasField = false
   if typ.kind == tyObject: 
-    useMagic(m, "TNimType")
     if typ.sons[0] == nil: 
       if typ.sym != nil and sfPure in typ.sym.flags or tfFinal in typ.flags: 
-        result = ropef("struct $1 {$n", [name])
+        result = ropecg(m, "struct $1 {$n", [name])
       else: 
-        result = ropef("struct $1 {$nTNimType* m_type;$n", [name])
+        result = ropecg(m, "struct $1 {$n#TNimType* m_type;$n", [name])
         hasField = true
     elif gCmd == cmdCompileToCpp: 
-      result = ropef("struct $1 : public $2 {$n", 
-                     [name, getTypeDescAux(m, typ.sons[0], check)])
+      result = ropecg(m, "struct $1 : public $2 {$n", 
+                      [name, getTypeDescAux(m, typ.sons[0], check)])
       hasField = true
     else: 
-      result = ropef("struct $1 {$n  $2 Sup;$n", 
-                     [name, getTypeDescAux(m, typ.sons[0], check)])
+      result = ropecg(m, "struct $1 {$n  $2 Sup;$n", 
+                      [name, getTypeDescAux(m, typ.sons[0], check)])
       hasField = true
   else: 
     result = ropef("struct $1 {$n", [name])
@@ -446,11 +445,12 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope =
     assert(CacheGetType(m.typeCache, t) == nil)
     IdTablePut(m.typeCache, t, con(result, "*"))
     if not isImportedType(t): 
-      useMagic(m, "TGenericSeq")
       if skipTypes(t.sons[0], abstractInst).kind != tyEmpty: 
-        appf(m.s[cfsSeqTypes], "struct $2 {$n" & "  TGenericSeq Sup;$n" &
-            "  $1 data[SEQ_DECL_SIZE];$n" & "};$n", 
-             [getTypeDescAux(m, t.sons[0], check), result])
+        appcg(m, m.s[cfsSeqTypes], 
+            "struct $2 {$n" & 
+            "  #TGenericSeq Sup;$n" &
+            "  $1 data[SEQ_DECL_SIZE];$n" & 
+            "};$n", [getTypeDescAux(m, t.sons[0], check), result])
       else: 
         result = toRope("TGenericSeq")
     app(result, "*")
@@ -595,10 +595,9 @@ proc genObjectFields(m: BModule, typ: PType, n: PNode, expr: PRope) =
     assert(n.sons[0].kind == nkSym)
     field = n.sons[0].sym
     tmp = getTempName()
-    useMagic(m, "chckNil")
     appf(m.s[cfsTypeInit3], "$1.kind = 3;$n" &
         "$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
-        "chckNil($1.typ);$n" & "$1.name = $5;$n" & "$1.sons = &$6[0];$n" &
+        "$1.name = $5;$n" & "$1.sons = &$6[0];$n" &
         "$1.len = $7;$n", [expr, getTypeDesc(m, typ), field.loc.r, 
                            genTypeInfo(m, field.typ), makeCString(field.name.s), 
                            tmp, toRope(lengthOrd(field.typ))])
@@ -628,10 +627,9 @@ proc genObjectFields(m: BModule, typ: PType, n: PNode, expr: PRope) =
       else: internalError(n.info, "genObjectFields(nkRecCase)")
   of nkSym: 
     field = n.sym
-    useMagic(m, "chckNil")
     appf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
         "$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
-        "chckNil($1.typ);$n" & "$1.name = $5;$n", [expr, getTypeDesc(m, typ), 
+        "$1.name = $5;$n", [expr, getTypeDesc(m, typ), 
         field.loc.r, genTypeInfo(m, field.typ), makeCString(field.name.s)])
   else: internalError(n.info, "genObjectFields")
   
@@ -658,10 +656,9 @@ proc genTupleInfo(m: BModule, typ: PType, name: PRope) =
       a = typ.sons[i]
       tmp2 = getNimNode(m)
       appf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, toRope(i), tmp2])
-      useMagic(m, "chckNil")
       appf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
           "$1.offset = offsetof($2, Field$3);$n" & "$1.typ = $4;$n" &
-          "chckNil($1.typ);$n" & "$1.name = \"Field$3\";$n", 
+          "$1.name = \"Field$3\";$n", 
            [tmp2, getTypeDesc(m, typ), toRope(i), genTypeInfo(m, a)])
     appf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n", 
          [expr, toRope(length), tmp])
@@ -735,8 +732,8 @@ proc genTypeInfo(m: BModule, typ: PType): PRope =
   result = ropef("NTI$1", [toRope(id)])
   if not IntSetContainsOrIncl(m.typeInfoMarker, id): 
     # declare type information structures:
-    useMagic(m, "TNimType")
-    useMagic(m, "TNimNode")
+    discard cgsym(m, "TNimType")
+    discard cgsym(m, "TNimNode")
     appf(m.s[cfsVars], "extern TNimType* $1; /* $2 */$n", 
          [result, toRope(typeToString(t))])
   if dataGenerated: return 
diff --git a/rod/cgen.nim b/rod/cgen.nim
index ad322a1dd..dd1878465 100755
--- a/rod/cgen.nim
+++ b/rod/cgen.nim
@@ -169,7 +169,68 @@ proc useHeader(m: BModule, sym: PSym) =
     assert(sym.annex != nil)
     discard lists.IncludeStr(m.headerFiles, getStr(sym.annex.path))
 
-proc UseMagic(m: BModule, name: string)
+proc cgsym(m: BModule, name: string): PRope
+
+proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope = 
+  var i, j, length, start, num: int
+  i = 0
+  length = len(frmt)
+  result = nil
+  num = 0
+  while i < length: 
+    if frmt[i] == '$': 
+      inc(i)                  # skip '$'
+      case frmt[i]
+      of '$': 
+        app(result, "$")
+        inc(i)
+      of '#': 
+        inc(i)
+        app(result, args[num])
+        inc(num)
+      of '0'..'9': 
+        j = 0
+        while true: 
+          j = (j * 10) + Ord(frmt[i]) - ord('0')
+          inc(i)
+          if (i > length + 0 - 1) or not (frmt[i] in {'0'..'9'}): break 
+        num = j
+        if j > high(args) + 1: 
+          internalError("ropes: invalid format string $" & $(j))
+        app(result, args[j - 1])
+      of 'N', 'n': 
+        app(result, tnl)
+        inc(i)
+      else: InternalError("ropes: invalid format string $" & frmt[i])
+    elif frmt[i] == '#' and frmt[i+1] in IdentStartChars:
+      inc(i)
+      var j = i
+      while frmt[j] in IdentChars: inc(j)
+      var ident = copy(frmt, i, j-1)
+      i = j
+      app(result, cgsym(m, ident))
+    elif frmt[i] == '#' and frmt[i+1] == '$':
+      inc(i, 2)
+      var j = 0
+      while frmt[i] in Digits: 
+        j = (j * 10) + Ord(frmt[i]) - ord('0')
+        inc(i)
+      app(result, cgsym(m, args[j-1].ropeToStr))
+    start = i
+    while i < length: 
+      if frmt[i] != '$' and frmt[i] != '#': inc(i)
+      else: break 
+    if i - 1 >= start: 
+      app(result, copy(frmt, start, i - 1))
+
+proc appcg(m: BModule, c: var PRope, frmt: TFormatStr, args: openarray[PRope]) = 
+  app(c, ropecg(m, frmt, args))
+
+
+proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr, 
+           args: openarray[PRope]) = 
+  app(p.s[s], ropecg(p.module, frmt, args))
+
 
 include "ccgtypes.nim"
 
@@ -274,26 +335,21 @@ proc assignLocalVar(p: BProc, s: PSym) =
 proc assignGlobalVar(p: BProc, s: PSym) = 
   if s.loc.k == locNone: 
     fillLoc(s.loc, locGlobalVar, s.typ, mangleName(s), OnHeap)
-  if gCmd == cmdCompileToLLVM: 
-    appf(p.module.s[cfsVars], "$1 = linkonce global $2 zeroinitializer$n", 
-         [s.loc.r, getTypeDesc(p.module, s.loc.t)])
-    incl(s.loc.flags, lfIndirect)
-  else: 
-    useHeader(p.module, s)
-    if lfNoDecl in s.loc.flags: return 
-    if sfImportc in s.flags: app(p.module.s[cfsVars], "extern ")
-    app(p.module.s[cfsVars], getTypeDesc(p.module, s.loc.t))
-    if sfRegister in s.flags: app(p.module.s[cfsVars], " register")
-    if sfVolatile in s.flags: app(p.module.s[cfsVars], " volatile")
-    if sfThreadVar in s.flags: app(p.module.s[cfsVars], " NIM_THREADVAR")
-    appf(p.module.s[cfsVars], " $1;$n", [s.loc.r])
+  useHeader(p.module, s)
+  if lfNoDecl in s.loc.flags: return 
+  if sfImportc in s.flags: app(p.module.s[cfsVars], "extern ")
+  app(p.module.s[cfsVars], getTypeDesc(p.module, s.loc.t))
+  if sfRegister in s.flags: app(p.module.s[cfsVars], " register")
+  if sfVolatile in s.flags: app(p.module.s[cfsVars], " volatile")
+  if sfThreadVar in s.flags: app(p.module.s[cfsVars], " NIM_THREADVAR")
+  appf(p.module.s[cfsVars], " $1;$n", [s.loc.r])
   if {optStackTrace, optEndb} * p.module.module.options ==
       {optStackTrace, optEndb}: 
-    useMagic(p.module, "dbgRegisterGlobal")
-    appff(p.module.s[cfsDebugInit], "dbgRegisterGlobal($1, &$2, $3);$n", 
-          "call void @dbgRegisterGlobal(i8* $1, i8* $2, $4* $3)$n", [cstringLit(
-        p, p.module.s[cfsDebugInit], normalize(s.owner.name.s & '.' & s.name.s)), 
-        s.loc.r, genTypeInfo(p.module, s.typ), getTypeDesc(p.module, "TNimType")])
+    appcg(p.module, p.module.s[cfsDebugInit], 
+          "#dbgRegisterGlobal($1, &$2, $3);$n", 
+         [cstringLit(p, p.module.s[cfsDebugInit], 
+          normalize(s.owner.name.s & '.' & s.name.s)), 
+          s.loc.r, genTypeInfo(p.module, s.typ)])
 
 proc iff(cond: bool, the, els: PRope): PRope = 
   if cond: result = the
@@ -352,11 +408,11 @@ proc loadDynamicLib(m: BModule, lib: PLib) =
       for i in countup(0, high(s)): 
         inc(m.labels)
         if i > 0: app(loadlib, "||")
-        appf(loadlib, "($1 = nimLoadLibrary((NimStringDesc*) &$2))$n", 
-             [tmp, getStrLit(m, s[i])])
-      appf(m.s[cfsDynLibInit], 
-           "if (!($1)) nimLoadLibraryError((NimStringDesc*) &$2);$n", 
-           [loadlib, getStrLit(m, lib.path.strVal)]) 
+        appcg(m, loadlib, "($1 = #nimLoadLibrary((#NimStringDesc*) &$2))$n", 
+              [tmp, getStrLit(m, s[i])])
+      appcg(m, m.s[cfsDynLibInit], 
+            "if (!($1)) #nimLoadLibraryError((#NimStringDesc*) &$2);$n", 
+            [loadlib, getStrLit(m, lib.path.strVal)]) 
     else:
       var p = newProc(nil, m)
       var dest: TLoc
@@ -364,37 +420,38 @@ proc loadDynamicLib(m: BModule, lib: PLib) =
       app(m.s[cfsVars], p.s[cpsLocals])
       app(m.s[cfsDynLibInit], p.s[cpsInit])
       app(m.s[cfsDynLibInit], p.s[cpsStmts])
-      appf(m.s[cfsDynLibInit], 
-           "if (!($1 = nimLoadLibrary($2))) nimLoadLibraryError($2);$n", 
+      appcg(m, m.s[cfsDynLibInit], 
+           "if (!($1 = #nimLoadLibrary($2))) #nimLoadLibraryError($2);$n", 
            [tmp, rdLoc(dest)])
       
-    useMagic(m, "nimLoadLibrary")
-    useMagic(m, "nimUnloadLibrary")
-    useMagic(m, "NimStringDesc")
-    useMagic(m, "nimLoadLibraryError")
   if lib.name == nil: InternalError("loadDynamicLib")
   
+proc mangleDynLibProc(sym: PSym): PRope =
+  if sfCompilerProc in sym.flags: 
+    # NOTE: sym.loc.r is the external name!
+    result = toRope(sym.name.s)
+  else:
+    result = ropef("Dl_$1", [toRope(sym.id)])
+  
 proc SymInDynamicLib(m: BModule, sym: PSym) = 
   var lib = sym.annex
   var extname = sym.loc.r
   loadDynamicLib(m, lib)
-  useMagic(m, "nimGetProcAddr")
+  discard cgsym(m, "nimGetProcAddr")
   if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
-  var tmp = ropeff("Dl_$1", "@Dl_$1", [toRope(sym.id)])
+  var tmp = mangleDynLibProc(sym)
   sym.loc.r = tmp             # from now on we only need the internal name
   sym.typ.sym = nil           # generate a new name
   inc(m.labels, 2)
-  appff(m.s[cfsDynLibInit], 
-      "$1 = ($2) nimGetProcAddr($3, $4);$n", "%MOC$5 = load i8* $3$n" &
-      "%MOC$6 = call $2 @nimGetProcAddr(i8* %MOC$5, i8* $4)$n" &
-      "store $2 %MOC$6, $2* $1$n", [tmp, getTypeDesc(m, sym.typ), 
-      lib.name, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname)), 
-      toRope(m.labels), toRope(m.labels - 1)])
+  appf(m.s[cfsDynLibInit], 
+      "$1 = ($2) nimGetProcAddr($3, $4);$n", 
+      [tmp, getTypeDesc(m, sym.typ), 
+      lib.name, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))])
   appff(m.s[cfsVars], "$2 $1;$n", 
       "$1 = linkonce global $2 zeroinitializer$n", 
       [sym.loc.r, getTypeDesc(m, sym.loc.t)])
 
-proc UseMagic(m: BModule, name: string) = 
+proc cgsym(m: BModule, name: string): PRope = 
   var sym = magicsys.getCompilerProc(name)
   if sym != nil: 
     case sym.kind
@@ -402,8 +459,16 @@ proc UseMagic(m: BModule, name: string) =
     of skVar: genVarPrototype(m, sym)
     of skType: discard getTypeDesc(m, sym.typ)
     else: InternalError("useMagic: " & name)
-  elif not (sfSystemModule in m.module.flags): 
-    rawMessage(errSystemNeeds, name) # don't be too picky here
+  else:
+    # we used to exclude the system module from this check, but for DLL
+    # generation support this sloppyness leads to hard to detect bugs, so
+    # we're picky here for the system module too:
+    when false:
+      if not (sfSystemModule in m.module.flags): 
+        rawMessage(errSystemNeeds, name) 
+    else:
+      rawMessage(errSystemNeeds, name)
+  result = sym.loc.r
   
 proc generateHeaders(m: BModule) = 
   app(m.s[cfsHeaders], "#include \"nimbase.h\"" & tnl & tnl)
@@ -418,7 +483,7 @@ proc generateHeaders(m: BModule) =
 proc getFrameDecl(p: BProc) = 
   var slots: PRope
   if p.frameLen > 0: 
-    useMagic(p.module, "TVarSlot")
+    discard cgsym(p.module, "TVarSlot")
     slots = ropeff("  TVarSlot s[$1];$n", ", [$1 x %TVarSlot]", 
                    [toRope(p.frameLen)])
   else: 
@@ -507,7 +572,7 @@ proc genProcAux(m: BModule, prc: PSym) =
     if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM): 
       if gProcProfile >= 64 * 1024: 
         InternalError(prc.info, "too many procedures for profiling")
-      useMagic(m, "profileData")
+      discard cgsym(m, "profileData")
       app(p.s[cpsLocals], "ticks NIM_profilingStart;" & tnl)
       if prc.loc.a < 0: 
         appf(m.s[cfsDebugInit], "profileData[$1].procname = $2;$n", [
@@ -534,9 +599,9 @@ proc genProcPrototype(m: BModule, sym: PSym) =
   if lfDynamicLib in sym.loc.Flags: 
     if (sym.owner.id != m.module.id) and
         not intSetContainsOrIncl(m.declaredThings, sym.id): 
-      appff(m.s[cfsVars], "extern $1 Dl_$2;$n", 
-            "@Dl_$2 = linkonce global $1 zeroinitializer$n", 
-            [getTypeDesc(m, sym.loc.t), toRope(sym.id)])
+      appff(m.s[cfsVars], "extern $1 $2;$n", 
+            "@$2 = linkonce global $1 zeroinitializer$n", 
+            [getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)])
       if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
   else: 
     if not IntSetContainsOrIncl(m.declaredProtos, sym.id): 
@@ -679,7 +744,7 @@ proc genMainProc(m: BModule) =
         "                            i8* %lpvReserved) {$n" &
         "  call void @NimMain()$n" & "  ret i32 1$n" & "}$n"
   var nimMain, otherMain: TFormatStr
-  useMagic(m, "setStackBottom")
+  discard cgsym(m, "setStackBottom")
   if (platform.targetOS == osWindows) and
       (gGlobalOptions * {optGenGuiApp, optGenDynLib} != {}): 
     if optGenGuiApp in gGlobalOptions: 
@@ -704,7 +769,7 @@ proc genMainProc(m: BModule) =
     else: 
       nimMain = PosixNimMain
       otherMain = PosixCMain
-  if gBreakpoints != nil: useMagic(m, "dbgRegisterBreakpoint")
+  if gBreakpoints != nil: discard cgsym(m, "dbgRegisterBreakpoint")
   inc(m.labels)
   appf(m.s[cfsProcs], nimMain, [gBreakpoints, mainModInit, toRope(m.labels)])
   if not (optNoMain in gGlobalOptions): appf(m.s[cfsProcs], otherMain, [])
@@ -730,14 +795,10 @@ proc genInitCode(m: BModule) =
   prc = ropeff("N_NOINLINE(void, $1)(void) {$n", 
                "define void $1() noinline {$n", [initname])
   if m.typeNodes > 0: 
-    useMagic(m, "TNimNode")
-    appff(m.s[cfsTypeInit1], "static TNimNode $1[$2];$n", 
-          "$1 = private alloca [$2 x @TNimNode]$n", 
+    appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n", 
           [m.typeNodesName, toRope(m.typeNodes)])
   if m.nimTypes > 0: 
-    useMagic(m, "TNimType")
-    appff(m.s[cfsTypeInit1], "static TNimType $1[$2];$n", 
-          "$1 = private alloca [$2 x @TNimType]$n", 
+    appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n", 
           [m.nimTypesName, toRope(m.nimTypes)])
   if optStackTrace in m.initProc.options: 
     getFrameDecl(m.initProc)
diff --git a/rod/magicsys.nim b/rod/magicsys.nim
index 58de1d795..1d758dcde 100755
--- a/rod/magicsys.nim
+++ b/rod/magicsys.nim
@@ -1,7 +1,7 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2010 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -69,8 +69,7 @@ proc getSysType(kind: TTypeKind): PType =
   if result == nil: InternalError("type not found: " & $kind)
   
 proc getCompilerProc(name: string): PSym = 
-  var ident: PIdent
-  ident = getIdent(name, getNormalizedHash(name))
+  var ident = getIdent(name, getNormalizedHash(name))
   result = StrTableGet(compilerprocs, ident)
   if result == nil: 
     result = StrTableGet(rodCompilerProcs, ident)
diff --git a/rod/nimrod.ini b/rod/nimrod.ini
index 1574721f1..9e3445c44 100755
--- a/rod/nimrod.ini
+++ b/rod/nimrod.ini
@@ -1,8 +1,9 @@
 [Project]
 Name: "Nimrod"
 Version: "$version"
-OS: "linux;macosx;freebsd;netbsd;openbsd;solaris"
-CPU: "i386;amd64"  # ;sparc;powerpc
+; Windows and i386 must be first!
+OS: "windows" ;linux;macosx;freebsd;netbsd;openbsd;solaris"
+CPU: "i386" ;amd64"  # ;sparc;powerpc
 Authors: "Andreas Rumpf"
 Description: """This is the Nimrod Compiler. Nimrod is a new statically typed,
 imperative programming language, that supports procedural, functional, object
diff --git a/rod/pragmas.nim b/rod/pragmas.nim
index 24c5be923..9f84c7f05 100755
--- a/rod/pragmas.nim
+++ b/rod/pragmas.nim
@@ -21,13 +21,13 @@ const
   procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
     wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, 
     wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, 
-    wBorrow}
+    wBorrow, wExtern}
   converterPragmas* = procPragmas
   methodPragmas* = procPragmas
   macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
-    wMagic, wNosideEffect, wCompilerProc, wDeprecated, wTypeCheck}
+    wMagic, wNosideEffect, wCompilerProc, wDeprecated, wTypeCheck, wExtern}
   iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect, 
-    wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow}
+    wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern}
   stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, 
     wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir, 
     wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal, 
@@ -35,13 +35,15 @@ const
     wCheckpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated, wFloatChecks,
     wInfChecks, wNanChecks, wPragma}
   lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
-    wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure, wDeprecated}
+    wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure, 
+    wDeprecated, wExtern}
   typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, 
-    wPure, wHeader, wCompilerProc, wFinal, wSize}
-  fieldPragmas* = {wImportc, wExportc, wDeprecated}
+    wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern}
+  fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern}
   varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, 
-    wMagic, wHeader, wDeprecated, wCompilerProc, wDynLib}
-  constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl}
+    wMagic, wHeader, wDeprecated, wCompilerProc, wDynLib, wExtern}
+  constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
+    wExtern}
   procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect}
 
 proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords)
@@ -64,18 +66,17 @@ proc pragmaAsm(c: PContext, n: PNode): char =
         else: invalidPragma(it)
       else: 
         invalidPragma(it)
-  
-const 
-  FirstPragmaWord = wMagic
-  LastPragmaWord = wNoconv
+
+proc setExternName(s: PSym, extname: string) = 
+  s.loc.r = toRope(extname % s.name.s)
 
 proc MakeExternImport(s: PSym, extname: string) = 
-  s.loc.r = toRope(extname)
+  setExternName(s, extname)
   incl(s.flags, sfImportc)
   excl(s.flags, sfForward)
 
 proc MakeExternExport(s: PSym, extname: string) = 
-  s.loc.r = toRope(extname)
+  setExternName(s, extname)
   incl(s.flags, sfExportc)
 
 proc getStrLitNode(c: PContext, n: PNode): PNode =
@@ -356,6 +357,7 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
             makeExternExport(sym, getOptionalStr(c, it, sym.name.s))
             incl(sym.flags, sfUsed) # avoid wrong hints
           of wImportc: makeExternImport(sym, getOptionalStr(c, it, sym.name.s))
+          of wExtern: setExternName(sym, expectStrLit(c, it))
           of wAlign: 
             if sym.typ == nil: invalidPragma(it)
             sym.typ.align = expectIntLit(c, it)
diff --git a/rod/semstmts.nim b/rod/semstmts.nim
index fdf931815..e700f8e71 100755
--- a/rod/semstmts.nim
+++ b/rod/semstmts.nim
@@ -688,7 +688,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
   else: 
     if n.sons[pragmasPos] != nil: 
       liMessage(n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProc)
-    if not (sfForward in proto.flags): 
+    if sfForward notin proto.flags: 
       liMessage(n.info, errAttemptToRedefineX, proto.name.s)
     excl(proto.flags, sfForward)
     closeScope(c.tab)         # close scope with wrong parameter symbols
@@ -715,7 +715,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
       c.p = newProcCon(s)
       if (s.typ.sons[0] != nil) and (kind != skIterator): 
         addResult(c, s.typ.sons[0], n.info)
-      n.sons[codePos] = semStmtScope(c, n.sons[codePos])
+      if sfImportc notin s.flags: 
+        # no semantic checking for importc:
+        n.sons[codePos] = semStmtScope(c, n.sons[codePos])
       if (s.typ.sons[0] != nil) and (kind != skIterator): addResultNode(c, n)
     else: 
       if (s.typ.sons[0] != nil) and (kind != skIterator): 
diff --git a/rod/wordrecg.nim b/rod/wordrecg.nim
index ac7265f7d..bf2aa84f7 100755
--- a/rod/wordrecg.nim
+++ b/rod/wordrecg.nim
@@ -34,6 +34,7 @@ type
     
     wColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus, 
     wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks, wImportc, wExportc, 
+    wExtern,
     wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader, 
     wNosideeffect, wNoreturn, wMerge, wLib, wDynlib, wCompilerproc, wProcVar, 
     wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef, 
@@ -54,7 +55,7 @@ type
     wCc, wGenscript, wCheckPoint, wCheckPoints, wNoMain, wSubsChar, 
     wAcyclic, wIndex, 
     wCompileToC, wCompileToCpp, wCompileToEcmaScript, wCompileToLLVM, wPretty, 
-    wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wBoot, wLazy, 
+    wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wLazy, 
     wRst2html, wRst2tex, wI,
     wWrite, wPutEnv, wPrependEnv, wAppendEnv, wThreadVar
     
@@ -78,7 +79,8 @@ const
 
     ":", "=", ".", "..", "^", "*", "-",
     "magic", "typecheck", "final", "profiler", "objchecks", "importc", 
-    "exportc", "align", "nodecl", "pure", "volatile", "register", "sideeffect", 
+    "exportc", "extern",
+    "align", "nodecl", "pure", "volatile", "register", "sideeffect", 
     "header", "nosideeffect", "noreturn", "merge", "lib", "dynlib", 
     "compilerproc", "procvar", "fatal", "error", "warning", "hint", "line", 
     "push", "pop", "define", "undef", "linedir", "stacktrace", "linetrace", 
@@ -101,7 +103,7 @@ const
     "nomain", "subschar", "acyclic", "index", 
     "compiletoc", "compiletocpp", "compiletoecmascript", "compiletollvm", 
     "pretty", "doc", "gendepend", "listdef", "check", "parse", "scan", 
-    "boot", "lazy", "rst2html", "rst2tex", "i", 
+    "lazy", "rst2html", "rst2tex", "i", 
     "write", "putenv", "prependenv", "appendenv", "threadvar"]
 
 proc whichKeyword*(id: PIdent): TSpecialWord