summary refs log tree commit diff stats
path: root/compiler/ccgexprs.nim
diff options
context:
space:
mode:
authorClyybber <darkmine956@gmail.com>2019-11-28 17:13:04 +0100
committerAndreas Rumpf <rumpf_a@web.de>2019-11-28 17:13:04 +0100
commit7e747d11c66405f08cc7c69e5afc18348663275e (patch)
treed6277a88b503ddd503d8b769bdae6c72fcf3d27b /compiler/ccgexprs.nim
parentb662842bd04852a751993ed506f9e38155a4e4aa (diff)
downloadNim-7e747d11c66405f08cc7c69e5afc18348663275e.tar.gz
Cosmetic compiler cleanup (#12718)
* Cleanup compiler code base

* Unify add calls

* Unify len invocations

* Unify range operators

* Fix oversight

* Remove {.procvar.} pragma

* initCandidate -> newCandidate where reasonable

* Unify safeLen calls
Diffstat (limited to 'compiler/ccgexprs.nim')
-rw-r--r--compiler/ccgexprs.nim598
1 files changed, 298 insertions, 300 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 009ee7221..a95086c71 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -64,7 +64,7 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): Rope =
       if id == p.module.labels:
         # not found in cache:
         inc(p.module.labels)
-        addf(p.module.s[cfsData],
+        p.module.s[cfsData].addf(
              "static NIM_CONST $1 $2 = {NIM_NIL,NIM_NIL};$n",
              [getTypeDesc(p.module, ty), result])
     else:
@@ -98,13 +98,13 @@ proc genLiteral(p: BProc, n: PNode): Rope =
 
 proc bitSetToWord(s: TBitSet, size: int): BiggestUInt =
   result = 0
-  for j in 0 ..< size:
-    if j < len(s): result = result or (BiggestUInt(s[j]) shl (j * 8))
+  for j in 0..<size:
+    if j < s.len: result = result or (BiggestUInt(s[j]) shl (j * 8))
 
 proc genRawSetData(cs: TBitSet, size: int): Rope =
   if size > 8:
     var res = "{\n"
-    for i in 0 ..< size:
+    for i in 0..<size:
       res.add "0x"
       res.add "0123456789abcdef"[cs[i] div 16]
       res.add "0123456789abcdef"[cs[i] mod 16]
@@ -131,7 +131,7 @@ proc genSetNode(p: BProc, n: PNode): Rope =
     if id == p.module.labels:
       # not found in cache:
       inc(p.module.labels)
-      addf(p.module.s[cfsData], "static NIM_CONST $1 $2 = $3;$n",
+      p.module.s[cfsData].addf("static NIM_CONST $1 $2 = $3;$n",
            [getTypeDesc(p.module, n.typ), result, genRawSetData(cs, size)])
   else:
     result = genRawSetData(cs, size)
@@ -150,13 +150,13 @@ proc getStorageLoc(n: PNode): TStorageLoc =
       else: result = OnUnknown
     else: result = OnUnknown
   of nkDerefExpr, nkHiddenDeref:
-    case n.sons[0].typ.kind
+    case n[0].typ.kind
     of tyVar, tyLent: result = OnUnknown
     of tyPtr: result = OnStack
     of tyRef: result = OnHeap
     else: doAssert(false, "getStorageLoc")
   of nkBracketExpr, nkDotExpr, nkObjDownConv, nkObjUpConv:
-    result = getStorageLoc(n.sons[0])
+    result = getStorageLoc(n[0])
   else: result = OnUnknown
 
 proc canMove(p: BProc, n: PNode; dest: TLoc): bool =
@@ -217,8 +217,8 @@ proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
     else:
       flags
   let t = skipTypes(dest.t, abstractInst).getUniqueType()
-  for i in 0 ..< t.len:
-    let t = t.sons[i]
+  for i in 0..<t.len:
+    let t = t[i]
     let field = "Field$1" % [i.rope]
     genAssignment(p, optAsgnLoc(dest, t, field),
                      optAsgnLoc(src, t, field), newflags)
@@ -327,7 +327,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
     elif not isObjLackingTypeField(ty):
       genGenericAsgn(p, dest, src, flags)
     elif containsGarbageCollectedRef(ty):
-      if ty.sons[0].isNil and asgnComplexity(ty.n) <= 4:
+      if ty[0].isNil and asgnComplexity(ty.n) <= 4:
         discard getTypeDesc(p.module, ty)
         internalAssert p.config, ty.n != nil
         genOptAsgnObject(p, dest, src, flags, ty.n, ty)
@@ -452,47 +452,47 @@ proc putIntoDest(p: BProc, d: var TLoc, n: PNode, r: Rope; s=OnUnknown) =
 proc binaryStmt(p: BProc, e: PNode, d: var TLoc, op: string) =
   var a, b: TLoc
   if d.k != locNone: internalError(p.config, e.info, "binaryStmt")
-  initLocExpr(p, e.sons[1], a)
-  initLocExpr(p, e.sons[2], b)
+  initLocExpr(p, e[1], a)
+  initLocExpr(p, e[2], b)
   lineCg(p, cpsStmts, "$1 $2 $3;$n", [rdLoc(a), op, rdLoc(b)])
 
 proc binaryStmtAddr(p: BProc, e: PNode, d: var TLoc, cpname: string) =
   var a, b: TLoc
   if d.k != locNone: internalError(p.config, e.info, "binaryStmtAddr")
-  initLocExpr(p, e.sons[1], a)
-  initLocExpr(p, e.sons[2], b)
+  initLocExpr(p, e[1], a)
+  initLocExpr(p, e[2], b)
   lineCg(p, cpsStmts, "#$1($2, $3);$n", [cpname, byRefLoc(p, a), rdLoc(b)])
 
 template unaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a: TLoc
   if d.k != locNone: internalError(p.config, e.info, "unaryStmt")
-  initLocExpr(p, e.sons[1], a)
+  initLocExpr(p, e[1], a)
   lineCg(p, cpsStmts, frmt, [rdLoc(a)])
 
 template binaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a, b: TLoc
-  assert(e.sons[1].typ != nil)
-  assert(e.sons[2].typ != nil)
-  initLocExpr(p, e.sons[1], a)
-  initLocExpr(p, e.sons[2], b)
+  assert(e[1].typ != nil)
+  assert(e[2].typ != nil)
+  initLocExpr(p, e[1], a)
+  initLocExpr(p, e[2], b)
   putIntoDest(p, d, e, ropecg(p.module, frmt, [rdLoc(a), rdLoc(b)]))
 
 template binaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a, b: TLoc
-  assert(e.sons[1].typ != nil)
-  assert(e.sons[2].typ != nil)
-  initLocExpr(p, e.sons[1], a)
-  initLocExpr(p, e.sons[2], b)
+  assert(e[1].typ != nil)
+  assert(e[2].typ != nil)
+  initLocExpr(p, e[1], a)
+  initLocExpr(p, e[2], b)
   putIntoDest(p, d, e, ropecg(p.module, frmt, [a.rdCharLoc, b.rdCharLoc]))
 
 template unaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a: TLoc
-  initLocExpr(p, e.sons[1], a)
+  initLocExpr(p, e[1], a)
   putIntoDest(p, d, e, ropecg(p.module, frmt, [rdLoc(a)]))
 
 template unaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a: TLoc
-  initLocExpr(p, e.sons[1], a)
+  initLocExpr(p, e[1], a)
   putIntoDest(p, d, e, ropecg(p.module, frmt, [rdCharLoc(a)]))
 
 template binaryArithOverflowRaw(p: BProc, t: PType, a, b: TLoc;
@@ -522,10 +522,10 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
     ]
     opr: array[mAddI..mPred, string] = ["+", "-", "*", "/", "%", "+", "-"]
   var a, b: TLoc
-  assert(e.sons[1].typ != nil)
-  assert(e.sons[2].typ != nil)
-  initLocExpr(p, e.sons[1], a)
-  initLocExpr(p, e.sons[2], b)
+  assert(e[1].typ != nil)
+  assert(e[2].typ != nil)
+  initLocExpr(p, e[1], a)
+  initLocExpr(p, e[2], b)
   # skipping 'range' is correct here as we'll generate a proper range check
   # later via 'chckRange'
   let t = e.typ.skipTypes(abstractRange)
@@ -541,8 +541,8 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
   var
     a: TLoc
     t: PType
-  assert(e.sons[1].typ != nil)
-  initLocExpr(p, e.sons[1], a)
+  assert(e[1].typ != nil)
+  initLocExpr(p, e[1], a)
   t = skipTypes(e.typ, abstractRange)
   if optOverflowCheck in p.options:
     linefmt(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n",
@@ -561,10 +561,10 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   var
     a, b: TLoc
     s, k: BiggestInt
-  assert(e.sons[1].typ != nil)
-  assert(e.sons[2].typ != nil)
-  initLocExpr(p, e.sons[1], a)
-  initLocExpr(p, e.sons[2], b)
+  assert(e[1].typ != nil)
+  assert(e[2].typ != nil)
+  initLocExpr(p, e[1], a)
+  initLocExpr(p, e[2], b)
   # BUGFIX: cannot use result-type here, as it may be a boolean
   s = max(getSize(p.config, a.t), getSize(p.config, b.t)) * 8
   k = getSize(p.config, a.t) * 8
@@ -622,10 +622,10 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
 
 proc genEqProc(p: BProc, e: PNode, d: var TLoc) =
   var a, b: TLoc
-  assert(e.sons[1].typ != nil)
-  assert(e.sons[2].typ != nil)
-  initLocExpr(p, e.sons[1], a)
-  initLocExpr(p, e.sons[2], b)
+  assert(e[1].typ != nil)
+  assert(e[2].typ != nil)
+  initLocExpr(p, e[1], a)
+  initLocExpr(p, e[2], b)
   if a.t.skipTypes(abstractInstOwned).callConv == ccClosure:
     putIntoDest(p, d, e,
       "($1.ClP_0 == $2.ClP_0 && $1.ClE_0 == $2.ClE_0)" % [rdLoc(a), rdLoc(b)])
@@ -633,7 +633,7 @@ proc genEqProc(p: BProc, e: PNode, d: var TLoc) =
     putIntoDest(p, d, e, "($1 == $2)" % [rdLoc(a), rdLoc(b)])
 
 proc genIsNil(p: BProc, e: PNode, d: var TLoc) =
-  let t = skipTypes(e.sons[1].typ, abstractRange)
+  let t = skipTypes(e[1].typ, abstractRange)
   if t.kind == tyProc and t.callConv == ccClosure:
     unaryExpr(p, e, d, "($1.ClP_0 == 0)")
   else:
@@ -643,8 +643,8 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   var
     a: TLoc
     t: PType
-  assert(e.sons[1].typ != nil)
-  initLocExpr(p, e.sons[1], a)
+  assert(e[1].typ != nil)
+  initLocExpr(p, e[1], a)
   t = skipTypes(e.typ, abstractRange)
 
   template applyFormat(frmt: untyped) =
@@ -670,24 +670,24 @@ proc isCppRef(p: BProc; typ: PType): bool {.inline.} =
       tfVarIsPtr notin skipTypes(typ, abstractInstOwned).flags
 
 proc genDeref(p: BProc, e: PNode, d: var TLoc) =
-  let mt = mapType(p.config, e.sons[0].typ)
+  let mt = mapType(p.config, e[0].typ)
   if mt in {ctArray, ctPtrToArray} and lfEnforceDeref notin d.flags:
     # XXX the amount of hacks for C's arrays is incredible, maybe we should
     # simply wrap them in a struct? --> Losing auto vectorization then?
-    expr(p, e.sons[0], d)
-    if e.sons[0].typ.skipTypes(abstractInstOwned).kind == tyRef:
+    expr(p, e[0], d)
+    if e[0].typ.skipTypes(abstractInstOwned).kind == tyRef:
       d.storage = OnHeap
   else:
     var a: TLoc
-    var typ = e.sons[0].typ
+    var typ = e[0].typ
     if typ.kind in {tyUserTypeClass, tyUserTypeClassInst} and typ.isResolvedUserTypeClass:
       typ = typ.lastSon
     typ = typ.skipTypes(abstractInstOwned)
-    if typ.kind == tyVar and tfVarIsPtr notin typ.flags and p.module.compileToCpp and e.sons[0].kind == nkHiddenAddr:
+    if typ.kind == tyVar and tfVarIsPtr notin typ.flags and p.module.compileToCpp and e[0].kind == nkHiddenAddr:
       initLocExprSingleUse(p, e[0][0], d)
       return
     else:
-      initLocExprSingleUse(p, e.sons[0], a)
+      initLocExprSingleUse(p, e[0], a)
     if d.k == locNone:
       # dest = *a;  <-- We do not know that 'dest' is on the heap!
       # It is completely wrong to set 'd.storage' here, unless it's not yet
@@ -716,30 +716,30 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc) =
       # See tmissingderef. So we get rid of the deref instead. The codegen
       # ends up using 'memcpy' for the array assignment,
       # so the '&' and '*' cancel out:
-      putIntoDest(p, d, lodeTyp(a.t.sons[0]), rdLoc(a), a.storage)
+      putIntoDest(p, d, lodeTyp(a.t[0]), rdLoc(a), a.storage)
     else:
       putIntoDest(p, d, e, "(*$1)" % [rdLoc(a)], a.storage)
 
 proc genAddr(p: BProc, e: PNode, d: var TLoc) =
   # careful  'addr(myptrToArray)' needs to get the ampersand:
-  if e.sons[0].typ.skipTypes(abstractInstOwned).kind in {tyRef, tyPtr}:
+  if e[0].typ.skipTypes(abstractInstOwned).kind in {tyRef, tyPtr}:
     var a: TLoc
-    initLocExpr(p, e.sons[0], a)
+    initLocExpr(p, e[0], a)
     putIntoDest(p, d, e, "&" & a.r, a.storage)
     #Message(e.info, warnUser, "HERE NEW &")
-  elif mapType(p.config, e.sons[0].typ) == ctArray or isCppRef(p, e.typ):
-    expr(p, e.sons[0], d)
+  elif mapType(p.config, e[0].typ) == ctArray or isCppRef(p, e.typ):
+    expr(p, e[0], d)
   else:
     var a: TLoc
-    initLocExpr(p, e.sons[0], a)
+    initLocExpr(p, e[0], a)
     putIntoDest(p, d, e, addrLoc(p.config, a), a.storage)
 
 template inheritLocation(d: var TLoc, a: TLoc) =
   if d.k == locNone: d.storage = a.storage
 
 proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc) =
-  initLocExpr(p, e.sons[0], a)
-  if e.sons[1].kind != nkSym: internalError(p.config, e.info, "genRecordFieldAux")
+  initLocExpr(p, e[0], a)
+  if e[1].kind != nkSym: internalError(p.config, e.info, "genRecordFieldAux")
   d.inheritLocation(a)
   discard getTypeDesc(p.module, a.t) # fill the record's fields.loc
 
@@ -747,16 +747,16 @@ proc genTupleElem(p: BProc, e: PNode, d: var TLoc) =
   var
     a: TLoc
     i: int
-  initLocExpr(p, e.sons[0], a)
+  initLocExpr(p, e[0], a)
   let tupType = a.t.skipTypes(abstractInst+{tyVar})
   assert tupType.kind == tyTuple
   d.inheritLocation(a)
   discard getTypeDesc(p.module, a.t) # fill the record's fields.loc
   var r = rdLoc(a)
-  case e.sons[1].kind
-  of nkIntLit..nkUInt64Lit: i = int(e.sons[1].intVal)
+  case e[1].kind
+  of nkIntLit..nkUInt64Lit: i = int(e[1].intVal)
   else: internalError(p.config, e.info, "genTupleElem")
-  addf(r, ".Field$1", [rope(i)])
+  r.addf(".Field$1", [rope(i)])
   putIntoDest(p, d, e, r, a.storage)
 
 proc lookupFieldAgain(p: BProc, ty: PType; field: PSym; r: var Rope;
@@ -770,43 +770,43 @@ proc lookupFieldAgain(p: BProc, ty: PType; field: PSym; r: var Rope;
     if result != nil:
       if resTyp != nil: resTyp[] = ty
       break
-    if not p.module.compileToCpp: add(r, ".Sup")
-    ty = ty.sons[0]
+    if not p.module.compileToCpp: r.add(".Sup")
+    ty = ty[0]
   if result == nil: internalError(p.config, field.info, "genCheckedRecordField")
 
 proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
   var a: TLoc
   genRecordFieldAux(p, e, d, a)
   var r = rdLoc(a)
-  var f = e.sons[1].sym
+  var f = e[1].sym
   let ty = skipTypes(a.t, abstractInstOwned + tyUserTypeClasses)
   if ty.kind == tyTuple:
     # we found a unique tuple type which lacks field information
     # so we use Field$i
-    addf(r, ".Field$1", [rope(f.position)])
+    r.addf(".Field$1", [rope(f.position)])
     putIntoDest(p, d, e, r, a.storage)
   else:
     var rtyp: PType
     let field = lookupFieldAgain(p, ty, f, r, addr rtyp)
     if field.loc.r == nil and rtyp != nil: fillObjectFields(p.module, rtyp)
     if field.loc.r == nil: internalError(p.config, e.info, "genRecordField 3 " & typeToString(ty))
-    addf(r, ".$1", [field.loc.r])
+    r.addf(".$1", [field.loc.r])
     putIntoDest(p, d, e, r, a.storage)
 
 proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc)
 
 proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) =
   var test, u, v: TLoc
-  for i in 1 ..< len(e):
-    var it = e.sons[i]
+  for i in 1..<e.len:
+    var it = e[i]
     assert(it.kind in nkCallKinds)
-    assert(it.sons[0].kind == nkSym)
-    let op = it.sons[0].sym
-    if op.magic == mNot: it = it.sons[1]
-    let disc = it.sons[2].skipConv
+    assert(it[0].kind == nkSym)
+    let op = it[0].sym
+    if op.magic == mNot: it = it[1]
+    let disc = it[2].skipConv
     assert(disc.kind == nkSym)
     initLoc(test, locNone, it, OnStack)
-    initLocExpr(p, it.sons[1], u)
+    initLocExpr(p, it[1], u)
     initLoc(v, locExpr, disc, OnUnknown)
     v.r = obj
     v.r.add(".")
@@ -826,19 +826,19 @@ proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) =
 proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
   if optFieldCheck in p.options:
     var a: TLoc
-    genRecordFieldAux(p, e.sons[0], d, a)
+    genRecordFieldAux(p, e[0], d, a)
     let ty = skipTypes(a.t, abstractInst + tyUserTypeClasses)
     var r = rdLoc(a)
-    let f = e.sons[0].sons[1].sym
+    let f = e[0][1].sym
     let field = lookupFieldAgain(p, ty, f, r)
     if field.loc.r == nil: fillObjectFields(p.module, ty)
     if field.loc.r == nil:
       internalError(p.config, e.info, "genCheckedRecordField") # generate the checks:
     genFieldCheck(p, e, r, field)
-    add(r, ropecg(p.module, ".$1", [field.loc.r]))
-    putIntoDest(p, d, e.sons[0], r, a.storage)
+    r.add(ropecg(p.module, ".$1", [field.loc.r]))
+    putIntoDest(p, d, e[0], r, a.storage)
   else:
-    genRecordField(p, e.sons[0], d)
+    genRecordField(p, e[0], d)
 
 proc genUncheckedArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
   var a, b: TLoc
@@ -940,14 +940,14 @@ proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) =
               ropecg(p.module, "$1$3[$2]", [rdLoc(a), rdCharLoc(b), dataField(p)]), a.storage)
 
 proc genBracketExpr(p: BProc; n: PNode; d: var TLoc) =
-  var ty = skipTypes(n.sons[0].typ, abstractVarRange + tyUserTypeClasses)
+  var ty = skipTypes(n[0].typ, abstractVarRange + tyUserTypeClasses)
   if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
   case ty.kind
-  of tyUncheckedArray: genUncheckedArrayElem(p, n, n.sons[0], n.sons[1], d)
-  of tyArray: genArrayElem(p, n, n.sons[0], n.sons[1], d)
-  of tyOpenArray, tyVarargs: genOpenArrayElem(p, n, n.sons[0], n.sons[1], d)
-  of tySequence, tyString: genSeqElem(p, n, n.sons[0], n.sons[1], d)
-  of tyCString: genCStringElem(p, n, n.sons[0], n.sons[1], d)
+  of tyUncheckedArray: genUncheckedArrayElem(p, n, n[0], n[1], d)
+  of tyArray: genArrayElem(p, n, n[0], n[1], d)
+  of tyOpenArray, tyVarargs: genOpenArrayElem(p, n, n[0], n[1], d)
+  of tySequence, tyString: genSeqElem(p, n, n[0], n[1], d)
+  of tyCString: genCStringElem(p, n, n[0], n[1], d)
   of tyTuple: genTupleElem(p, n, d)
   else: internalError(p.config, n.info, "expr(nkBracketExpr, " & $ty.kind & ')')
   discard getTypeDesc(p.module, n.typ)
@@ -962,7 +962,7 @@ proc isSimpleExpr(n: PNode): bool =
       if not isSimpleExpr(c): return false
     result = true
   of nkStmtListExpr:
-    for i in 0..n.len-2:
+    for i in 0..<n.len-1:
       if n[i].kind notin {nkCommentStmt, nkEmpty}: return false
     result = isSimpleExpr(n.lastSon)
   else:
@@ -995,8 +995,8 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
     var tmpA, tmpB: TLoc
     #getTemp(p, e.typ, tmpA)
     #getTemp(p, e.typ, tmpB)
-    initLocExprSingleUse(p, e.sons[1], tmpA)
-    initLocExprSingleUse(p, e.sons[2], tmpB)
+    initLocExprSingleUse(p, e[1], tmpA)
+    initLocExprSingleUse(p, e[2], tmpB)
     tmpB.k = locExpr
     if m == mOr:
       tmpB.r = "((" & rdLoc(tmpA) & ")||(" & rdLoc(tmpB) & "))"
@@ -1012,13 +1012,13 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
       tmp: TLoc
     getTemp(p, e.typ, tmp)      # force it into a temp!
     inc p.splitDecls
-    expr(p, e.sons[1], tmp)
+    expr(p, e[1], tmp)
     L = getLabel(p)
     if m == mOr:
       lineF(p, cpsStmts, "if ($1) goto $2;$n", [rdLoc(tmp), L])
     else:
       lineF(p, cpsStmts, "if (!($1)) goto $2;$n", [rdLoc(tmp), L])
-    expr(p, e.sons[2], tmp)
+    expr(p, e[2], tmp)
     fixLabel(p, L)
     if d.k == locNone:
       d = tmp
@@ -1036,10 +1036,10 @@ proc genEcho(p: BProc, n: PNode) =
     var a: TLoc
     for it in n.sons:
       if it.skipConv.kind == nkNilLit:
-        add(args, ", \"\"")
+        args.add(", \"\"")
       else:
         initLocExpr(p, it, a)
-        add(args, ropecg(p.module, ", Genode::Cstring($1->data, $1->len)", [rdLoc(a)]))
+        args.add(ropecg(p.module, ", Genode::Cstring($1->data, $1->len)", [rdLoc(a)]))
     p.module.includeHeader("<base/log.h>")
     p.module.includeHeader("<util/string.h>")
     linefmt(p, cpsStmts, """Genode::log(""$1);$n""", [args])
@@ -1087,21 +1087,21 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
   var L = 0
   var appends: Rope = nil
   var lens: Rope = nil
-  for i in 0 .. len(e) - 2:
+  for i in 0..<e.len - 1:
     # compute the length expression:
-    initLocExpr(p, e.sons[i + 1], a)
-    if skipTypes(e.sons[i + 1].typ, abstractVarRange).kind == tyChar:
+    initLocExpr(p, e[i + 1], a)
+    if skipTypes(e[i + 1].typ, abstractVarRange).kind == tyChar:
       inc(L)
-      add(appends, ropecg(p.module, "#appendChar($1, $2);$n", [strLoc(p, tmp), rdLoc(a)]))
+      appends.add(ropecg(p.module, "#appendChar($1, $2);$n", [strLoc(p, tmp), rdLoc(a)]))
     else:
-      if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
-        inc(L, len(e.sons[i + 1].strVal))
+      if e[i + 1].kind in {nkStrLit..nkTripleStrLit}:
+        inc(L, e[i + 1].strVal.len)
       else:
-        add(lens, lenExpr(p, a))
-        add(lens, " + ")
-      add(appends, ropecg(p.module, "#appendString($1, $2);$n", [strLoc(p, tmp), rdLoc(a)]))
+        lens.add(lenExpr(p, a))
+        lens.add(" + ")
+      appends.add(ropecg(p.module, "#appendString($1, $2);$n", [strLoc(p, tmp), rdLoc(a)]))
   linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, L])
-  add(p.s(cpsStmts), appends)
+  p.s(cpsStmts).add appends
   if d.k == locNone:
     d = tmp
   else:
@@ -1125,21 +1125,21 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
     appends, lens: Rope
   assert(d.k == locNone)
   var L = 0
-  initLocExpr(p, e.sons[1], dest)
-  for i in 0 .. len(e) - 3:
+  initLocExpr(p, e[1], dest)
+  for i in 0..<e.len - 2:
     # compute the length expression:
-    initLocExpr(p, e.sons[i + 2], a)
-    if skipTypes(e.sons[i + 2].typ, abstractVarRange).kind == tyChar:
+    initLocExpr(p, e[i + 2], a)
+    if skipTypes(e[i + 2].typ, abstractVarRange).kind == tyChar:
       inc(L)
-      add(appends, ropecg(p.module, "#appendChar($1, $2);$n",
+      appends.add(ropecg(p.module, "#appendChar($1, $2);$n",
                         [strLoc(p, dest), rdLoc(a)]))
     else:
-      if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}:
-        inc(L, len(e.sons[i + 2].strVal))
+      if e[i + 2].kind in {nkStrLit..nkTripleStrLit}:
+        inc(L, e[i + 2].strVal.len)
       else:
-        add(lens, lenExpr(p, a))
-        add(lens, " + ")
-      add(appends, ropecg(p.module, "#appendString($1, $2);$n",
+        lens.add(lenExpr(p, a))
+        lens.add(" + ")
+      appends.add(ropecg(p.module, "#appendString($1, $2);$n",
                         [strLoc(p, dest), rdLoc(a)]))
   if optSeqDestructors in p.config.globalOptions:
     linefmt(p, cpsStmts, "#prepareAdd($1, $2$3);$n",
@@ -1149,33 +1149,33 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
     call.r = ropecg(p.module, "#resizeString($1, $2$3)", [rdLoc(dest), lens, L])
     genAssignment(p, dest, call, {})
     gcUsage(p.config, e)
-  add(p.s(cpsStmts), appends)
+  p.s(cpsStmts).add appends
 
 proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
   # seq &= x  -->
   #    seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x));
   #    seq->data[seq->len-1] = x;
   var a, b, dest, tmpL, call: TLoc
-  initLocExpr(p, e.sons[1], a)
-  initLocExpr(p, e.sons[2], b)
-  let seqType = skipTypes(e.sons[1].typ, {tyVar})
+  initLocExpr(p, e[1], a)
+  initLocExpr(p, e[2], b)
+  let seqType = skipTypes(e[1].typ, {tyVar})
   initLoc(call, locCall, e, OnHeap)
   if not p.module.compileToCpp:
     const seqAppendPattern = "($2) #incrSeqV3((TGenericSeq*)($1), $3)"
     call.r = ropecg(p.module, seqAppendPattern, [rdLoc(a),
-      getTypeDesc(p.module, e.sons[1].typ),
+      getTypeDesc(p.module, e[1].typ),
       genTypeInfo(p.module, seqType, e.info)])
   else:
     const seqAppendPattern = "($2) #incrSeqV3($1, $3)"
     call.r = ropecg(p.module, seqAppendPattern, [rdLoc(a),
-      getTypeDesc(p.module, e.sons[1].typ),
+      getTypeDesc(p.module, e[1].typ),
       genTypeInfo(p.module, seqType, e.info)])
   # emit the write barrier if required, but we can always move here, so
   # use 'genRefAssign' for the seq.
   genRefAssign(p, a, call)
   #if bt != b.t:
   #  echo "YES ", e.info, " new: ", typeToString(bt), " old: ", typeToString(b.t)
-  initLoc(dest, locExpr, e.sons[2], OnHeap)
+  initLoc(dest, locExpr, e[2], OnHeap)
   getIntTemp(p, tmpL)
   lineCg(p, cpsStmts, "$1 = $2->$3++;$n", [tmpL.r, rdLoc(a), lenField(p)])
   dest.r = ropecg(p.module, "$1$3[$2]", [rdLoc(a), tmpL.r, dataField(p)])
@@ -1184,7 +1184,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
 
 proc genReset(p: BProc, n: PNode) =
   var a: TLoc
-  initLocExpr(p, n.sons[1], a)
+  initLocExpr(p, n[1], a)
   linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
           [addrLoc(p.config, a),
           genTypeInfo(p.module, skipTypes(a.t, {tyVar}), n.info)])
@@ -1220,7 +1220,7 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
           "to have the 'nimcall' calling convention")
       var f: TLoc
       initLocExpr(p, newSymNode(bt.destructor), f)
-      addf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
+      p.module.s[cfsTypeInit3].addf("$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
 
     if a.storage == OnHeap and usesWriteBarrier(p.config):
       if canFormAcycle(a.t):
@@ -1245,11 +1245,11 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
 
 proc genNew(p: BProc, e: PNode) =
   var a: TLoc
-  initLocExpr(p, e.sons[1], a)
+  initLocExpr(p, e[1], a)
   # 'genNew' also handles 'unsafeNew':
   if e.len == 3:
     var se: TLoc
-    initLocExpr(p, e.sons[2], se)
+    initLocExpr(p, e[2], se)
     rawGenNew(p, a, se.rdLoc)
   else:
     rawGenNew(p, a, nil)
@@ -1284,10 +1284,10 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope; lenIsZero: bool) =
 
 proc genNewSeq(p: BProc, e: PNode) =
   var a, b: TLoc
-  initLocExpr(p, e.sons[1], a)
-  initLocExpr(p, e.sons[2], b)
+  initLocExpr(p, e[1], a)
+  initLocExpr(p, e[2], b)
   if optSeqDestructors in p.config.globalOptions:
-    let seqtype = skipTypes(e.sons[1].typ, abstractVarRange)
+    let seqtype = skipTypes(e[1].typ, abstractVarRange)
     linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
       [a.rdLoc, b.rdLoc, getTypeDesc(p.module, seqtype.lastSon),
       getSeqPayloadType(p.module, seqtype)])
@@ -1300,7 +1300,7 @@ proc genNewSeq(p: BProc, e: PNode) =
 proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
   let seqtype = skipTypes(e.typ, abstractVarRange)
   var a: TLoc
-  initLocExpr(p, e.sons[1], a)
+  initLocExpr(p, e[1], a)
   if optSeqDestructors in p.config.globalOptions:
     if d.k == locNone: getTemp(p, e.typ, d, needsInit=false)
     linefmt(p, cpsStmts, "$1.len = 0; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
@@ -1323,7 +1323,7 @@ proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool =
     if id == p.module.labels:
       # expression not found in the cache:
       inc(p.module.labels)
-      addf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
+      p.module.s[cfsData].addf("NIM_CONST $1 $2 = $3;$n",
            [getTypeDesc(p.module, t), d.r, genConstExpr(p, n)])
     result = true
   else:
@@ -1361,25 +1361,25 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
     r = rdLoc(d)
   discard getTypeDesc(p.module, t)
   let ty = getUniqueType(t)
-  for i in 1 ..< e.len:
-    let it = e.sons[i]
+  for i in 1..<e.len:
+    let it = e[i]
     var tmp2: TLoc
     tmp2.r = r
-    let field = lookupFieldAgain(p, ty, it.sons[0].sym, tmp2.r)
+    let field = lookupFieldAgain(p, ty, it[0].sym, tmp2.r)
     if field.loc.r == nil: fillObjectFields(p.module, ty)
     if field.loc.r == nil: internalError(p.config, e.info, "genObjConstr")
     if it.len == 3 and optFieldCheck in p.options:
-      genFieldCheck(p, it.sons[2], r, field)
-    add(tmp2.r, ".")
-    add(tmp2.r, field.loc.r)
+      genFieldCheck(p, it[2], r, field)
+    tmp2.r.add(".")
+    tmp2.r.add(field.loc.r)
     if useTemp:
       tmp2.k = locTemp
       tmp2.storage = if isRef: OnHeap else: OnStack
     else:
       tmp2.k = d.k
       tmp2.storage = if isRef: OnHeap else: d.storage
-    tmp2.lode = it.sons[1]
-    expr(p, it.sons[1], tmp2)
+    tmp2.lode = it[1]
+    expr(p, it[1], tmp2)
   if useTemp:
     if d.k == locNone:
       d = tmp
@@ -1400,7 +1400,7 @@ proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) =
   elif d.k == locNone:
     getTemp(p, n.typ, d)
 
-  let l = intLiteral(len(n))
+  let l = intLiteral(n.len)
   if optSeqDestructors in p.config.globalOptions:
     let seqtype = n.typ
     linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
@@ -1410,7 +1410,7 @@ proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) =
     # generate call to newSeq before adding the elements per hand:
     genNewSeqAux(p, dest[], l,
       optNilSeqs notin p.options and n.len == 0)
-  for i in 0 ..< len(n):
+  for i in 0..<n.len:
     initLoc(arr, locExpr, n[i], OnHeap)
     arr.r = ropecg(p.module, "$1$3[$2]", [rdLoc(dest[]), intLiteral(i), dataField(p)])
     arr.storage = OnHeap            # we know that sequences are on the heap
@@ -1424,14 +1424,14 @@ proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) =
 
 proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
   var elem, a, arr: TLoc
-  if n.sons[1].kind == nkBracket:
-    n.sons[1].typ = n.typ
-    genSeqConstr(p, n.sons[1], d)
+  if n[1].kind == nkBracket:
+    n[1].typ = n.typ
+    genSeqConstr(p, n[1], d)
     return
   if d.k == locNone:
     getTemp(p, n.typ, d)
   # generate call to newSeq before adding the elements per hand:
-  let L = toInt(lengthOrd(p.config, n.sons[1].typ))
+  let L = toInt(lengthOrd(p.config, n[1].typ))
   if optSeqDestructors in p.config.globalOptions:
     let seqtype = n.typ
     linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
@@ -1439,14 +1439,14 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
       getSeqPayloadType(p.module, seqtype)])
   else:
     genNewSeqAux(p, d, intLiteral(L), optNilSeqs notin p.options and L == 0)
-  initLocExpr(p, n.sons[1], a)
+  initLocExpr(p, n[1], a)
   # bug #5007; do not produce excessive C source code:
   if L < 10:
-    for i in 0 ..< L:
+    for i in 0..<L:
       initLoc(elem, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), OnHeap)
       elem.r = ropecg(p.module, "$1$3[$2]", [rdLoc(d), intLiteral(i), dataField(p)])
       elem.storage = OnHeap # we know that sequences are on the heap
-      initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n.sons[1].typ, abstractInst)), a.storage)
+      initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n[1].typ, abstractInst)), a.storage)
       arr.r = ropecg(p.module, "$1[$2]", [rdLoc(a), intLiteral(i)])
       genAssignment(p, elem, arr, {needToCopy})
   else:
@@ -1456,7 +1456,7 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
     initLoc(elem, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), OnHeap)
     elem.r = ropecg(p.module, "$1$3[$2]", [rdLoc(d), rdLoc(i), dataField(p)])
     elem.storage = OnHeap # we know that sequences are on the heap
-    initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n.sons[1].typ, abstractInst)), a.storage)
+    initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n[1].typ, abstractInst)), a.storage)
     arr.r = ropecg(p.module, "$1[$2]", [rdLoc(a), rdLoc(i)])
     genAssignment(p, elem, arr, {needToCopy})
     lineF(p, cpsStmts, "}$n", [])
@@ -1467,12 +1467,12 @@ proc genNewFinalize(p: BProc, e: PNode) =
     a, b, f: TLoc
     refType, bt: PType
     ti: Rope
-  refType = skipTypes(e.sons[1].typ, abstractVarRange)
-  initLocExpr(p, e.sons[1], a)
-  initLocExpr(p, e.sons[2], f)
+  refType = skipTypes(e[1].typ, abstractVarRange)
+  initLocExpr(p, e[1], a)
+  initLocExpr(p, e[2], f)
   initLoc(b, locExpr, a.lode, OnHeap)
   ti = genTypeInfo(p.module, refType, e.info)
-  addf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
+  p.module.s[cfsTypeInit3].addf("$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
   b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
       getTypeDesc(p.module, refType),
       ti, getTypeDesc(p.module, skipTypes(refType.lastSon, abstractRange))])
@@ -1496,7 +1496,7 @@ proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo): Rope =
       discard cgsym(p.module, "TNimType")
       inc p.module.labels
       let cache = "Nim_OfCheck_CACHE" & p.module.labels.rope
-      addf(p.module.s[cfsVars], "static TNimType* $#[2];$n", [cache])
+      p.module.s[cfsVars].addf("static TNimType* $#[2];$n", [cache])
       result = ropecg(p.module, "#isObjWithCache($#.m_type, $#, $#)", [a, ti, cache])
     when false:
       # former version:
@@ -1517,9 +1517,9 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
     t = skipTypes(t.lastSon, typedescInst+{tyOwned})
   discard getTypeDesc(p.module, t)
   if not p.module.compileToCpp:
-    while t.kind == tyObject and t.sons[0] != nil:
-      add(r, ~".Sup")
-      t = skipTypes(t.sons[0], skipPtrs)
+    while t.kind == tyObject and t[0] != nil:
+      r.add(~".Sup")
+      t = skipTypes(t[0], skipPtrs)
   if isObjLackingTypeField(t):
     globalError(p.config, x.info,
       "no 'of' operator available for pure objects")
@@ -1530,14 +1530,14 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
   putIntoDest(p, d, x, r, a.storage)
 
 proc genOf(p: BProc, n: PNode, d: var TLoc) =
-  genOf(p, n.sons[1], n.sons[2].typ, d)
+  genOf(p, n[1], n[2].typ, d)
 
 proc genRepr(p: BProc, e: PNode, d: var TLoc) =
   if optTinyRtti in p.config.globalOptions:
     localError(p.config, e.info, "'repr' is not available for --newruntime")
   var a: TLoc
-  initLocExpr(p, e.sons[1], a)
-  var t = skipTypes(e.sons[1].typ, abstractVarRange)
+  initLocExpr(p, e[1], a)
+  var t = skipTypes(e[1].typ, abstractVarRange)
   case t.kind
   of tyInt..tyInt64, tyUInt..tyUInt64:
     putIntoDest(p, d, e,
@@ -1568,7 +1568,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
     of tyArray:
       putIntoDest(p, b, e,
                   "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, a.t))], a.storage)
-    else: internalError(p.config, e.sons[0].info, "genRepr()")
+    else: internalError(p.config, e[0].info, "genRepr()")
     putIntoDest(p, d, e,
         ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b),
         genTypeInfo(p.module, elemType(t), e.info)]), a.storage)
@@ -1585,12 +1585,12 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
   gcUsage(p.config, e)
 
 proc genGetTypeInfo(p: BProc, e: PNode, d: var TLoc) =
-  let t = e.sons[1].typ
+  let t = e[1].typ
   putIntoDest(p, d, e, genTypeInfo(p.module, t, e.info))
 
 template genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
   var a: TLoc
-  initLocExpr(p, n.sons[1], a)
+  initLocExpr(p, n[1], a)
   a.r = ropecg(p.module, frmt, [rdLoc(a)])
   a.flags = a.flags - {lfIndirect} # this flag should not be propagated here (not just for HCR)
   if d.k == locNone: getTemp(p, n.typ, d)
@@ -1598,8 +1598,8 @@ template genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
   gcUsage(p.config, n)
 
 proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
-  var a = e.sons[1]
-  if a.kind == nkHiddenAddr: a = a.sons[0]
+  var a = e[1]
+  if a.kind == nkHiddenAddr: a = a[0]
   var typ = skipTypes(a.typ, abstractVar + tyUserTypeClasses)
   case typ.kind
   of tyOpenArray, tyVarargs:
@@ -1621,7 +1621,7 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
     else: unaryExpr(p, e, d, "($1 ? #nimCStrLen($1) : 0)")
   of tyString:
     var a: TLoc
-    initLocExpr(p, e.sons[1], a)
+    initLocExpr(p, e[1], a)
     var x = lenExpr(p, a)
     if op == mHigh: x = "($1-1)" % [x]
     putIntoDest(p, d, e, x)
@@ -1653,16 +1653,16 @@ proc makeAddr(n: PNode): PNode =
 
 proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
   if optSeqDestructors in p.config.globalOptions:
-    e.sons[1] = makeAddr(e[1])
+    e[1] = makeAddr(e[1])
     genCall(p, e, d)
     return
   var a, b, call: TLoc
   assert(d.k == locNone)
-  var x = e.sons[1]
+  var x = e[1]
   if x.kind in {nkAddr, nkHiddenAddr}: x = x[0]
   initLocExpr(p, x, a)
-  initLocExpr(p, e.sons[2], b)
-  let t = skipTypes(e.sons[1].typ, {tyVar})
+  initLocExpr(p, e[2], b)
+  let t = skipTypes(e[1].typ, {tyVar})
 
   initLoc(call, locCall, e, OnHeap)
   if not p.module.compileToCpp:
@@ -1686,8 +1686,8 @@ proc genSetLengthStr(p: BProc, e: PNode, d: var TLoc) =
   else:
     var a, b, call: TLoc
     if d.k != locNone: internalError(p.config, e.info, "genSetLengthStr")
-    initLocExpr(p, e.sons[1], a)
-    initLocExpr(p, e.sons[2], b)
+    initLocExpr(p, e[1], a)
+    initLocExpr(p, e[2], b)
 
     initLoc(call, locCall, e, OnHeap)
     call.r = ropecg(p.module, "#setLengthStr($1, $2)", [
@@ -1701,9 +1701,9 @@ proc genSwap(p: BProc, e: PNode, d: var TLoc) =
   # a = b
   # b = temp
   var a, b, tmp: TLoc
-  getTemp(p, skipTypes(e.sons[1].typ, abstractVar), tmp)
-  initLocExpr(p, e.sons[1], a) # eval a
-  initLocExpr(p, e.sons[2], b) # eval b
+  getTemp(p, skipTypes(e[1].typ, abstractVar), tmp)
+  initLocExpr(p, e[1], a) # eval a
+  initLocExpr(p, e[2], b) # eval b
   genAssignment(p, tmp, a, {})
   genAssignment(p, a, b, {})
   genAssignment(p, b, tmp, {})
@@ -1726,13 +1726,13 @@ proc fewCmps(conf: ConfigRef; s: PNode): bool =
   elif elemType(s.typ).kind in {tyInt, tyInt16..tyInt64}:
     result = true             # better not emit the set if int is basetype!
   else:
-    result = len(s) <= 8  # 8 seems to be a good value
+    result = s.len <= 8  # 8 seems to be a good value
 
 template binaryExprIn(p: BProc, e: PNode, a, b, d: var TLoc, frmt: string) =
   putIntoDest(p, d, e, frmt % [rdLoc(a), rdSetElemLoc(p.config, b, a.t)])
 
 proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) =
-  case int(getSize(p.config, skipTypes(e.sons[1].typ, abstractVar)))
+  case int(getSize(p.config, skipTypes(e[1].typ, abstractVar)))
   of 1: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&7U)))!=0)")
   of 2: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&15U)))!=0)")
   of 4: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&31U)))!=0)")
@@ -1742,47 +1742,46 @@ proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) =
 template binaryStmtInExcl(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   var a, b: TLoc
   assert(d.k == locNone)
-  initLocExpr(p, e.sons[1], a)
-  initLocExpr(p, e.sons[2], b)
+  initLocExpr(p, e[1], a)
+  initLocExpr(p, e[2], b)
   lineF(p, cpsStmts, frmt, [rdLoc(a), rdSetElemLoc(p.config, b, a.t)])
 
 proc genInOp(p: BProc, e: PNode, d: var TLoc) =
   var a, b, x, y: TLoc
-  if (e.sons[1].kind == nkCurly) and fewCmps(p.config, e.sons[1]):
+  if (e[1].kind == nkCurly) and fewCmps(p.config, e[1]):
     # a set constructor but not a constant set:
     # do not emit the set, but generate a bunch of comparisons; and if we do
     # so, we skip the unnecessary range check: This is a semantical extension
     # that code now relies on. :-/ XXX
-    let ea = if e.sons[2].kind in {nkChckRange, nkChckRange64}:
-               e.sons[2].sons[0]
+    let ea = if e[2].kind in {nkChckRange, nkChckRange64}:
+               e[2][0]
              else:
-               e.sons[2]
+               e[2]
     initLocExpr(p, ea, a)
     initLoc(b, locExpr, e, OnUnknown)
-    var length = len(e.sons[1])
-    if length > 0:
+    if e[1].len > 0:
       b.r = rope("(")
-      for i in 0 ..< length:
-        let it = e.sons[1].sons[i]
+      for i in 0..<e[1].len:
+        let it = e[1][i]
         if it.kind == nkRange:
-          initLocExpr(p, it.sons[0], x)
-          initLocExpr(p, it.sons[1], y)
-          addf(b.r, "$1 >= $2 && $1 <= $3",
+          initLocExpr(p, it[0], x)
+          initLocExpr(p, it[1], y)
+          b.r.addf("$1 >= $2 && $1 <= $3",
                [rdCharLoc(a), rdCharLoc(x), rdCharLoc(y)])
         else:
           initLocExpr(p, it, x)
-          addf(b.r, "$1 == $2", [rdCharLoc(a), rdCharLoc(x)])
-        if i < length - 1: add(b.r, " || ")
-      add(b.r, ")")
+          b.r.addf("$1 == $2", [rdCharLoc(a), rdCharLoc(x)])
+        if i < e[1].len - 1: b.r.add(" || ")
+      b.r.add(")")
     else:
       # handle the case of an empty set
       b.r = rope("0")
     putIntoDest(p, d, e, b.r)
   else:
-    assert(e.sons[1].typ != nil)
-    assert(e.sons[2].typ != nil)
-    initLocExpr(p, e.sons[1], a)
-    initLocExpr(p, e.sons[2], b)
+    assert(e[1].typ != nil)
+    assert(e[2].typ != nil)
+    initLocExpr(p, e[1], a)
+    initLocExpr(p, e[2], b)
     genInExprAux(p, e, a, b, d)
 
 proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
@@ -1800,7 +1799,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
       "& ~",
       "^"]
   var a, b, i: TLoc
-  var setType = skipTypes(e.sons[1].typ, abstractVar)
+  var setType = skipTypes(e[1].typ, abstractVar)
   var size = int(getSize(p.config, setType))
   case size
   of 1, 2, 4, 8:
@@ -1838,12 +1837,12 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
     of mExcl: binaryStmtInExcl(p, e, d, "$1[(NU)($2)>>3] &= ~(1U<<($2&7U));$n")
     of mCard:
       var a: TLoc
-      initLocExpr(p, e.sons[1], a)
+      initLocExpr(p, e[1], a)
       putIntoDest(p, d, e, ropecg(p.module, "#cardSet($1, $2)", [rdCharLoc(a), size]))
     of mLtSet, mLeSet:
       getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i) # our counter
-      initLocExpr(p, e.sons[1], a)
-      initLocExpr(p, e.sons[2], b)
+      initLocExpr(p, e[1], a)
+      initLocExpr(p, e[2], b)
       if d.k == locNone: getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyBool), d)
       if op == mLtSet:
         linefmt(p, cpsStmts, lookupOpr[mLtSet],
@@ -1853,16 +1852,16 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
            [rdLoc(i), size, rdLoc(d), rdLoc(a), rdLoc(b)])
     of mEqSet:
       var a, b: TLoc
-      assert(e.sons[1].typ != nil)
-      assert(e.sons[2].typ != nil)
-      initLocExpr(p, e.sons[1], a)
-      initLocExpr(p, e.sons[2], b)
+      assert(e[1].typ != nil)
+      assert(e[2].typ != nil)
+      initLocExpr(p, e[1], a)
+      initLocExpr(p, e[2], b)
       putIntoDest(p, d, e, ropecg(p.module, "(#nimCmpMem($1, $2, $3)==0)", [a.rdCharLoc, b.rdCharLoc, size]))
     of mMulSet, mPlusSet, mMinusSet, mSymDiffSet:
       # we inline the simple for loop for better code generation:
       getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i) # our counter
-      initLocExpr(p, e.sons[1], a)
-      initLocExpr(p, e.sons[2], b)
+      initLocExpr(p, e[1], a)
+      initLocExpr(p, e[2], b)
       if d.k == locNone: getTemp(p, setType, d)
       lineF(p, cpsStmts,
            "for ($1 = 0; $1 < $2; $1++) $n" &
@@ -1881,9 +1880,9 @@ proc genSomeCast(p: BProc, e: PNode, d: var TLoc) =
   # we use whatever C gives us. Except if we have a value-type, we need to go
   # through its address:
   var a: TLoc
-  initLocExpr(p, e.sons[1], a)
+  initLocExpr(p, e[1], a)
   let etyp = skipTypes(e.typ, abstractRange+{tyOwned})
-  let srcTyp = skipTypes(e.sons[1].typ, abstractRange)
+  let srcTyp = skipTypes(e[1].typ, abstractRange)
   if etyp.kind in ValueTypes and lfIndirect notin a.flags:
     putIntoDest(p, d, e, "(*($1*) ($2))" %
         [getTypeDesc(p.module, e.typ), addrLoc(p.config, a)], a.storage)
@@ -1906,7 +1905,7 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) =
   const ValueTypes = {tyFloat..tyFloat128, tyTuple, tyObject, tyArray}
   let
     destt = skipTypes(e.typ, abstractRange)
-    srct = skipTypes(e.sons[1].typ, abstractRange)
+    srct = skipTypes(e[1].typ, abstractRange)
   if destt.kind in ValueTypes or srct.kind in ValueTypes:
     # 'cast' and some float type involved? --> use a union.
     inc(p.labels)
@@ -1914,12 +1913,12 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) =
     var tmp: TLoc
     tmp.r = "LOC$1.source" % [lbl]
     linefmt(p, cpsLocals, "union { $1 source; $2 dest; } LOC$3;$n",
-      [getTypeDesc(p.module, e.sons[1].typ), getTypeDesc(p.module, e.typ), lbl])
+      [getTypeDesc(p.module, e[1].typ), getTypeDesc(p.module, e.typ), lbl])
     tmp.k = locExpr
     tmp.lode = lodeTyp srct
     tmp.storage = OnStack
     tmp.flags = {}
-    expr(p, e.sons[1], tmp)
+    expr(p, e[1], tmp)
     putIntoDest(p, d, e, "LOC$#.dest" % [lbl], tmp.storage)
   else:
     # I prefer the shorter cast version for pointer types -> generate less
@@ -1931,27 +1930,27 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
   var dest = skipTypes(n.typ, abstractVar)
   if optRangeCheck notin p.options or (dest.kind in {tyUInt..tyUInt64} and
       checkUnsignedConversions notin p.config.legacyFeatures):
-    initLocExpr(p, n.sons[0], a)
+    initLocExpr(p, n[0], a)
     putIntoDest(p, d, n, "(($1) ($2))" %
         [getTypeDesc(p.module, dest), rdCharLoc(a)], a.storage)
   else:
     let mm = if dest.kind in {tyUInt32, tyUInt64, tyUInt}: "chckRangeU" else: magic
-    initLocExpr(p, n.sons[0], a)
+    initLocExpr(p, n[0], a)
     putIntoDest(p, d, lodeTyp 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),
+        genLiteral(p, n[1], dest), genLiteral(p, n[2], dest),
         mm]), a.storage)
 
 proc genConv(p: BProc, e: PNode, d: var TLoc) =
   let destType = e.typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink})
-  if sameBackendType(destType, e.sons[1].typ):
-    expr(p, e.sons[1], d)
+  if sameBackendType(destType, e[1].typ):
+    expr(p, e[1], d)
   else:
     genSomeCast(p, e, d)
 
 proc convStrToCStr(p: BProc, n: PNode, d: var TLoc) =
   var a: TLoc
-  initLocExpr(p, n.sons[0], a)
+  initLocExpr(p, n[0], a)
   putIntoDest(p, d, n,
               ropecg(p.module, "#nimToCStringConv($1)", [rdLoc(a)]),
 #                "($1 ? $1->data : (NCSTRING)\"\")" % [a.rdLoc],
@@ -1959,7 +1958,7 @@ proc convStrToCStr(p: BProc, n: PNode, d: var TLoc) =
 
 proc convCStrToStr(p: BProc, n: PNode, d: var TLoc) =
   var a: TLoc
-  initLocExpr(p, n.sons[0], a)
+  initLocExpr(p, n[0], a)
   putIntoDest(p, d, n,
               ropecg(p.module, "#cstrToNimstr($1)", [rdLoc(a)]),
               a.storage)
@@ -1967,14 +1966,14 @@ proc convCStrToStr(p: BProc, n: PNode, d: var TLoc) =
 
 proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
   var x: TLoc
-  var a = e.sons[1]
-  var b = e.sons[2]
+  var a = e[1]
+  var b = e[2]
   if a.kind in {nkStrLit..nkTripleStrLit} and a.strVal == "":
-    initLocExpr(p, e.sons[2], x)
+    initLocExpr(p, e[2], x)
     putIntoDest(p, d, e,
       ropecg(p.module, "($1 == 0)", [lenExpr(p, x)]))
   elif b.kind in {nkStrLit..nkTripleStrLit} and b.strVal == "":
-    initLocExpr(p, e.sons[1], x)
+    initLocExpr(p, e[1], x)
     putIntoDest(p, d, e,
       ropecg(p.module, "($1 == 0)", [lenExpr(p, x)]))
   else:
@@ -1984,10 +1983,10 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
   if {optNaNCheck, optInfCheck} * p.options != {}:
     const opr: array[mAddF64..mDivF64, string] = ["+", "-", "*", "/"]
     var a, b: TLoc
-    assert(e.sons[1].typ != nil)
-    assert(e.sons[2].typ != nil)
-    initLocExpr(p, e.sons[1], a)
-    initLocExpr(p, e.sons[2], b)
+    assert(e[1].typ != nil)
+    assert(e[2].typ != nil)
+    initLocExpr(p, e[1], a)
+    initLocExpr(p, e[2], b)
     putIntoDest(p, d, e, ropecg(p.module, "(($4)($2) $1 ($4)($3))",
                               [opr[m], rdLoc(a), rdLoc(b),
                               getSimpleTypeDesc(p.module, e[1].typ)]))
@@ -2100,21 +2099,21 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
                                                "subInt64"]
     const fun: array[mInc..mDec, string] = ["addInt",
                                              "subInt"]
-    let underlying = skipTypes(e.sons[1].typ, {tyGenericInst, tyAlias, tySink, tyVar, tyLent, tyRange})
+    let underlying = skipTypes(e[1].typ, {tyGenericInst, tyAlias, tySink, tyVar, tyLent, tyRange})
     if optOverflowCheck notin p.options or underlying.kind in {tyUInt..tyUInt64}:
       binaryStmt(p, e, d, opr[op])
     else:
       var a, b: TLoc
-      assert(e.sons[1].typ != nil)
-      assert(e.sons[2].typ != nil)
-      initLocExpr(p, e.sons[1], a)
-      initLocExpr(p, e.sons[2], b)
+      assert(e[1].typ != nil)
+      assert(e[2].typ != nil)
+      initLocExpr(p, e[1], a)
+      initLocExpr(p, e[2], b)
 
-      let ranged = skipTypes(e.sons[1].typ, {tyGenericInst, tyAlias, tySink, tyVar, tyLent})
+      let ranged = skipTypes(e[1].typ, {tyGenericInst, tyAlias, tySink, tyVar, tyLent})
       let res = binaryArithOverflowRaw(p, ranged, a, b,
         if underlying.kind == tyInt64: fun64[op] else: fun[op])
 
-      putIntoDest(p, a, e.sons[1], "($#)($#)" % [
+      putIntoDest(p, a, e[1], "($#)($#)" % [
         getTypeDesc(p.module, ranged), res])
 
   of mConStrStr: genStrConcat(p, e, d)
@@ -2124,14 +2123,14 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
     else:
       var dest, b, call: TLoc
       initLoc(call, locCall, e, OnHeap)
-      initLocExpr(p, e.sons[1], dest)
-      initLocExpr(p, e.sons[2], b)
+      initLocExpr(p, e[1], dest)
+      initLocExpr(p, e[2], b)
       call.r = ropecg(p.module, "#addChar($1, $2)", [rdLoc(dest), rdLoc(b)])
       genAssignment(p, dest, call, {})
   of mAppendStrStr: genStrAppend(p, e, d)
   of mAppendSeqElem:
     if optSeqDestructors in p.config.globalOptions:
-      e.sons[1] = makeAddr(e[1])
+      e[1] = makeAddr(e[1])
       genCall(p, e, d)
     else:
       genSeqElemAppend(p, e, d)
@@ -2145,7 +2144,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   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, mUnown: expr(p, e.sons[1], d)
+  of mStrToStr, mUnown: expr(p, e[1], d)
   of mEnumToStr:
     if optTinyRtti in p.config.globalOptions:
       genEnumToStr(p, e, d)
@@ -2157,10 +2156,10 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mNewSeq: genNewSeq(p, e)
   of mNewSeqOfCap: genNewSeqOfCap(p, e, d)
   of mSizeOf:
-    let t = e.sons[1].typ.skipTypes({tyTypeDesc})
+    let t = e[1].typ.skipTypes({tyTypeDesc})
     putIntoDest(p, d, e, "((NI)sizeof($1))" % [getTypeDesc(p.module, t)])
   of mAlignOf:
-    let t = e.sons[1].typ.skipTypes({tyTypeDesc})
+    let t = e[1].typ.skipTypes({tyTypeDesc})
     if not p.module.compileToCpp:
       p.module.includeHeader("<stdalign.h>")
     putIntoDest(p, d, e, "((NI)alignof($1))" % [getTypeDesc(p.module, t)])
@@ -2209,7 +2208,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mCopyStr, mCopyStrLast:
     genCall(p, e, d)
   of mNewString, mNewStringOfCap, mExit, mParseBiggestFloat:
-    var opr = e.sons[0].sym
+    var opr = e[0].sym
     # Why would anyone want to set nodecl to one of these hardcoded magics?
     # - not sure, and it wouldn't work if the symbol behind the magic isn't
     #   somehow forward-declared from some other usage, but it is *possible*
@@ -2230,7 +2229,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
       discard cgsym(p.module, $opr.loc.r)
       # make sure we have pointer-initialising code for hot code reloading
       if not wasDeclared and p.hcrOn:
-        addf(p.module.s[cfsDynLibInit], "\t$1 = ($2) hcrGetProc($3, \"$1\");$n",
+        p.module.s[cfsDynLibInit].addf("\t$1 = ($2) hcrGetProc($3, \"$1\");$n",
              [mangleDynLibProc(prc), getTypeDesc(p.module, prc.loc.t), getModuleDllPath(p.module, prc)])
     genCall(p, e, d)
   of mDefault: genDefault(p, e, d)
@@ -2238,7 +2237,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mEcho: genEcho(p, e[1].skipConv)
   of mArrToSeq: genArrToSeq(p, e, d)
   of mNLen..mNError, mSlurp..mQuoteAst:
-    localError(p.config, e.info, strutils.`%`(errXMustBeCompileTime, e.sons[0].sym.name.s))
+    localError(p.config, e.info, strutils.`%`(errXMustBeCompileTime, e[0].sym.name.s))
   of mSpawn:
     when defined(leanCompiler):
       quit "compiler built without support for the 'spawn' statement"
@@ -2255,7 +2254,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
     var a, b: TLoc
     let x = if e[1].kind in {nkAddr, nkHiddenAddr}: e[1][0] else: e[1]
     initLocExpr(p, x, a)
-    initLocExpr(p, e.sons[2], b)
+    initLocExpr(p, e[2], b)
     genDeepCopy(p, a, b)
   of mDotDot, mEqCString: genCall(p, e, d)
   of mWasMoved: genWasMoved(p, e)
@@ -2288,8 +2287,8 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) =
       for it in e.sons:
         if it.kind == nkRange:
           getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), idx) # our counter
-          initLocExpr(p, it.sons[0], a)
-          initLocExpr(p, it.sons[1], b)
+          initLocExpr(p, it[0], a)
+          initLocExpr(p, it[1], b)
           lineF(p, cpsStmts, "for ($1 = $3; $1 <= $4; $1++) $n" &
               "$2[(NU)($1)>>3] |=(1U<<((NU)($1)&7U));$n", [rdLoc(idx), rdLoc(d),
               rdSetElemLoc(p.config, a, e.typ), rdSetElemLoc(p.config, b, e.typ)])
@@ -2304,8 +2303,8 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) =
       for it in e.sons:
         if it.kind == nkRange:
           getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), idx) # our counter
-          initLocExpr(p, it.sons[0], a)
-          initLocExpr(p, it.sons[1], b)
+          initLocExpr(p, it[0], a)
+          initLocExpr(p, it[1], b)
           lineF(p, cpsStmts, "for ($1 = $3; $1 <= $4; $1++) $n" &
               "$2 |=(($5)(1)<<(($1)%(sizeof($5)*8)));$n", [
               rdLoc(idx), rdLoc(d), rdSetElemLoc(p.config, a, e.typ),
@@ -2322,17 +2321,17 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) =
     let t = n.typ
     discard getTypeDesc(p.module, t) # so that any fields are initialized
     if d.k == locNone: getTemp(p, t, d)
-    for i in 0 ..< len(n):
-      var it = n.sons[i]
-      if it.kind == nkExprColonExpr: it = it.sons[1]
+    for i in 0..<n.len:
+      var it = n[i]
+      if it.kind == nkExprColonExpr: it = it[1]
       initLoc(rec, locExpr, it, d.storage)
       rec.r = "$1.Field$2" % [rdLoc(d), rope(i)]
       rec.flags.incl(lfEnforceDeref)
       expr(p, it, rec)
 
 proc isConstClosure(n: PNode): bool {.inline.} =
-  result = n.sons[0].kind == nkSym and isRoutine(n.sons[0].sym) and
-      n.sons[1].kind == nkNilLit
+  result = n[0].kind == nkSym and isRoutine(n[0].sym) and
+      n[1].kind == nkNilLit
 
 proc genClosure(p: BProc, n: PNode, d: var TLoc) =
   assert n.kind in {nkPar, nkTupleConstr, nkClosure}
@@ -2340,14 +2339,14 @@ proc genClosure(p: BProc, n: PNode, d: var TLoc) =
   if isConstClosure(n):
     inc(p.module.labels)
     var tmp = "CNSTCLOSURE" & rope(p.module.labels)
-    addf(p.module.s[cfsData], "static NIM_CONST $1 $2 = $3;$n",
+    p.module.s[cfsData].addf("static NIM_CONST $1 $2 = $3;$n",
         [getTypeDesc(p.module, n.typ), tmp, genConstExpr(p, n)])
     putIntoDest(p, d, n, tmp, OnStatic)
   else:
     var tmp, a, b: TLoc
-    initLocExpr(p, n.sons[0], a)
-    initLocExpr(p, n.sons[1], b)
-    if n.sons[0].skipConv.kind == nkClosure:
+    initLocExpr(p, n[0], a)
+    initLocExpr(p, n[1], b)
+    if n[0].skipConv.kind == nkClosure:
       internalError(p.config, n.info, "closure to closure created")
     # tasyncawait.nim breaks with this optimization:
     when false:
@@ -2364,10 +2363,10 @@ proc genArrayConstr(p: BProc, n: PNode, d: var TLoc) =
   var arr: TLoc
   if not handleConstExpr(p, n, d):
     if d.k == locNone: getTemp(p, n.typ, d)
-    for i in 0 ..< len(n):
+    for i in 0..<n.len:
       initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), d.storage)
       arr.r = "$1[$2]" % [rdLoc(d), intLiteral(i)]
-      expr(p, n.sons[i], arr)
+      expr(p, n[i], arr)
 
 proc genComplexConst(p: BProc, sym: PSym, d: var TLoc) =
   requestConstImpl(p, sym)
@@ -2380,7 +2379,7 @@ template genStmtListExprImpl(exprOrStmt) {.dirty.} =
       sfSystemModule notin p.module.module.flags and
       optStackTrace in p.prc.options
   var frameName: Rope = nil
-  for i in 0 .. n.len - 2:
+  for i in 0..<n.len - 1:
     let it = n[i]
     if it.kind == nkComesFrom:
       if hasNimFrame and frameName == nil:
@@ -2394,19 +2393,19 @@ template genStmtListExprImpl(exprOrStmt) {.dirty.} =
       genStmts(p, it)
   if n.len > 0: exprOrStmt
   if frameName != nil:
-    add p.s(cpsStmts), deinitFrameNoDebug(p, frameName)
+    p.s(cpsStmts).add deinitFrameNoDebug(p, frameName)
 
 proc genStmtListExpr(p: BProc, n: PNode, d: var TLoc) =
   genStmtListExprImpl:
-    expr(p, n[n.len - 1], d)
+    expr(p, n[^1], d)
 
 proc genStmtList(p: BProc, n: PNode) =
   genStmtListExprImpl:
-    genStmts(p, n[n.len - 1])
+    genStmts(p, n[^1])
 
 proc upConv(p: BProc, n: PNode, d: var TLoc) =
   var a: TLoc
-  initLocExpr(p, n.sons[0], a)
+  initLocExpr(p, n[0], a)
   let dest = skipTypes(n.typ, abstractPtrs)
   if optObjCheck in p.options and not isObjLackingTypeField(dest):
     var r = rdLoc(a)
@@ -2419,9 +2418,9 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
       t = skipTypes(t.lastSon, abstractInst)
     discard getTypeDesc(p.module, t)
     if not p.module.compileToCpp:
-      while t.kind == tyObject and t.sons[0] != nil:
-        add(r, ".Sup")
-        t = skipTypes(t.sons[0], skipPtrs)
+      while t.kind == tyObject and t[0] != nil:
+        r.add(".Sup")
+        t = skipTypes(t[0], skipPtrs)
     let checkFor = if optTinyRtti in p.config.globalOptions:
                      genTypeInfo2Name(p.module, dest)
                    else:
@@ -2432,7 +2431,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
     else:
       linefmt(p, cpsStmts, "#chckObj($1.m_type, $2);$n",
               [r, checkFor])
-  if n.sons[0].typ.kind != tyObject:
+  if n[0].typ.kind != tyObject:
     putIntoDest(p, d, n,
                 "(($1) ($2))" % [getTypeDesc(p.module, n.typ), rdLoc(a)], a.storage)
   else:
@@ -2442,12 +2441,12 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
 proc downConv(p: BProc, n: PNode, d: var TLoc) =
   if p.module.compileToCpp:
     discard getTypeDesc(p.module, skipTypes(n[0].typ, abstractPtrs))
-    expr(p, n.sons[0], d)     # downcast does C++ for us
+    expr(p, n[0], d)     # downcast does C++ for us
   else:
     var dest = skipTypes(n.typ, abstractPtrs)
 
-    var arg = n.sons[0]
-    while arg.kind == nkObjDownConv: arg = arg.sons[0]
+    var arg = n[0]
+    while arg.kind == nkObjDownConv: arg = arg[0]
 
     var src = skipTypes(arg.typ, abstractPtrs)
     discard getTypeDesc(p.module, src)
@@ -2456,10 +2455,10 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
     var r = rdLoc(a)
     let isRef = skipTypes(arg.typ, abstractInstOwned).kind in {tyRef, tyPtr, tyVar, tyLent}
     if isRef:
-      add(r, "->Sup")
+      r.add("->Sup")
     else:
-      add(r, ".Sup")
-    for i in 2 .. abs(inheritanceDiff(dest, src)): add(r, ".Sup")
+      r.add(".Sup")
+    for i in 2..abs(inheritanceDiff(dest, src)): r.add(".Sup")
     if isRef:
       # it can happen that we end up generating '&&x->Sup' here, so we pack
       # the '&x->Sup' into a temporary and then those address is taken
@@ -2484,7 +2483,7 @@ proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
   if id == p.module.labels:
     # expression not found in the cache:
     inc(p.module.labels)
-    addf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
+    p.module.s[cfsData].addf("NIM_CONST $1 $2 = $3;$n",
          [getTypeDesc(p.module, t), tmp, genConstExpr(p, n)])
 
   if d.k == locNone:
@@ -2574,7 +2573,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
   of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkPostfix, nkCommand,
      nkCallStrLit:
     genLineDir(p, n) # may be redundant, it is generated in fixupCall as well
-    let op = n.sons[0]
+    let op = n[0]
     if n.typ.isNil:
       # discard the value:
       var a: TLoc
@@ -2621,7 +2620,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
   of nkIfExpr, nkIfStmt: genIf(p, n, d)
   of nkWhen:
     # This should be a "when nimvm" node.
-    expr(p, n.sons[1].sons[0], d)
+    expr(p, n[1][0], d)
   of nkObjDownConv: downConv(p, n, d)
   of nkObjUpConv: upConv(p, n, d)
   of nkChckRangeF: genRangeChck(p, n, d, "chckRangeF")
@@ -2630,7 +2629,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
   of nkStringToCString: convStrToCStr(p, n, d)
   of nkCStringToString: convCStrToStr(p, n, d)
   of nkLambdaKinds:
-    var sym = n.sons[namePos].sym
+    var sym = n[namePos].sym
     genProc(p.module, sym)
     if sym.loc.r == nil or sym.loc.lode == nil:
       internalError(p.config, n.info, "expr: proc not init " & sym.name.s)
@@ -2678,8 +2677,8 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
   of nkPragma: genPragma(p, n)
   of nkPragmaBlock: expr(p, n.lastSon, d)
   of nkProcDef, nkFuncDef, nkMethodDef, nkConverterDef:
-    if n.sons[genericParamsPos].kind == nkEmpty:
-      var prc = n.sons[namePos].sym
+    if n[genericParamsPos].kind == nkEmpty:
+      var prc = n[namePos].sym
       # due to a bug/limitation in the lambda lifting, unused inner procs
       # are not transformed correctly. We work around this issue (#411) here
       # by ensuring it's no inner proc (owner is a module):
@@ -2699,7 +2698,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
   else: internalError(p.config, n.info, "expr(" & $n.kind & "); unknown node kind")
 
 proc genNamedConstExpr(p: BProc, n: PNode): Rope =
-  if n.kind == nkExprColonExpr: result = genConstExpr(p, n.sons[1])
+  if n.kind == nkExprColonExpr: result = genConstExpr(p, n[1])
   else: result = genConstExpr(p, n)
 
 proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo): Rope =
@@ -2728,9 +2727,9 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo): Rope =
       result = rope"{}"
   of tyTuple:
     result = rope"{"
-    for i in 0 ..< typ.len:
+    for i in 0..<typ.len:
       if i > 0: result.add ", "
-      result.add getDefaultValue(p, typ.sons[i], info)
+      result.add getDefaultValue(p, typ[i], info)
     result.add "}"
   of tyArray: result = rope"{}"
   of tySet:
@@ -2746,9 +2745,9 @@ proc getNullValueAux(p: BProc; t: PType; obj, cons: PNode,
     for it in obj.sons:
       getNullValueAux(p, t, it, cons, result, count)
   of nkRecCase:
-    getNullValueAux(p, t, obj.sons[0], cons, result, count)
-    for i in 1 ..< len(obj):
-      getNullValueAux(p, t, lastSon(obj.sons[i]), cons, result, count)
+    getNullValueAux(p, t, obj[0], cons, result, count)
+    for i in 1..<obj.len:
+      getNullValueAux(p, t, lastSon(obj[i]), cons, result, count)
   of nkSym:
     if count > 0: result.add ", "
     inc count
@@ -2768,7 +2767,7 @@ proc getNullValueAux(p: BProc; t: PType; obj, cons: PNode,
 
 proc getNullValueAuxT(p: BProc; orig, t: PType; obj, cons: PNode,
                       result: var Rope; count: var int) =
-  var base = t.sons[0]
+  var base = t[0]
   let oldRes = result
   if not p.module.compileToCpp: result.add "{"
   let oldcount = count
@@ -2776,7 +2775,7 @@ proc getNullValueAuxT(p: BProc; orig, t: PType; obj, cons: PNode,
     base = skipTypes(base, skipPtrs)
     getNullValueAuxT(p, orig, base, base.n, cons, result, count)
   elif not isObjLackingTypeField(t) and not p.module.compileToCpp:
-    addf(result, "$1", [genTypeInfo(p.module, orig, obj.info)])
+    result.addf("$1", [genTypeInfo(p.module, orig, obj.info)])
     inc count
   getNullValueAux(p, t, obj, cons, result, count)
   # do not emit '{}' as that is not valid C:
@@ -2788,34 +2787,33 @@ proc genConstObjConstr(p: BProc; n: PNode): Rope =
   let t = n.typ.skipTypes(abstractInstOwned)
   var count = 0
   #if not isObjLackingTypeField(t) and not p.module.compileToCpp:
-  #  addf(result, "{$1}", [genTypeInfo(p.module, t)])
+  #  result.addf("{$1}", [genTypeInfo(p.module, t)])
   #  inc count
   getNullValueAuxT(p, t, t, t.n, n, result, count)
   if p.module.compileToCpp:
     result = "{$1}$n" % [result]
 
 proc genConstSimpleList(p: BProc, n: PNode): Rope =
-  var length = len(n)
   result = rope("{")
-  for i in 0 .. length - 2:
-    addf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])])
-  if length > 0:
-    add(result, genNamedConstExpr(p, n.sons[length - 1]))
-  addf(result, "}$n", [])
+  for i in 0..<n.len - 1:
+    result.addf("$1,$n", [genNamedConstExpr(p, n[i])])
+  if n.len > 0:
+    result.add(genNamedConstExpr(p, n[^1]))
+  result.addf("}$n", [])
 
 proc genConstSeq(p: BProc, n: PNode, t: PType): Rope =
   var data = "{{$1, $1 | NIM_STRLIT_FLAG}" % [n.len.rope]
   if n.len > 0:
     # array part needs extra curlies:
     data.add(", {")
-    for i in 0 ..< n.len:
+    for i in 0..<n.len:
       if i > 0: data.addf(",$n", [])
-      data.add genConstExpr(p, n.sons[i])
+      data.add genConstExpr(p, n[i])
     data.add("}")
   data.add("}")
 
   result = getTempName(p.module)
-  let base = t.skipTypes(abstractInst).sons[0]
+  let base = t.skipTypes(abstractInst)[0]
 
   appcg(p.module, cfsData,
         "NIM_CONST struct {$n" &
@@ -2828,25 +2826,25 @@ proc genConstSeq(p: BProc, n: PNode, t: PType): Rope =
 
 proc genConstSeqV2(p: BProc, n: PNode, t: PType): Rope =
   var data = rope"{"
-  for i in 0 ..< n.len:
+  for i in 0..<n.len:
     if i > 0: data.addf(",$n", [])
-    data.add genConstExpr(p, n.sons[i])
+    data.add genConstExpr(p, n[i])
   data.add("}")
 
   let payload = getTempName(p.module)
-  let base = t.skipTypes(abstractInst).sons[0]
+  let base = t.skipTypes(abstractInst)[0]
 
   appcg(p.module, cfsData,
     "static const struct {$n" &
     "  NI cap; void* allocator; $1 data[$2];$n" &
     "} $3 = {$2, NIM_NIL, $4};$n", [
-    getTypeDesc(p.module, base), len(n), payload, data])
-  result = "{$1, ($2*)&$3}" % [rope(len(n)), getSeqPayloadType(p.module, t), payload]
+    getTypeDesc(p.module, base), n.len, payload, data])
+  result = "{$1, ($2*)&$3}" % [rope(n.len), getSeqPayloadType(p.module, t), payload]
 
 proc genConstExpr(p: BProc, n: PNode): Rope =
   case n.kind
   of nkHiddenStdConv, nkHiddenSubConv:
-    result = genConstExpr(p, n.sons[1])
+    result = genConstExpr(p, n[1])
   of nkCurly:
     var cs: TBitSet
     toBitSet(p.config, n, cs)
@@ -2859,7 +2857,7 @@ proc genConstExpr(p: BProc, n: PNode): Rope =
       else:
         result = genConstSeq(p, n, n.typ)
     elif t.kind == tyProc and t.callConv == ccClosure and n.len > 1 and
-         n.sons[1].kind == nkNilLit:
+         n[1].kind == nkNilLit:
       # Conversion: nimcall -> closure.
       # this hack fixes issue that nkNilLit is expanded to {NIM_NIL,NIM_NIL}
       # this behaviour is needed since closure_var = nil must be