summary refs log tree commit diff stats
path: root/compiler/transf.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/transf.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/transf.nim')
-rw-r--r--compiler/transf.nim531
1 files changed, 254 insertions, 277 deletions
diff --git a/compiler/transf.nim b/compiler/transf.nim
index c998b53b5..68ef464c4 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -29,14 +29,12 @@ proc transformBody*(g: ModuleGraph, prc: PSym, cache: bool): PNode
 import closureiters, lambdalifting
 
 type
-  PTransNode* = distinct PNode
-
   PTransCon = ref TTransCon
   TTransCon{.final.} = object # part of TContext; stackable
     mapping: TIdNodeTable     # mapping from symbols to nodes
     owner: PSym               # current owner
     forStmt: PNode            # current for stmt
-    forLoopBody: PTransNode   # transformed for loop body
+    forLoopBody: PNode   # transformed for loop body
     yieldStmts: int           # we count the number of yield statements,
                               # because we need to introduce new variables
                               # if we encounter the 2nd yield statement
@@ -52,39 +50,22 @@ type
     graph: ModuleGraph
   PTransf = ref TTransfContext
 
-proc newTransNode(a: PNode): PTransNode {.inline.} =
-  result = PTransNode(shallowCopy(a))
+proc newTransNode(a: PNode): PNode {.inline.} =
+  result = shallowCopy(a)
 
 proc newTransNode(kind: TNodeKind, info: TLineInfo,
-                  sons: int): PTransNode {.inline.} =
+                  sons: int): PNode {.inline.} =
   var x = newNodeI(kind, info)
   newSeq(x.sons, sons)
-  result = x.PTransNode
+  result = x
 
 proc newTransNode(kind: TNodeKind, n: PNode,
-                  sons: int): PTransNode {.inline.} =
+                  sons: int): PNode {.inline.} =
   var x = newNodeIT(kind, n.info, n.typ)
   newSeq(x.sons, sons)
   x.typ = n.typ
 #  x.flags = n.flags
-  result = x.PTransNode
-
-proc add(a, b: PTransNode) {.inline.} = addSon(PNode(a), PNode(b))
-proc len(a: PTransNode): int {.inline.} = len(a.PNode)
-
-proc `[]=`(a: PTransNode, i: int, x: PTransNode) {.inline.} =
-  var n = PNode(a)
-  n.sons[i] = PNode(x)
-
-proc `[]=`(a: PTransNode, i: BackwardsIndex, x: PTransNode) {.inline.} =
-  `[]=`(a, a.len - i.int, x)
-
-proc `[]`(a: PTransNode, i: int): PTransNode {.inline.} =
-  var n = PNode(a)
-  result = n.sons[i].PTransNode
-
-proc `[]`(a: PTransNode, i: BackwardsIndex): PTransNode {.inline.} =
-  `[]`(a, a.len - i.int)
+  result = x
 
 proc newTransCon(owner: PSym): PTransCon =
   assert owner != nil
@@ -114,16 +95,16 @@ proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PNode =
   else:
     result = newSymNode(r)
 
-proc transform(c: PTransf, n: PNode): PTransNode
+proc transform(c: PTransf, n: PNode): PNode
 
-proc transformSons(c: PTransf, n: PNode): PTransNode =
+proc transformSons(c: PTransf, n: PNode): PNode =
   result = newTransNode(n)
-  for i in 0 ..< len(n):
-    result[i] = transform(c, n.sons[i])
+  for i in 0..<n.len:
+    result[i] = transform(c, n[i])
 
-proc newAsgnStmt(c: PTransf, kind: TNodeKind, le: PNode, ri: PTransNode): PTransNode =
-  result = newTransNode(kind, PNode(ri).info, 2)
-  result[0] = PTransNode(le)
+proc newAsgnStmt(c: PTransf, kind: TNodeKind, le: PNode, ri: PNode): PNode =
+  result = newTransNode(kind, ri.info, 2)
+  result[0] = le
   result[1] = ri
 
 proc transformSymAux(c: PTransf, n: PNode): PNode =
@@ -160,8 +141,8 @@ proc transformSymAux(c: PTransf, n: PNode): PNode =
     tc = tc.next
   result = b
 
-proc transformSym(c: PTransf, n: PNode): PTransNode =
-  result = PTransNode(transformSymAux(c, n))
+proc transformSym(c: PTransf, n: PNode): PNode =
+  result = transformSymAux(c, n)
 
 proc freshVar(c: PTransf; v: PSym): PNode =
   let owner = getCurrOwner(c)
@@ -173,25 +154,25 @@ proc freshVar(c: PTransf; v: PSym): PNode =
     newVar.owner = owner
     result = newSymNode(newVar)
 
-proc transformVarSection(c: PTransf, v: PNode): PTransNode =
+proc transformVarSection(c: PTransf, v: PNode): PNode =
   result = newTransNode(v)
-  for i in 0 ..< len(v):
-    var it = v.sons[i]
+  for i in 0..<v.len:
+    var it = v[i]
     if it.kind == nkCommentStmt:
-      result[i] = PTransNode(it)
+      result[i] = it
     elif it.kind == nkIdentDefs:
-      if it.sons[0].kind == nkSym:
+      if it[0].kind == nkSym:
         internalAssert(c.graph.config, it.len == 3)
-        let x = freshVar(c, it.sons[0].sym)
-        idNodeTablePut(c.transCon.mapping, it.sons[0].sym, x)
+        let x = freshVar(c, it[0].sym)
+        idNodeTablePut(c.transCon.mapping, it[0].sym, x)
         var defs = newTransNode(nkIdentDefs, it.info, 3)
         if importantComments(c.graph.config):
           # keep documentation information:
-          PNode(defs).comment = it.comment
-        defs[0] = x.PTransNode
-        defs[1] = it.sons[1].PTransNode
-        defs[2] = transform(c, it.sons[2])
-        if x.kind == nkSym: x.sym.ast = defs[2].PNode
+          defs.comment = it.comment
+        defs[0] = x
+        defs[1] = it[1]
+        defs[2] = transform(c, it[2])
+        if x.kind == nkSym: x.sym.ast = defs[2]
         result[i] = defs
       else:
         # has been transformed into 'param.x' for closure iterators, so just
@@ -200,65 +181,64 @@ proc transformVarSection(c: PTransf, v: PNode): PTransNode =
     else:
       if it.kind != nkVarTuple:
         internalError(c.graph.config, it.info, "transformVarSection: not nkVarTuple")
-      var L = len(it)
-      var defs = newTransNode(it.kind, it.info, L)
-      for j in 0 .. L-3:
+      var defs = newTransNode(it.kind, it.info, it.len)
+      for j in 0..<it.len-2:
         if it[j].kind == nkSym:
-          let x = freshVar(c, it.sons[j].sym)
-          idNodeTablePut(c.transCon.mapping, it.sons[j].sym, x)
-          defs[j] = x.PTransNode
+          let x = freshVar(c, it[j].sym)
+          idNodeTablePut(c.transCon.mapping, it[j].sym, x)
+          defs[j] = x
         else:
           defs[j] = transform(c, it[j])
-      assert(it.sons[L-2].kind == nkEmpty)
-      defs[L-2] = newNodeI(nkEmpty, it.info).PTransNode
-      defs[L-1] = transform(c, it.sons[L-1])
+      assert(it[^2].kind == nkEmpty)
+      defs[^2] = newNodeI(nkEmpty, it.info)
+      defs[^1] = transform(c, it[^1])
       result[i] = defs
 
-proc transformConstSection(c: PTransf, v: PNode): PTransNode =
-  result = PTransNode(v)
+proc transformConstSection(c: PTransf, v: PNode): PNode =
+  result = v
   when false:
     result = newTransNode(v)
-    for i in 0 ..< len(v):
-      var it = v.sons[i]
+    for i in 0..<v.len:
+      var it = v[i]
       if it.kind == nkCommentStmt:
-        result[i] = PTransNode(it)
+        result[i] = it
       else:
         if it.kind != nkConstDef: internalError(c.graph.config, it.info, "transformConstSection")
-        if it.sons[0].kind != nkSym:
-          debug it.sons[0]
+        if it[0].kind != nkSym:
+          debug it[0]
           internalError(c.graph.config, it.info, "transformConstSection")
 
-        result[i] = PTransNode(it)
+        result[i] = it
 
 proc hasContinue(n: PNode): bool =
   case n.kind
   of nkEmpty..nkNilLit, nkForStmt, nkParForStmt, nkWhileStmt: discard
   of nkContinueStmt: result = true
   else:
-    for i in 0 ..< len(n):
-      if hasContinue(n.sons[i]): return true
+    for i in 0..<n.len:
+      if hasContinue(n[i]): return true
 
 proc newLabel(c: PTransf, n: PNode): PSym =
   result = newSym(skLabel, nil, getCurrOwner(c), n.info)
   result.name = getIdent(c.graph.cache, genPrefix & $result.id)
 
-proc transformBlock(c: PTransf, n: PNode): PTransNode =
+proc transformBlock(c: PTransf, n: PNode): PNode =
   var labl: PSym
   if c.inlining > 0:
     labl = newLabel(c, n[0])
     idNodeTablePut(c.transCon.mapping, n[0].sym, newSymNode(labl))
   else:
     labl =
-      if n.sons[0].kind != nkEmpty:
-        n.sons[0].sym  # already named block? -> Push symbol on the stack
+      if n[0].kind != nkEmpty:
+        n[0].sym  # already named block? -> Push symbol on the stack
       else:
         newLabel(c, n)
   c.breakSyms.add(labl)
   result = transformSons(c, n)
   discard c.breakSyms.pop
-  result[0] = newSymNode(labl).PTransNode
+  result[0] = newSymNode(labl)
 
-proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
+proc transformLoopBody(c: PTransf, n: PNode): PNode =
   # What if it contains "continue" and "break"? "break" needs
   # an explicit label too, but not the same!
 
@@ -270,41 +250,41 @@ proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
     c.contSyms.add(labl)
 
     result = newTransNode(nkBlockStmt, n.info, 2)
-    result[0] = newSymNode(labl).PTransNode
+    result[0] = newSymNode(labl)
     result[1] = transform(c, n)
     discard c.contSyms.pop()
   else:
     result = transform(c, n)
 
-proc transformWhile(c: PTransf; n: PNode): PTransNode =
+proc transformWhile(c: PTransf; n: PNode): PNode =
   if c.inlining > 0:
     result = transformSons(c, n)
   else:
     let labl = newLabel(c, n)
     c.breakSyms.add(labl)
     result = newTransNode(nkBlockStmt, n.info, 2)
-    result[0] = newSymNode(labl).PTransNode
+    result[0] = newSymNode(labl)
 
     var body = newTransNode(n)
-    for i in 0..n.len-2:
-      body[i] = transform(c, n.sons[i])
-    body[n.len-1] = transformLoopBody(c, n.sons[n.len-1])
+    for i in 0..<n.len-1:
+      body[i] = transform(c, n[i])
+    body[^1] = transformLoopBody(c, n[^1])
     result[1] = body
     discard c.breakSyms.pop
 
-proc transformBreak(c: PTransf, n: PNode): PTransNode =
+proc transformBreak(c: PTransf, n: PNode): PNode =
   result = transformSons(c, n)
-  if n.sons[0].kind == nkEmpty and c.breakSyms.len > 0:
+  if n[0].kind == nkEmpty and c.breakSyms.len > 0:
     let labl = c.breakSyms[c.breakSyms.high]
-    result[0] = newSymNode(labl).PTransNode
+    result[0] = newSymNode(labl)
 
-proc introduceNewLocalVars(c: PTransf, n: PNode): PTransNode =
+proc introduceNewLocalVars(c: PTransf, n: PNode): PNode =
   case n.kind
   of nkSym:
     result = transformSym(c, n)
   of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit:
     # nothing to be done for leaves:
-    result = PTransNode(n)
+    result = n
   of nkVarSection, nkLetSection:
     result = transformVarSection(c, n)
   of nkClosure:
@@ -313,14 +293,14 @@ proc introduceNewLocalVars(c: PTransf, n: PNode): PTransNode =
     # (bug #2604). We need to patch this environment here too:
     let a = n[1]
     if a.kind == nkSym:
-      n.sons[1] = transformSymAux(c, a)
-    return PTransNode(n)
+      n[1] = transformSymAux(c, a)
+    return n
   else:
     result = newTransNode(n)
-    for i in 0 ..< len(n):
-      result[i] = introduceNewLocalVars(c, n.sons[i])
+    for i in 0..<n.len:
+      result[i] = introduceNewLocalVars(c, n[i])
 
-proc transformAsgn(c: PTransf, n: PNode): PTransNode =
+proc transformAsgn(c: PTransf, n: PNode): PNode =
   let rhs = n[1]
 
   if rhs.kind != nkTupleConstr:
@@ -334,15 +314,15 @@ proc transformAsgn(c: PTransf, n: PNode): PTransNode =
   for i, field in rhs:
     let val = if field.kind == nkExprColonExpr: field[1] else: field
     let def = newTransNode(nkIdentDefs, field.info, 3)
-    def[0] = PTransNode(newTemp(c, val.typ, field.info))
-    def[1] = PTransNode(newNodeI(nkEmpty, field.info))
+    def[0] = newTemp(c, val.typ, field.info)
+    def[1] = newNodeI(nkEmpty, field.info)
     def[2] = transform(c, val)
     letSection[i] = def
     # NOTE: We assume the constructor fields are in the correct order for the
     # given tuple type
     newTupleConstr[i] = def[0]
 
-  PNode(newTupleConstr).typ = rhs.typ
+  newTupleConstr.typ = rhs.typ
 
   let asgnNode = newTransNode(nkAsgn, n.info, 2)
   asgnNode[0] = transform(c, n[0])
@@ -352,8 +332,8 @@ proc transformAsgn(c: PTransf, n: PNode): PTransNode =
   result[0] = letSection
   result[1] = asgnNode
 
-proc transformYield(c: PTransf, n: PNode): PTransNode =
-  proc asgnTo(lhs: PNode, rhs: PTransNode): PTransNode =
+proc transformYield(c: PTransf, n: PNode): PNode =
+  proc asgnTo(lhs: PNode, rhs: PNode): PNode =
     # Choose the right assignment instruction according to the given ``lhs``
     # node since it may not be a nkSym (a stack-allocated skForVar) but a
     # nkDotExpr (a heap-allocated slot into the envP block)
@@ -366,87 +346,87 @@ proc transformYield(c: PTransf, n: PNode): PTransNode =
     else:
       internalAssert c.graph.config, false
   result = newTransNode(nkStmtList, n.info, 0)
-  var e = n.sons[0]
+  var e = n[0]
   # c.transCon.forStmt.len == 3 means that there is one for loop variable
   # and thus no tuple unpacking:
   if e.typ.isNil: return result # can happen in nimsuggest for unknown reasons
   if c.transCon.forStmt.len != 3:
     e = skipConv(e)
     if e.kind in {nkPar, nkTupleConstr}:
-      for i in 0 ..< len(e):
-        var v = e.sons[i]
-        if v.kind == nkExprColonExpr: v = v.sons[1]
+      for i in 0..<e.len:
+        var v = e[i]
+        if v.kind == nkExprColonExpr: v = v[1]
         if c.transCon.forStmt[i].kind == nkVarTuple:
-          for j in 0 ..< len(c.transCon.forStmt[i])-1:
+          for j in 0..<c.transCon.forStmt[i].len-1:
             let lhs = c.transCon.forStmt[i][j]
             let rhs = transform(c, newTupleAccess(c.graph, v, j))
-            add(result, asgnTo(lhs, rhs))
+            result.add(asgnTo(lhs, rhs))
         else:
-          let lhs = c.transCon.forStmt.sons[i]
+          let lhs = c.transCon.forStmt[i]
           let rhs = transform(c, v)
-          add(result, asgnTo(lhs, rhs))
+          result.add(asgnTo(lhs, rhs))
     else:
       # Unpack the tuple into the loop variables
       # XXX: BUG: what if `n` is an expression with side-effects?
-      for i in 0 .. len(c.transCon.forStmt) - 3:
-        let lhs = c.transCon.forStmt.sons[i]
+      for i in 0..<c.transCon.forStmt.len - 2:
+        let lhs = c.transCon.forStmt[i]
         let rhs = transform(c, newTupleAccess(c.graph, e, i))
-        add(result, asgnTo(lhs, rhs))
+        result.add(asgnTo(lhs, rhs))
   else:
-    if c.transCon.forStmt.sons[0].kind == nkVarTuple:
-      for i in 0 ..< len(c.transCon.forStmt[0])-1:
+    if c.transCon.forStmt[0].kind == nkVarTuple:
+      for i in 0..<c.transCon.forStmt[0].len-1:
         let lhs = c.transCon.forStmt[0][i]
         let rhs = transform(c, newTupleAccess(c.graph, e, i))
-        add(result, asgnTo(lhs, rhs))
+        result.add(asgnTo(lhs, rhs))
     else:
-      let lhs = c.transCon.forStmt.sons[0]
+      let lhs = c.transCon.forStmt[0]
       let rhs = transform(c, e)
-      add(result, asgnTo(lhs, rhs))
+      result.add(asgnTo(lhs, rhs))
 
   inc(c.transCon.yieldStmts)
   if c.transCon.yieldStmts <= 1:
     # common case
-    add(result, c.transCon.forLoopBody)
+    result.add(c.transCon.forLoopBody)
   else:
     # we need to introduce new local variables:
-    add(result, introduceNewLocalVars(c, c.transCon.forLoopBody.PNode))
+    result.add(introduceNewLocalVars(c, c.transCon.forLoopBody))
   if result.len > 0:
-    var changeNode = PNode(result[0])
+    var changeNode = result[0]
     changeNode.info = c.transCon.forStmt.info
     for i, child in changeNode:
       child.info = changeNode.info
 
-proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
+proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
   result = transformSons(c, n)
   if c.graph.config.cmd == cmdCompileToCpp or sfCompileToCpp in c.module.flags: return
-  var n = result.PNode
-  case n.sons[0].kind
+  var n = result
+  case n[0].kind
   of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
-    var m = n.sons[0].sons[0]
+    var m = n[0][0]
     if m.kind == a or m.kind == b:
       # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
-      n.sons[0].sons[0] = m.sons[0]
-      result = PTransNode(n.sons[0])
+      n[0][0] = m[0]
+      result = n[0]
       if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
-        PNode(result).typ = n.typ
+        result.typ = n.typ
       elif n.typ.skipTypes(abstractInst).kind in {tyVar}:
-        PNode(result).typ = toVar(PNode(result).typ)
+        result.typ = toVar(result.typ)
   of nkHiddenStdConv, nkHiddenSubConv, nkConv:
-    var m = n.sons[0].sons[1]
+    var m = n[0][1]
     if m.kind == a or m.kind == b:
       # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
-      n.sons[0].sons[1] = m.sons[0]
-      result = PTransNode(n.sons[0])
+      n[0][1] = m[0]
+      result = n[0]
       if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
-        PNode(result).typ = n.typ
+        result.typ = n.typ
       elif n.typ.skipTypes(abstractInst).kind in {tyVar}:
-        PNode(result).typ = toVar(PNode(result).typ)
+        result.typ = toVar(result.typ)
   else:
-    if n.sons[0].kind == a or n.sons[0].kind == b:
+    if n[0].kind == a or n[0].kind == b:
       # addr ( deref ( x )) --> x
-      result = PTransNode(n.sons[0].sons[0])
+      result = n[0][0]
       if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
-        PNode(result).typ = n.typ
+        result.typ = n.typ
 
 proc generateThunk(c: PTransf; prc: PNode, dest: PType): PNode =
   ## Converts 'prc' into '(thunk, nil)' so that it's compatible with
@@ -464,18 +444,18 @@ proc generateThunk(c: PTransf; prc: PNode, dest: PType): PNode =
   result.add(conv)
   result.add(newNodeIT(nkNilLit, prc.info, getSysType(c.graph, prc.info, tyNil)))
 
-proc transformConv(c: PTransf, n: PNode): PTransNode =
+proc transformConv(c: PTransf, n: PNode): PNode =
   # numeric types need range checks:
   var dest = skipTypes(n.typ, abstractVarRange)
-  var source = skipTypes(n.sons[1].typ, abstractVarRange)
+  var source = skipTypes(n[1].typ, abstractVarRange)
   case dest.kind
   of tyInt..tyInt64, tyEnum, tyChar, tyBool, tyUInt8..tyUInt32:
     # we don't include uint and uint64 here as these are no ordinal types ;-)
     if not isOrdinalType(source):
       # float -> int conversions. ugh.
       result = transformSons(c, n)
-    elif firstOrd(c.graph.config, n.typ) <= firstOrd(c.graph.config, n.sons[1].typ) and
-        lastOrd(c.graph.config, n.sons[1].typ) <= lastOrd(c.graph.config, n.typ):
+    elif firstOrd(c.graph.config, n.typ) <= firstOrd(c.graph.config, n[1].typ) and
+        lastOrd(c.graph.config, n[1].typ) <= lastOrd(c.graph.config, n.typ):
       # BUGFIX: simply leave n as it is; we need a nkConv node,
       # but no range check:
       result = transformSons(c, n)
@@ -486,34 +466,34 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
       else:
         result = newTransNode(nkChckRange, n, 3)
       dest = skipTypes(n.typ, abstractVar)
-      result[0] = transform(c, n.sons[1])
-      result[1] = newIntTypeNode(firstOrd(c.graph.config, dest), dest).PTransNode
-      result[2] = newIntTypeNode(lastOrd(c.graph.config, dest), dest).PTransNode
+      result[0] = transform(c, n[1])
+      result[1] = newIntTypeNode(firstOrd(c.graph.config, dest), dest)
+      result[2] = newIntTypeNode(lastOrd(c.graph.config, dest), dest)
   of tyFloat..tyFloat128:
     # XXX int64 -> float conversion?
     if skipTypes(n.typ, abstractVar).kind == tyRange:
       result = newTransNode(nkChckRangeF, n, 3)
       dest = skipTypes(n.typ, abstractVar)
-      result[0] = transform(c, n.sons[1])
-      result[1] = copyTree(dest.n.sons[0]).PTransNode
-      result[2] = copyTree(dest.n.sons[1]).PTransNode
+      result[0] = transform(c, n[1])
+      result[1] = copyTree(dest.n[0])
+      result[2] = copyTree(dest.n[1])
     else:
       result = transformSons(c, n)
   of tyOpenArray, tyVarargs:
-    result = transform(c, n.sons[1])
-    PNode(result).typ = takeType(n.typ, n.sons[1].typ)
-    #echo n.info, " came here and produced ", typeToString(PNode(result).typ),
-    #   " from ", typeToString(n.typ), " and ", typeToString(n.sons[1].typ)
+    result = transform(c, n[1])
+    result.typ = takeType(n.typ, n[1].typ)
+    #echo n.info, " came here and produced ", typeToString(result.typ),
+    #   " from ", typeToString(n.typ), " and ", typeToString(n[1].typ)
   of tyCString:
     if source.kind == tyString:
       result = newTransNode(nkStringToCString, n, 1)
-      result[0] = transform(c, n.sons[1])
+      result[0] = transform(c, n[1])
     else:
       result = transformSons(c, n)
   of tyString:
     if source.kind == tyCString:
       result = newTransNode(nkCStringToString, n, 1)
-      result[0] = transform(c, n.sons[1])
+      result[0] = transform(c, n[1])
     else:
       result = transformSons(c, n)
   of tyRef, tyPtr:
@@ -523,31 +503,31 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
       var diff = inheritanceDiff(dest, source)
       if diff < 0:
         result = newTransNode(nkObjUpConv, n, 1)
-        result[0] = transform(c, n.sons[1])
+        result[0] = transform(c, n[1])
       elif diff > 0 and diff != high(int):
         result = newTransNode(nkObjDownConv, n, 1)
-        result[0] = transform(c, n.sons[1])
+        result[0] = transform(c, n[1])
       else:
-        result = transform(c, n.sons[1])
+        result = transform(c, n[1])
     else:
       result = transformSons(c, n)
   of tyObject:
     var diff = inheritanceDiff(dest, source)
     if diff < 0:
       result = newTransNode(nkObjUpConv, n, 1)
-      result[0] = transform(c, n.sons[1])
+      result[0] = transform(c, n[1])
     elif diff > 0 and diff != high(int):
       result = newTransNode(nkObjDownConv, n, 1)
-      result[0] = transform(c, n.sons[1])
+      result[0] = transform(c, n[1])
     else:
-      result = transform(c, n.sons[1])
+      result = transform(c, n[1])
   of tyGenericParam, tyOrdinal:
-    result = transform(c, n.sons[1])
+    result = transform(c, n[1])
     # happens sometimes for generated assignments, etc.
   of tyProc:
     result = transformSons(c, n)
     if dest.callConv == ccClosure and source.callConv == ccDefault:
-      result = generateThunk(c, result[1].PNode, dest).PTransNode
+      result = generateThunk(c, result[1], dest)
   else:
     result = transformSons(c, n)
 
@@ -574,8 +554,8 @@ proc putArgInto(arg: PNode, formal: PType): TPutArgInto =
     result = paDirectMapping
   of nkPar, nkTupleConstr, nkCurly, nkBracket:
     result = paFastAsgn
-    for i in 0 ..< len(arg):
-      if putArgInto(arg.sons[i], formal) != paDirectMapping: return
+    for i in 0..<arg.len:
+      if putArgInto(arg[i], formal) != paDirectMapping: return
     result = paDirectMapping
   else:
     if skipTypes(formal, abstractInst).kind in {tyVar, tyLent}: result = paVarAsgn
@@ -583,35 +563,34 @@ proc putArgInto(arg: PNode, formal: PType): TPutArgInto =
 
 proc findWrongOwners(c: PTransf, n: PNode) =
   if n.kind == nkVarSection:
-    let x = n.sons[0].sons[0]
+    let x = n[0][0]
     if x.kind == nkSym and x.sym.owner != getCurrOwner(c):
       internalError(c.graph.config, x.info, "bah " & x.sym.name.s & " " &
         x.sym.owner.name.s & " " & getCurrOwner(c).name.s)
   else:
-    for i in 0 ..< safeLen(n): findWrongOwners(c, n.sons[i])
+    for i in 0..<n.safeLen: findWrongOwners(c, n[i])
 
-proc transformFor(c: PTransf, n: PNode): PTransNode =
+proc transformFor(c: PTransf, n: PNode): PNode =
   # generate access statements for the parameters (unless they are constant)
   # put mapping from formal parameters to actual parameters
   if n.kind != nkForStmt: internalError(c.graph.config, n.info, "transformFor")
 
-  var length = len(n)
-  var call = n.sons[length - 2]
+  var call = n[^2]
 
   let labl = newLabel(c, n)
   result = newTransNode(nkBlockStmt, n.info, 2)
-  result[0] = newSymNode(labl).PTransNode
+  result[0] = newSymNode(labl)
   if call.typ.isNil:
     # see bug #3051
-    result[1] = newNode(nkEmpty).PTransNode
+    result[1] = newNode(nkEmpty)
     return result
   c.breakSyms.add(labl)
-  if call.kind notin nkCallKinds or call.sons[0].kind != nkSym or
-      call.sons[0].typ.skipTypes(abstractInst).callConv == ccClosure:
-    result[1] = n.PTransNode
+  if call.kind notin nkCallKinds or call[0].kind != nkSym or
+      call[0].typ.skipTypes(abstractInst).callConv == ccClosure:
+    result[1] = n
     result[1][^1] = transformLoopBody(c, n[^1])
     result[1][^2] = transform(c, n[^2])
-    result[1] = lambdalifting.liftForLoop(c.graph, result[1].PNode, getCurrOwner(c)).PTransNode
+    result[1] = lambdalifting.liftForLoop(c.graph, result[1], getCurrOwner(c))
     discard c.breakSyms.pop
     return result
 
@@ -619,22 +598,22 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
   var stmtList = newTransNode(nkStmtList, n.info, 0)
   result[1] = stmtList
 
-  var loopBody = transformLoopBody(c, n.sons[length-1])
+  var loopBody = transformLoopBody(c, n[^1])
 
   discard c.breakSyms.pop
 
   var v = newNodeI(nkVarSection, n.info)
-  for i in 0 .. length - 3:
+  for i in 0..<n.len - 2:
     if n[i].kind == nkVarTuple:
-      for j in 0 ..< len(n[i])-1:
+      for j in 0..<n[i].len-1:
         addVar(v, copyTree(n[i][j])) # declare new vars
     else:
-      addVar(v, copyTree(n.sons[i])) # declare new vars
-  add(stmtList, v.PTransNode)
+      addVar(v, copyTree(n[i])) # declare new vars
+  stmtList.add(v)
 
   # Bugfix: inlined locals belong to the invoking routine, not to the invoked
   # iterator!
-  let iter = call.sons[0].sym
+  let iter = call[0].sym
   var newC = newTransCon(getCurrOwner(c))
   newC.forStmt = n
   newC.forLoopBody = loopBody
@@ -642,12 +621,12 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
   if iter.kind != skIterator: return result
   # generate access statements for the parameters (unless they are constant)
   pushTransCon(c, newC)
-  for i in 1 ..< len(call):
-    var arg = transform(c, call.sons[i]).PNode
+  for i in 1..<call.len:
+    var arg = transform(c, call[i])
     let ff = skipTypes(iter.typ, abstractInst)
     # can happen for 'nim check':
     if i >= ff.n.len: return result
-    var formal = ff.n.sons[i].sym
+    var formal = ff.n[i].sym
     let pa = putArgInto(arg, formal.typ)
     case pa
     of paDirectMapping:
@@ -663,7 +642,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
       # generate a temporary and produce an assignment statement:
       var temp = newTemp(c, t, formal.info)
       addVar(v, temp)
-      add(stmtList, newAsgnStmt(c, nkFastAsgn, temp, arg.PTransNode))
+      stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg))
       idNodeTablePut(newC.mapping, formal, temp)
     of paVarAsgn:
       assert(skipTypes(formal.typ, abstractInst).kind == tyVar)
@@ -671,150 +650,149 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
       # XXX BUG still not correct if the arg has a side effect!
     of paComplexOpenarray:
       let typ = newType(tySequence, formal.owner)
-      addSonSkipIntLit(typ, formal.typ.sons[0])
+      addSonSkipIntLit(typ, formal.typ[0])
       var temp = newTemp(c, typ, formal.info)
       addVar(v, temp)
-      add(stmtList, newAsgnStmt(c, nkFastAsgn, temp, arg.PTransNode))
+      stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg))
       idNodeTablePut(newC.mapping, formal, temp)
 
   let body = transformBody(c.graph, iter, true)
   pushInfoContext(c.graph.config, n.info)
   inc(c.inlining)
-  add(stmtList, transform(c, body))
+  stmtList.add(transform(c, body))
   #findWrongOwners(c, stmtList.pnode)
   dec(c.inlining)
   popInfoContext(c.graph.config)
   popTransCon(c)
-  # echo "transformed: ", stmtList.PNode.renderTree
+  # echo "transformed: ", stmtList.renderTree
 
-proc transformCase(c: PTransf, n: PNode): PTransNode =
+proc transformCase(c: PTransf, n: PNode): PNode =
   # removes `elif` branches of a case stmt
   # adds ``else: nil`` if needed for the code generator
   result = newTransNode(nkCaseStmt, n, 0)
-  var ifs = PTransNode(nil)
-  for i in 0 .. len(n)-1:
-    var it = n.sons[i]
+  var ifs: PNode = nil
+  for it in n:
     var e = transform(c, it)
     case it.kind
     of nkElifBranch:
-      if ifs.PNode == nil:
+      if ifs == nil:
         # Generate the right node depending on whether `n` is used as a stmt or
         # as an expr
         let kind = if n.typ != nil: nkIfExpr else: nkIfStmt
         ifs = newTransNode(kind, it.info, 0)
-        ifs.PNode.typ = n.typ
+        ifs.typ = n.typ
       ifs.add(e)
     of nkElse:
-      if ifs.PNode == nil: result.add(e)
+      if ifs == nil: result.add(e)
       else: ifs.add(e)
     else:
       result.add(e)
-  if ifs.PNode != nil:
+  if ifs != nil:
     var elseBranch = newTransNode(nkElse, n.info, 1)
     elseBranch[0] = ifs
     result.add(elseBranch)
-  elif result.PNode.lastSon.kind != nkElse and not (
-      skipTypes(n.sons[0].typ, abstractVarRange).kind in
+  elif result.lastSon.kind != nkElse and not (
+      skipTypes(n[0].typ, abstractVarRange).kind in
         {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt64}):
     # fix a stupid code gen bug by normalizing:
     var elseBranch = newTransNode(nkElse, n.info, 1)
     elseBranch[0] = newTransNode(nkNilLit, n.info, 0)
-    add(result, elseBranch)
+    result.add(elseBranch)
 
-proc transformArrayAccess(c: PTransf, n: PNode): PTransNode =
+proc transformArrayAccess(c: PTransf, n: PNode): PNode =
   # XXX this is really bad; transf should use a proper AST visitor
-  if n.sons[0].kind == nkSym and n.sons[0].sym.kind == skType:
-    result = n.PTransNode
+  if n[0].kind == nkSym and n[0].sym.kind == skType:
+    result = n
   else:
     result = newTransNode(n)
-    for i in 0 ..< n.len:
-      result[i] = transform(c, skipConv(n.sons[i]))
+    for i in 0..<n.len:
+      result[i] = transform(c, skipConv(n[i]))
 
 proc getMergeOp(n: PNode): PSym =
   case n.kind
   of nkCall, nkHiddenCallConv, nkCommand, nkInfix, nkPrefix, nkPostfix,
      nkCallStrLit:
-    if n.sons[0].kind == nkSym and n.sons[0].sym.magic == mConStrStr:
-      result = n.sons[0].sym
+    if n[0].kind == nkSym and n[0].sym.magic == mConStrStr:
+      result = n[0].sym
   else: discard
 
 proc flattenTreeAux(d, a: PNode, op: PSym) =
   let op2 = getMergeOp(a)
   if op2 != nil and
       (op2.id == op.id or op.magic != mNone and op2.magic == op.magic):
-    for i in 1 ..< len(a): flattenTreeAux(d, a.sons[i], op)
+    for i in 1..<a.len: flattenTreeAux(d, a[i], op)
   else:
-    addSon(d, copyTree(a))
+    d.add copyTree(a)
 
 proc flattenTree(root: PNode): PNode =
   let op = getMergeOp(root)
   if op != nil:
     result = copyNode(root)
-    addSon(result, copyTree(root.sons[0]))
+    result.add copyTree(root[0])
     flattenTreeAux(result, root, op)
   else:
     result = root
 
-proc transformCall(c: PTransf, n: PNode): PTransNode =
+proc transformCall(c: PTransf, n: PNode): PNode =
   var n = flattenTree(n)
   let op = getMergeOp(n)
   let magic = getMagic(n)
   if op != nil and op.magic != mNone and n.len >= 3:
     result = newTransNode(nkCall, n, 0)
-    add(result, transform(c, n.sons[0]))
+    result.add(transform(c, n[0]))
     var j = 1
-    while j < len(n):
-      var a = transform(c, n.sons[j]).PNode
+    while j < n.len:
+      var a = transform(c, n[j])
       inc(j)
       if isConstExpr(a):
-        while (j < len(n)):
-          let b = transform(c, n.sons[j]).PNode
+        while (j < n.len):
+          let b = transform(c, n[j])
           if not isConstExpr(b): break
           a = evalOp(op.magic, n, a, b, nil, c.graph)
           inc(j)
-      add(result, a.PTransNode)
-    if len(result) == 2: result = result[1]
+      result.add(a)
+    if result.len == 2: result = result[1]
   elif magic == mAddr:
     result = newTransNode(nkAddr, n, 1)
-    result[0] = n[1].PTransNode
-    result = transformAddrDeref(c, result.PNode, nkDerefExpr, nkHiddenDeref)
+    result[0] = n[1]
+    result = transformAddrDeref(c, result, nkDerefExpr, nkHiddenDeref)
   elif magic in {mNBindSym, mTypeOf, mRunnableExamples}:
     # for bindSym(myconst) we MUST NOT perform constant folding:
-    result = n.PTransNode
+    result = n
   elif magic == mProcCall:
     # but do not change to its dispatcher:
     result = transformSons(c, n[1])
   elif magic == mStrToStr:
     result = transform(c, n[1])
   else:
-    let s = transformSons(c, n).PNode
+    let s = transformSons(c, n)
     # bugfix: check after 'transformSons' if it's still a method call:
     # use the dispatcher for the call:
-    if s.sons[0].kind == nkSym and s.sons[0].sym.kind == skMethod:
+    if s[0].kind == nkSym and s[0].sym.kind == skMethod:
       when false:
-        let t = lastSon(s.sons[0].sym.ast)
+        let t = lastSon(s[0].sym.ast)
         if t.kind != nkSym or sfDispatcher notin t.sym.flags:
-          methodDef(s.sons[0].sym, false)
-      result = methodCall(s, c.graph.config).PTransNode
+          methodDef(s[0].sym, false)
+      result = methodCall(s, c.graph.config)
     else:
-      result = s.PTransNode
+      result = s
 
-proc transformExceptBranch(c: PTransf, n: PNode): PTransNode =
+proc transformExceptBranch(c: PTransf, n: PNode): PNode =
   if n[0].isInfixAs() and not isImportedException(n[0][1].typ, c.graph.config):
     let excTypeNode = n[0][1]
     let actions = newTransNode(nkStmtListExpr, n[1], 2)
     # Generating `let exc = (excType)(getCurrentException())`
     # -> getCurrentException()
-    let excCall = PTransNode(callCodegenProc(c.graph, "getCurrentException"))
+    let excCall = callCodegenProc(c.graph, "getCurrentException")
     # -> (excType)
     let convNode = newTransNode(nkHiddenSubConv, n[1].info, 2)
-    convNode[0] = PTransNode(newNodeI(nkEmpty, n.info))
+    convNode[0] = newNodeI(nkEmpty, n.info)
     convNode[1] = excCall
-    PNode(convNode).typ = excTypeNode.typ.toRef()
+    convNode.typ = excTypeNode.typ.toRef()
     # -> let exc = ...
     let identDefs = newTransNode(nkIdentDefs, n[1].info, 3)
-    identDefs[0] = PTransNode(n[0][2])
-    identDefs[1] = PTransNode(newNodeI(nkEmpty, n.info))
+    identDefs[0] = n[0][2]
+    identDefs[1] = newNodeI(nkEmpty, n.info)
     identDefs[2] = convNode
 
     let letSection = newTransNode(nkLetSection, n[1].info, 1)
@@ -839,26 +817,26 @@ proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} =
 
 proc commonOptimizations*(g: ModuleGraph; c: PSym, n: PNode): PNode =
   result = n
-  for i in 0 ..< n.safeLen:
-    result.sons[i] = commonOptimizations(g, c, n.sons[i])
+  for i in 0..<n.safeLen:
+    result[i] = commonOptimizations(g, c, n[i])
   var op = getMergeOp(n)
-  if (op != nil) and (op.magic != mNone) and (len(n) >= 3):
+  if (op != nil) and (op.magic != mNone) and (n.len >= 3):
     result = newNodeIT(nkCall, n.info, n.typ)
-    add(result, n.sons[0])
+    result.add(n[0])
     var args = newNode(nkArgList)
     flattenTreeAux(args, n, op)
     var j = 0
-    while j < len(args):
-      var a = args.sons[j]
+    while j < args.len:
+      var a = args[j]
       inc(j)
       if isConstExpr(a):
-        while j < len(args):
-          let b = args.sons[j]
+        while j < args.len:
+          let b = args[j]
           if not isConstExpr(b): break
           a = evalOp(op.magic, result, a, b, nil, g)
           inc(j)
-      add(result, a)
-    if len(result) == 2: result = result[1]
+      result.add(a)
+    if result.len == 2: result = result[1]
   else:
     var cnst = getConstExpr(c, n, g)
     # we inline constants if they are not complex constants:
@@ -904,7 +882,7 @@ proc hoistParamsUsedInDefault(c: PTransf, call, letSection, defExpr: PNode): PNo
       let hoisted = hoistParamsUsedInDefault(c, call, letSection, defExpr[i])
       if hoisted != nil: defExpr[i] = hoisted
 
-proc transform(c: PTransf, n: PNode): PTransNode =
+proc transform(c: PTransf, n: PNode): PNode =
   when false:
     var oldDeferAnchor: PNode
     if n.kind in {nkElifBranch, nkOfBranch, nkExceptBranch, nkElifExpr,
@@ -917,24 +895,24 @@ proc transform(c: PTransf, n: PNode): PTransNode =
     result = transformSym(c, n)
   of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, nkComesFrom:
     # nothing to be done for leaves:
-    result = PTransNode(n)
+    result = n
   of nkBracketExpr: result = transformArrayAccess(c, n)
   of procDefs:
-    var s = n.sons[namePos].sym
+    var s = n[namePos].sym
     if n.typ != nil and s.typ.callConv == ccClosure:
-      result = transformSym(c, n.sons[namePos])
+      result = transformSym(c, n[namePos])
       # use the same node as before if still a symbol:
-      if result.PNode.kind == nkSym: result = PTransNode(n)
+      if result.kind == nkSym: result = n
     else:
-      result = PTransNode(n)
+      result = n
   of nkMacroDef:
     # XXX no proper closure support yet:
     when false:
-      if n.sons[genericParamsPos].kind == nkEmpty:
-        var s = n.sons[namePos].sym
-        n.sons[bodyPos] = PNode(transform(c, s.getBody))
+      if n[genericParamsPos].kind == nkEmpty:
+        var s = n[namePos].sym
+        n[bodyPos] = transform(c, s.getBody)
         if n.kind == nkMethodDef: methodDef(s, false)
-    result = PTransNode(n)
+    result = n
   of nkForStmt:
     result = transformFor(c, n)
   of nkParForStmt:
@@ -949,38 +927,37 @@ proc transform(c: PTransf, n: PNode): PTransNode =
     result = transformSons(c, n)
     when false:
       let deferPart = newNodeI(nkFinally, n.info)
-      deferPart.add n.sons[0]
+      deferPart.add n[0]
       let tryStmt = newNodeI(nkTryStmt, n.info)
       if c.deferAnchor.isNil:
         tryStmt.add c.root
         c.root = tryStmt
-        result = PTransNode(tryStmt)
+        result = tryStmt
       else:
         # modify the corresponding *action*, don't rely on nkStmtList:
-        let L = c.deferAnchor.len-1
-        tryStmt.add c.deferAnchor.sons[L]
-        c.deferAnchor.sons[L] = tryStmt
+        tryStmt.add c.deferAnchor[^1]
+        c.deferAnchor[^1] = tryStmt
         result = newTransNode(nkCommentStmt, n.info, 0)
-      tryStmt.addSon(deferPart)
+      tryStmt.add deferPart
       # disable the original 'defer' statement:
       n.kind = nkEmpty
   of nkContinueStmt:
-    result = PTransNode(newNodeI(nkBreakStmt, n.info))
+    result = newNodeI(nkBreakStmt, n.info)
     var labl = c.contSyms[c.contSyms.high]
-    add(result, PTransNode(newSymNode(labl)))
+    result.add(newSymNode(labl))
   of nkBreakStmt: result = transformBreak(c, n)
   of nkCallKinds:
     result = transformCall(c, n)
-    var call = result.PNode
+    var call = result
     if nfDefaultRefsParam in call.flags:
       # We've found a default value that references another param.
       # See the notes in `hoistParamsUsedInDefault` for more details.
       var hoistedParams = newNodeI(nkLetSection, call.info, 0)
-      for i in 1 ..< call.len:
+      for i in 1..<call.len:
         let hoisted = hoistParamsUsedInDefault(c, call, hoistedParams, call[i])
         if hoisted != nil: call[i] = hoisted
-      result = newTree(nkStmtListExpr, hoistedParams, call).PTransNode
-      PNode(result).typ = call.typ
+      result = newTree(nkStmtListExpr, hoistedParams, call)
+      result.typ = call.typ
   of nkAddr, nkHiddenAddr:
     result = transformAddrDeref(c, n, nkDerefExpr, nkHiddenDeref)
   of nkDerefExpr, nkHiddenDeref:
@@ -988,22 +965,22 @@ proc transform(c: PTransf, n: PNode): PTransNode =
   of nkHiddenStdConv, nkHiddenSubConv, nkConv:
     result = transformConv(c, n)
   of nkDiscardStmt:
-    result = PTransNode(n)
-    if n.sons[0].kind != nkEmpty:
+    result = n
+    if n[0].kind != nkEmpty:
       result = transformSons(c, n)
-      if isConstExpr(PNode(result).sons[0]):
+      if isConstExpr(result[0]):
         # ensure that e.g. discard "some comment" gets optimized away
         # completely:
-        result = PTransNode(newNode(nkCommentStmt))
+        result = newNode(nkCommentStmt)
   of nkCommentStmt, nkTemplateDef, nkImportStmt, nkStaticStmt,
       nkExportStmt, nkExportExceptStmt:
-    return n.PTransNode
+    return n
   of nkConstSection:
     # do not replace ``const c = 3`` with ``const 3 = 3``
     return transformConstSection(c, n)
   of nkTypeSection, nkTypeOfExpr:
     # no need to transform type sections:
-    return PTransNode(n)
+    return n
   of nkVarSection, nkLetSection:
     if c.inlining > 0:
       # we need to copy the variables for multiple yield statements:
@@ -1018,22 +995,22 @@ proc transform(c: PTransf, n: PNode): PTransNode =
   of nkAsgn:
     result = transformAsgn(c, n)
   of nkIdentDefs, nkConstDef:
-    result = PTransNode(n)
+    result = n
     result[0] = transform(c, n[0])
     # Skip the second son since it only contains an unsemanticized copy of the
     # variable type used by docgen
     result[2] = transform(c, n[2])
     # XXX comment handling really sucks:
     if importantComments(c.graph.config):
-      PNode(result).comment = n.comment
+      result.comment = n.comment
   of nkClosure:
     # it can happen that for-loop-inlining produced a fresh
     # set of variables, including some computed environment
     # (bug #2604). We need to patch this environment here too:
     let a = n[1]
     if a.kind == nkSym:
-      n.sons[1] = transformSymAux(c, a)
-    return PTransNode(n)
+      n[1] = transformSymAux(c, a)
+    return n
   of nkExceptBranch:
     result = transformExceptBranch(c, n)
   else:
@@ -1046,10 +1023,10 @@ proc transform(c: PTransf, n: PNode): PTransNode =
   let exprIsPointerCast = n.kind in {nkCast, nkConv, nkHiddenStdConv} and
                           n.typ.kind == tyPointer
   if not exprIsPointerCast:
-    var cnst = getConstExpr(c.module, PNode(result), c.graph)
+    var cnst = getConstExpr(c.module, result, c.graph)
     # we inline constants if they are not complex constants:
     if cnst != nil and not dontInlineConstant(n, cnst):
-      result = PTransNode(cnst) # do not miss an optimization
+      result = cnst # do not miss an optimization
 
 proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode =
   # Note: For interactive mode we cannot call 'passes.skipCodegen' and skip
@@ -1057,7 +1034,7 @@ proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode =
   # nodes into an empty node.
   if nfTransf in n.flags: return n
   pushTransCon(c, newTransCon(owner))
-  result = PNode(transform(c, n))
+  result = transform(c, n)
   popTransCon(c)
   incl(result.flags, nfTransf)
 
@@ -1088,22 +1065,22 @@ proc liftDeferAux(n: PNode) =
       goOn = false
       let last = n.len-1
       for i in 0..last:
-        if n.sons[i].kind == nkDefer:
-          let deferPart = newNodeI(nkFinally, n.sons[i].info)
-          deferPart.add n.sons[i].sons[0]
-          var tryStmt = newNodeI(nkTryStmt, n.sons[i].info)
-          var body = newNodeI(n.kind, n.sons[i].info)
+        if n[i].kind == nkDefer:
+          let deferPart = newNodeI(nkFinally, n[i].info)
+          deferPart.add n[i][0]
+          var tryStmt = newNodeI(nkTryStmt, n[i].info)
+          var body = newNodeI(n.kind, n[i].info)
           if i < last:
             body.sons = n.sons[(i+1)..last]
-          tryStmt.addSon(body)
-          tryStmt.addSon(deferPart)
-          n.sons[i] = tryStmt
+          tryStmt.add body
+          tryStmt.add deferPart
+          n[i] = tryStmt
           n.sons.setLen(i+1)
-          n.typ = n.sons[i].typ
+          n.typ = n[i].typ
           goOn = true
           break
   for i in 0..n.safeLen-1:
-    liftDeferAux(n.sons[i])
+    liftDeferAux(n[i])
 
 template liftDefer(c, root) =
   if c.deferDetected: