summary refs log tree commit diff stats
path: root/compiler/astalgo.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/astalgo.nim')
-rw-r--r--compiler/astalgo.nim667
1 files changed, 333 insertions, 334 deletions
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index c53e53b88..1707718d7 100644
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -11,18 +11,18 @@
 # and sets of nodes are supported. Efficiency is important as
 # the data structures here are used in various places of the compiler.
 
-import 
+import
   ast, hashes, intsets, strutils, options, msgs, ropes, idents, rodutils
 
 proc hashNode*(p: RootRef): THash
-proc treeToYaml*(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope
+proc treeToYaml*(n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope
   # Convert a tree into its YAML representation; this is used by the
   # YAML code generator and it is invaluable for debugging purposes.
   # If maxRecDepht <> -1 then it won't print the whole graph.
-proc typeToYaml*(n: PType, indent: int = 0, maxRecDepth: int = - 1): PRope
-proc symToYaml*(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope
-proc lineInfoToStr*(info: TLineInfo): PRope
-  
+proc typeToYaml*(n: PType, indent: int = 0, maxRecDepth: int = - 1): Rope
+proc symToYaml*(n: PSym, indent: int = 0, maxRecDepth: int = - 1): Rope
+proc lineInfoToStr*(info: TLineInfo): Rope
+
 # ----------------------- node sets: ---------------------------------------
 proc objectSetContains*(t: TObjectSet, obj: RootRef): bool
   # returns true whether n is in t
@@ -34,10 +34,10 @@ proc objectSetContainsOrIncl*(t: var TObjectSet, obj: RootRef): bool
 # ----------------------- (key, val)-Hashtables ----------------------------
 proc tablePut*(t: var TTable, key, val: RootRef)
 proc tableGet*(t: TTable, key: RootRef): RootRef
-type 
+type
   TCmpProc* = proc (key, closure: RootRef): bool {.nimcall.} # true if found
 
-proc tableSearch*(t: TTable, key, closure: RootRef, 
+proc tableSearch*(t: TTable, key, closure: RootRef,
                   comparator: TCmpProc): RootRef
   # return val as soon as comparator returns true; if this never happens,
   # nil is returned
@@ -45,16 +45,16 @@ proc tableSearch*(t: TTable, key, closure: RootRef,
 # ----------------------- str table -----------------------------------------
 proc strTableContains*(t: TStrTable, n: PSym): bool
 proc strTableAdd*(t: var TStrTable, n: PSym)
-proc strTableGet*(t: TStrTable, name: PIdent): PSym  
-  
-type 
+proc strTableGet*(t: TStrTable, name: PIdent): PSym
+
+type
   TTabIter*{.final.} = object # consider all fields here private
     h*: THash                 # current hash
 
 proc initTabIter*(ti: var TTabIter, tab: TStrTable): PSym
 proc nextIter*(ti: var TTabIter, tab: TStrTable): PSym
   # usage:
-  # var 
+  # var
   #   i: TTabIter
   #   s: PSym
   # s = InitTabIter(i, table)
@@ -63,7 +63,7 @@ proc nextIter*(ti: var TTabIter, tab: TStrTable): PSym
   #   s = NextIter(i, table)
   #
 
-type 
+type
   TIdentIter*{.final.} = object # iterator over all syms with same identifier
     h*: THash                   # current hash
     name*: PIdent
@@ -97,11 +97,11 @@ proc mustRehash*(length, counter: int): bool
 proc nextTry*(h, maxHash: THash): THash {.inline.}
 
 # ------------- table[int, int] ---------------------------------------------
-const 
+const
   InvalidKey* = low(int)
 
-type 
-  TIIPair*{.final.} = object 
+type
+  TIIPair*{.final.} = object
     key*, val*: int
 
   TIIPairSeq* = seq[TIIPair]
@@ -127,21 +127,21 @@ proc skipConvAndClosure*(n: PNode): PNode =
       result = result.sons[1]
     else: break
 
-proc sameValue*(a, b: PNode): bool = 
+proc sameValue*(a, b: PNode): bool =
   result = false
   case a.kind
-  of nkCharLit..nkUInt64Lit: 
+  of nkCharLit..nkUInt64Lit:
     if b.kind in {nkCharLit..nkUInt64Lit}: result = a.intVal == b.intVal
-  of nkFloatLit..nkFloat64Lit: 
+  of nkFloatLit..nkFloat64Lit:
     if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal
-  of nkStrLit..nkTripleStrLit: 
+  of nkStrLit..nkTripleStrLit:
     if b.kind in {nkStrLit..nkTripleStrLit}: result = a.strVal == b.strVal
   else:
     # don't raise an internal error for 'nimrod check':
     #InternalError(a.info, "SameValue")
     discard
 
-proc leValue*(a, b: PNode): bool = 
+proc leValue*(a, b: PNode): bool =
   # a <= b?
   result = false
   case a.kind
@@ -162,289 +162,289 @@ proc weakLeValue*(a, b: PNode): TImplication =
   else:
     result = if leValue(a, b): impYes else: impNo
 
-proc lookupInRecord(n: PNode, field: PIdent): PSym = 
+proc lookupInRecord(n: PNode, field: PIdent): PSym =
   result = nil
   case n.kind
-  of nkRecList: 
-    for i in countup(0, sonsLen(n) - 1): 
+  of nkRecList:
+    for i in countup(0, sonsLen(n) - 1):
       result = lookupInRecord(n.sons[i], field)
-      if result != nil: return 
-  of nkRecCase: 
+      if result != nil: return
+  of nkRecCase:
     if (n.sons[0].kind != nkSym): internalError(n.info, "lookupInRecord")
     result = lookupInRecord(n.sons[0], field)
-    if result != nil: return 
-    for i in countup(1, sonsLen(n) - 1): 
+    if result != nil: return
+    for i in countup(1, sonsLen(n) - 1):
       case n.sons[i].kind
-      of nkOfBranch, nkElse: 
+      of nkOfBranch, nkElse:
         result = lookupInRecord(lastSon(n.sons[i]), field)
-        if result != nil: return 
+        if result != nil: return
       else: internalError(n.info, "lookupInRecord(record case branch)")
-  of nkSym: 
+  of nkSym:
     if n.sym.name.id == field.id: result = n.sym
   else: internalError(n.info, "lookupInRecord()")
-  
-proc getModule(s: PSym): PSym = 
+
+proc getModule(s: PSym): PSym =
   result = s
   assert((result.kind == skModule) or (result.owner != result))
   while result != nil and result.kind != skModule: result = result.owner
-  
-proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym = 
-  for i in countup(start, sonsLen(list) - 1): 
+
+proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym =
+  for i in countup(start, sonsLen(list) - 1):
     if list.sons[i].kind == nkSym:
       result = list.sons[i].sym
-      if result.name.id == ident.id: return 
+      if result.name.id == ident.id: return
     else: internalError(list.info, "getSymFromList")
   result = nil
 
-proc hashNode(p: RootRef): THash = 
+proc hashNode(p: RootRef): THash =
   result = hash(cast[pointer](p))
 
-proc mustRehash(length, counter: int): bool = 
+proc mustRehash(length, counter: int): bool =
   assert(length > counter)
   result = (length * 2 < counter * 3) or (length - counter < 4)
 
-proc rspaces(x: int): PRope = 
+proc rspaces(x: int): Rope =
   # returns x spaces
-  result = toRope(spaces(x))
+  result = rope(spaces(x))
 
-proc toYamlChar(c: char): string = 
+proc toYamlChar(c: char): string =
   case c
   of '\0'..'\x1F', '\x80'..'\xFF': result = "\\u" & strutils.toHex(ord(c), 4)
   of '\'', '\"', '\\': result = '\\' & c
   else: result = $c
-  
-proc makeYamlString*(s: string): PRope = 
+
+proc makeYamlString*(s: string): Rope =
   # We have to split long strings into many ropes. Otherwise
   # this could trigger InternalError(111). See the ropes module for
   # further information.
   const MaxLineLength = 64
   result = nil
   var res = "\""
-  for i in countup(0, if s.isNil: -1 else: (len(s)-1)): 
-    if (i + 1) mod MaxLineLength == 0: 
+  for i in countup(0, if s.isNil: -1 else: (len(s)-1)):
+    if (i + 1) mod MaxLineLength == 0:
       add(res, '\"')
       add(res, "\n")
-      app(result, toRope(res))
+      add(result, rope(res))
       res = "\""              # reset
     add(res, toYamlChar(s[i]))
   add(res, '\"')
-  app(result, toRope(res))
+  add(result, rope(res))
 
-proc flagsToStr[T](flags: set[T]): PRope = 
-  if flags == {}: 
-    result = toRope("[]")
-  else: 
+proc flagsToStr[T](flags: set[T]): Rope =
+  if flags == {}:
+    result = rope("[]")
+  else:
     result = nil
-    for x in items(flags): 
-      if result != nil: app(result, ", ")
-      app(result, makeYamlString($x))
-    result = con("[", con(result, "]"))
-
-proc lineInfoToStr(info: TLineInfo): PRope = 
-  result = ropef("[$1, $2, $3]", [makeYamlString(toFilename(info)), 
-                                  toRope(toLinenumber(info)), 
-                                  toRope(toColumn(info))])
-
-proc treeToYamlAux(n: PNode, marker: var IntSet, 
-                   indent, maxRecDepth: int): PRope
-proc symToYamlAux(n: PSym, marker: var IntSet, 
-                  indent, maxRecDepth: int): PRope
-proc typeToYamlAux(n: PType, marker: var IntSet, 
-                   indent, maxRecDepth: int): PRope
-proc strTableToYaml(n: TStrTable, marker: var IntSet, indent: int, 
-                    maxRecDepth: int): PRope = 
+    for x in items(flags):
+      if result != nil: add(result, ", ")
+      add(result, makeYamlString($x))
+    result = "[" & result & "]"
+
+proc lineInfoToStr(info: TLineInfo): Rope =
+  result = "[$1, $2, $3]" % [makeYamlString(toFilename(info)),
+                             rope(toLinenumber(info)),
+                             rope(toColumn(info))]
+
+proc treeToYamlAux(n: PNode, marker: var IntSet,
+                   indent, maxRecDepth: int): Rope
+proc symToYamlAux(n: PSym, marker: var IntSet,
+                  indent, maxRecDepth: int): Rope
+proc typeToYamlAux(n: PType, marker: var IntSet,
+                   indent, maxRecDepth: int): Rope
+proc strTableToYaml(n: TStrTable, marker: var IntSet, indent: int,
+                    maxRecDepth: int): Rope =
   var istr = rspaces(indent + 2)
-  result = toRope("[")
+  result = rope("[")
   var mycount = 0
-  for i in countup(0, high(n.data)): 
-    if n.data[i] != nil: 
-      if mycount > 0: app(result, ",")
-      appf(result, "$N$1$2", 
+  for i in countup(0, high(n.data)):
+    if n.data[i] != nil:
+      if mycount > 0: add(result, ",")
+      addf(result, "$N$1$2",
            [istr, symToYamlAux(n.data[i], marker, indent + 2, maxRecDepth - 1)])
       inc(mycount)
-  if mycount > 0: appf(result, "$N$1", [rspaces(indent)])
-  app(result, "]")
+  if mycount > 0: addf(result, "$N$1", [rspaces(indent)])
+  add(result, "]")
   assert(mycount == n.counter)
 
-proc ropeConstr(indent: int, c: openArray[PRope]): PRope = 
+proc ropeConstr(indent: int, c: openArray[Rope]): Rope =
   # array of (name, value) pairs
   var istr = rspaces(indent + 2)
-  result = toRope("{")
+  result = rope("{")
   var i = 0
-  while i <= high(c): 
-    if i > 0: app(result, ",")
-    appf(result, "$N$1\"$2\": $3", [istr, c[i], c[i + 1]])
+  while i <= high(c):
+    if i > 0: add(result, ",")
+    addf(result, "$N$1\"$2\": $3", [istr, c[i], c[i + 1]])
     inc(i, 2)
-  appf(result, "$N$1}", [rspaces(indent)])
-
-proc symToYamlAux(n: PSym, marker: var IntSet, indent: int, 
-                  maxRecDepth: int): PRope = 
-  if n == nil: 
-    result = toRope("null")
-  elif containsOrIncl(marker, n.id): 
-    result = ropef("\"$1 @$2\"", [toRope(n.name.s), toRope(
-        strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))])
-  else: 
+  addf(result, "$N$1}", [rspaces(indent)])
+
+proc symToYamlAux(n: PSym, marker: var IntSet, indent: int,
+                  maxRecDepth: int): Rope =
+  if n == nil:
+    result = rope("null")
+  elif containsOrIncl(marker, n.id):
+    result = "\"$1 @$2\"" % [rope(n.name.s), rope(
+        strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))]
+  else:
     var ast = treeToYamlAux(n.ast, marker, indent + 2, maxRecDepth - 1)
-    result = ropeConstr(indent, [toRope("kind"), 
-                                 makeYamlString($n.kind), 
-                                 toRope("name"), makeYamlString(n.name.s), 
-                                 toRope("typ"), typeToYamlAux(n.typ, marker, 
-                                   indent + 2, maxRecDepth - 1), 
-                                 toRope("info"), lineInfoToStr(n.info), 
-                                 toRope("flags"), flagsToStr(n.flags), 
-                                 toRope("magic"), makeYamlString($n.magic), 
-                                 toRope("ast"), ast, toRope("options"), 
-                                 flagsToStr(n.options), toRope("position"), 
-                                 toRope(n.position)])
-
-proc typeToYamlAux(n: PType, marker: var IntSet, indent: int, 
-                   maxRecDepth: int): PRope = 
-  if n == nil: 
-    result = toRope("null")
-  elif containsOrIncl(marker, n.id): 
-    result = ropef("\"$1 @$2\"", [toRope($n.kind), toRope(
-        strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))])
-  else: 
-    if sonsLen(n) > 0: 
-      result = toRope("[")
-      for i in countup(0, sonsLen(n) - 1): 
-        if i > 0: app(result, ",")
-        appf(result, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(n.sons[i], 
+    result = ropeConstr(indent, [rope("kind"),
+                                 makeYamlString($n.kind),
+                                 rope("name"), makeYamlString(n.name.s),
+                                 rope("typ"), typeToYamlAux(n.typ, marker,
+                                   indent + 2, maxRecDepth - 1),
+                                 rope("info"), lineInfoToStr(n.info),
+                                 rope("flags"), flagsToStr(n.flags),
+                                 rope("magic"), makeYamlString($n.magic),
+                                 rope("ast"), ast, rope("options"),
+                                 flagsToStr(n.options), rope("position"),
+                                 rope(n.position)])
+
+proc typeToYamlAux(n: PType, marker: var IntSet, indent: int,
+                   maxRecDepth: int): Rope =
+  if n == nil:
+    result = rope("null")
+  elif containsOrIncl(marker, n.id):
+    result = "\"$1 @$2\"" % [rope($n.kind), rope(
+        strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))]
+  else:
+    if sonsLen(n) > 0:
+      result = rope("[")
+      for i in countup(0, sonsLen(n) - 1):
+        if i > 0: add(result, ",")
+        addf(result, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(n.sons[i],
             marker, indent + 4, maxRecDepth - 1)])
-      appf(result, "$N$1]", [rspaces(indent + 2)])
-    else: 
-      result = toRope("null")
-    result = ropeConstr(indent, [toRope("kind"), 
-                                 makeYamlString($n.kind), 
-                                 toRope("sym"), symToYamlAux(n.sym, marker, 
-        indent + 2, maxRecDepth - 1), toRope("n"), treeToYamlAux(n.n, marker, 
-        indent + 2, maxRecDepth - 1), toRope("flags"), flagsToStr(n.flags), 
-                                 toRope("callconv"), 
-                                 makeYamlString(CallingConvToStr[n.callConv]), 
-                                 toRope("size"), toRope(n.size), 
-                                 toRope("align"), toRope(n.align), 
-                                 toRope("sons"), result])
-
-proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int, 
-                   maxRecDepth: int): PRope = 
-  if n == nil: 
-    result = toRope("null")
-  else: 
+      addf(result, "$N$1]", [rspaces(indent + 2)])
+    else:
+      result = rope("null")
+    result = ropeConstr(indent, [rope("kind"),
+                                 makeYamlString($n.kind),
+                                 rope("sym"), symToYamlAux(n.sym, marker,
+        indent + 2, maxRecDepth - 1), rope("n"), treeToYamlAux(n.n, marker,
+        indent + 2, maxRecDepth - 1), rope("flags"), flagsToStr(n.flags),
+                                 rope("callconv"),
+                                 makeYamlString(CallingConvToStr[n.callConv]),
+                                 rope("size"), rope(n.size),
+                                 rope("align"), rope(n.align),
+                                 rope("sons"), result])
+
+proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int,
+                   maxRecDepth: int): Rope =
+  if n == nil:
+    result = rope("null")
+  else:
     var istr = rspaces(indent + 2)
-    result = ropef("{$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
-    if maxRecDepth != 0: 
-      appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
+    result = "{$N$1\"kind\": $2" % [istr, makeYamlString($n.kind)]
+    if maxRecDepth != 0:
+      addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
       case n.kind
-      of nkCharLit..nkInt64Lit: 
-        appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)])
-      of nkFloatLit, nkFloat32Lit, nkFloat64Lit: 
-        appf(result, ",$N$1\"floatVal\": $2", 
-            [istr, toRope(n.floatVal.toStrMaxPrecision)])
-      of nkStrLit..nkTripleStrLit: 
+      of nkCharLit..nkInt64Lit:
+        addf(result, ",$N$1\"intVal\": $2", [istr, rope(n.intVal)])
+      of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
+        addf(result, ",$N$1\"floatVal\": $2",
+            [istr, rope(n.floatVal.toStrMaxPrecision)])
+      of nkStrLit..nkTripleStrLit:
         if n.strVal.isNil:
-          appf(result, ",$N$1\"strVal\": null", [istr])
+          addf(result, ",$N$1\"strVal\": null", [istr])
         else:
-          appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
-      of nkSym: 
-        appf(result, ",$N$1\"sym\": $2", 
+          addf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
+      of nkSym:
+        addf(result, ",$N$1\"sym\": $2",
              [istr, symToYamlAux(n.sym, marker, indent + 2, maxRecDepth)])
-      of nkIdent: 
-        if n.ident != nil: 
-          appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
-        else: 
-          appf(result, ",$N$1\"ident\": null", [istr])
-      else: 
-        if sonsLen(n) > 0: 
-          appf(result, ",$N$1\"sons\": [", [istr])
-          for i in countup(0, sonsLen(n) - 1): 
-            if i > 0: app(result, ",")
-            appf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(n.sons[i], 
+      of nkIdent:
+        if n.ident != nil:
+          addf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
+        else:
+          addf(result, ",$N$1\"ident\": null", [istr])
+      else:
+        if sonsLen(n) > 0:
+          addf(result, ",$N$1\"sons\": [", [istr])
+          for i in countup(0, sonsLen(n) - 1):
+            if i > 0: add(result, ",")
+            addf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(n.sons[i],
                 marker, indent + 4, maxRecDepth - 1)])
-          appf(result, "$N$1]", [istr])
-      appf(result, ",$N$1\"typ\": $2", 
+          addf(result, "$N$1]", [istr])
+      addf(result, ",$N$1\"typ\": $2",
            [istr, typeToYamlAux(n.typ, marker, indent + 2, maxRecDepth)])
-    appf(result, "$N$1}", [rspaces(indent)])
+    addf(result, "$N$1}", [rspaces(indent)])
 
-proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope = 
+proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope =
   var marker = initIntSet()
   result = treeToYamlAux(n, marker, indent, maxRecDepth)
 
-proc typeToYaml(n: PType, indent: int = 0, maxRecDepth: int = - 1): PRope = 
+proc typeToYaml(n: PType, indent: int = 0, maxRecDepth: int = - 1): Rope =
   var marker = initIntSet()
   result = typeToYamlAux(n, marker, indent, maxRecDepth)
 
-proc symToYaml(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope = 
+proc symToYaml(n: PSym, indent: int = 0, maxRecDepth: int = - 1): Rope =
   var marker = initIntSet()
   result = symToYamlAux(n, marker, indent, maxRecDepth)
 
-proc debugTree(n: PNode, indent: int, maxRecDepth: int; renderType=false): PRope
-proc debugType(n: PType, maxRecDepth=100): PRope = 
-  if n == nil: 
-    result = toRope("null")
+proc debugTree*(n: PNode, indent: int, maxRecDepth: int; renderType=false): Rope
+proc debugType(n: PType, maxRecDepth=100): Rope =
+  if n == nil:
+    result = rope("null")
   else:
-    result = toRope($n.kind)
-    if n.sym != nil: 
-      app(result, " ")
-      app(result, n.sym.name.s)
+    result = rope($n.kind)
+    if n.sym != nil:
+      add(result, " ")
+      add(result, n.sym.name.s)
     if n.kind in IntegralTypes and n.n != nil:
-      app(result, ", node: ")
-      app(result, debugTree(n.n, 2, maxRecDepth-1, renderType=true))
+      add(result, ", node: ")
+      add(result, debugTree(n.n, 2, maxRecDepth-1, renderType=true))
     if (n.kind != tyString) and (sonsLen(n) > 0) and maxRecDepth != 0:
-      app(result, "(")
+      add(result, "(")
       for i in countup(0, sonsLen(n) - 1):
-        if i > 0: app(result, ", ")
+        if i > 0: add(result, ", ")
         if n.sons[i] == nil:
-          app(result, "null")
+          add(result, "null")
         else:
-          app(result, debugType(n.sons[i], maxRecDepth-1))
+          add(result, debugType(n.sons[i], maxRecDepth-1))
       if n.kind == tyObject and n.n != nil:
-        app(result, ", node: ")
-        app(result, debugTree(n.n, 2, maxRecDepth-1, renderType=true))
-      app(result, ")")
+        add(result, ", node: ")
+        add(result, debugTree(n.n, 2, maxRecDepth-1, renderType=true))
+      add(result, ")")
 
 proc debugTree(n: PNode, indent: int, maxRecDepth: int;
-               renderType=false): PRope = 
-  if n == nil: 
-    result = toRope("null")
-  else: 
+               renderType=false): Rope =
+  if n == nil:
+    result = rope("null")
+  else:
     var istr = rspaces(indent + 2)
-    result = ropef("{$N$1\"kind\": $2", 
-                   [istr, makeYamlString($n.kind)])
-    if maxRecDepth != 0: 
+    result = "{$N$1\"kind\": $2" %
+             [istr, makeYamlString($n.kind)]
+    if maxRecDepth != 0:
       case n.kind
       of nkCharLit..nkUInt64Lit:
-        appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)])
-      of nkFloatLit, nkFloat32Lit, nkFloat64Lit: 
-        appf(result, ",$N$1\"floatVal\": $2", 
-            [istr, toRope(n.floatVal.toStrMaxPrecision)])
-      of nkStrLit..nkTripleStrLit: 
+        addf(result, ",$N$1\"intVal\": $2", [istr, rope(n.intVal)])
+      of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
+        addf(result, ",$N$1\"floatVal\": $2",
+            [istr, rope(n.floatVal.toStrMaxPrecision)])
+      of nkStrLit..nkTripleStrLit:
         if n.strVal.isNil:
-          appf(result, ",$N$1\"strVal\": null", [istr])
+          addf(result, ",$N$1\"strVal\": null", [istr])
         else:
-          appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
-      of nkSym: 
-        appf(result, ",$N$1\"sym\": $2_$3", 
-            [istr, toRope(n.sym.name.s), toRope(n.sym.id)])
-        #     [istr, symToYaml(n.sym, indent, maxRecDepth), 
-        #     toRope(n.sym.id)])
+          addf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
+      of nkSym:
+        addf(result, ",$N$1\"sym\": $2_$3",
+            [istr, rope(n.sym.name.s), rope(n.sym.id)])
+        #     [istr, symToYaml(n.sym, indent, maxRecDepth),
+        #     rope(n.sym.id)])
         if renderType and n.sym.typ != nil:
-          appf(result, ",$N$1\"typ\": $2", [istr, debugType(n.sym.typ, 2)])
-      of nkIdent: 
-        if n.ident != nil: 
-          appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
-        else: 
-          appf(result, ",$N$1\"ident\": null", [istr])
-      else: 
-        if sonsLen(n) > 0: 
-          appf(result, ",$N$1\"sons\": [", [istr])
-          for i in countup(0, sonsLen(n) - 1): 
-            if i > 0: app(result, ",")
-            appf(result, "$N$1$2", [rspaces(indent + 4), debugTree(n.sons[i], 
+          addf(result, ",$N$1\"typ\": $2", [istr, debugType(n.sym.typ, 2)])
+      of nkIdent:
+        if n.ident != nil:
+          addf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
+        else:
+          addf(result, ",$N$1\"ident\": null", [istr])
+      else:
+        if sonsLen(n) > 0:
+          addf(result, ",$N$1\"sons\": [", [istr])
+          for i in countup(0, sonsLen(n) - 1):
+            if i > 0: add(result, ",")
+            addf(result, "$N$1$2", [rspaces(indent + 4), debugTree(n.sons[i],
                 indent + 4, maxRecDepth - 1, renderType)])
-          appf(result, "$N$1]", [istr])
-    appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
-    appf(result, "$N$1}", [rspaces(indent)])
+          addf(result, "$N$1]", [istr])
+    addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
+    addf(result, "$N$1}", [rspaces(indent)])
 
 proc debug(n: PSym) =
   if n == nil:
@@ -452,27 +452,26 @@ proc debug(n: PSym) =
   elif n.kind == skUnknown:
     msgWriteln("skUnknown")
   else:
-    #writeln(stdout, ropeToStr(symToYaml(n, 0, 1)))
+    #writeln(stdout, $symToYaml(n, 0, 1))
     msgWriteln("$1_$2: $3, $4, $5, $6" % [
-      n.name.s, $n.id, flagsToStr(n.flags).ropeToStr, 
-      flagsToStr(n.loc.flags).ropeToStr, lineInfoToStr(n.info).ropeToStr,
-      $n.kind])
+      n.name.s, $n.id, $flagsToStr(n.flags), $flagsToStr(n.loc.flags),
+      $lineInfoToStr(n.info), $n.kind])
 
-proc debug(n: PType) = 
-  msgWriteln(ropeToStr(debugType(n)))
+proc debug(n: PType) =
+  msgWriteln($debugType(n))
 
-proc debug(n: PNode) = 
-  msgWriteln(ropeToStr(debugTree(n, 0, 100)))
+proc debug(n: PNode) =
+  msgWriteln($debugTree(n, 0, 100))
 
-const 
+const
   EmptySeq = @[]
 
-proc nextTry(h, maxHash: THash): THash = 
-  result = ((5 * h) + 1) and maxHash 
+proc nextTry(h, maxHash: THash): THash =
+  result = ((5 * h) + 1) and maxHash
   # For any initial h in range(maxHash), repeating that maxHash times
   # generates each int in range(maxHash) exactly once (see any text on
   # random-number generation for proof).
-  
+
 proc objectSetContains(t: TObjectSet, obj: RootRef): bool =
   # returns true whether n is in t
   var h: THash = hashNode(obj) and high(t.data) # start with real hash value
@@ -490,94 +489,94 @@ proc objectSetRawInsert(data: var TObjectSeq, obj: RootRef) =
   assert(data[h] == nil)
   data[h] = obj
 
-proc objectSetEnlarge(t: var TObjectSet) = 
+proc objectSetEnlarge(t: var TObjectSet) =
   var n: TObjectSeq
   newSeq(n, len(t.data) * GrowthFactor)
   for i in countup(0, high(t.data)):
     if t.data[i] != nil: objectSetRawInsert(n, t.data[i])
   swap(t.data, n)
 
-proc objectSetIncl(t: var TObjectSet, obj: RootRef) = 
+proc objectSetIncl(t: var TObjectSet, obj: RootRef) =
   if mustRehash(len(t.data), t.counter): objectSetEnlarge(t)
   objectSetRawInsert(t.data, obj)
   inc(t.counter)
 
-proc objectSetContainsOrIncl(t: var TObjectSet, obj: RootRef): bool = 
+proc objectSetContainsOrIncl(t: var TObjectSet, obj: RootRef): bool =
   # returns true if obj is already in the string table:
   var h: THash = hashNode(obj) and high(t.data)
-  while true: 
+  while true:
     var it = t.data[h]
-    if it == nil: break 
-    if it == obj: 
+    if it == nil: break
+    if it == obj:
       return true             # found it
     h = nextTry(h, high(t.data))
-  if mustRehash(len(t.data), t.counter): 
+  if mustRehash(len(t.data), t.counter):
     objectSetEnlarge(t)
     objectSetRawInsert(t.data, obj)
-  else: 
+  else:
     assert(t.data[h] == nil)
     t.data[h] = obj
   inc(t.counter)
   result = false
 
-proc tableRawGet(t: TTable, key: RootRef): int = 
+proc tableRawGet(t: TTable, key: RootRef): int =
   var h: THash = hashNode(key) and high(t.data) # start with real hash value
-  while t.data[h].key != nil: 
-    if t.data[h].key == key: 
+  while t.data[h].key != nil:
+    if t.data[h].key == key:
       return h
     h = nextTry(h, high(t.data))
   result = -1
 
-proc tableSearch(t: TTable, key, closure: RootRef, 
-                 comparator: TCmpProc): RootRef = 
+proc tableSearch(t: TTable, key, closure: RootRef,
+                 comparator: TCmpProc): RootRef =
   var h: THash = hashNode(key) and high(t.data) # start with real hash value
-  while t.data[h].key != nil: 
-    if t.data[h].key == key: 
-      if comparator(t.data[h].val, closure): 
+  while t.data[h].key != nil:
+    if t.data[h].key == key:
+      if comparator(t.data[h].val, closure):
         # BUGFIX 1
         return t.data[h].val
     h = nextTry(h, high(t.data))
   result = nil
 
-proc tableGet(t: TTable, key: RootRef): RootRef = 
+proc tableGet(t: TTable, key: RootRef): RootRef =
   var index = tableRawGet(t, key)
   if index >= 0: result = t.data[index].val
   else: result = nil
-  
-proc tableRawInsert(data: var TPairSeq, key, val: RootRef) = 
+
+proc tableRawInsert(data: var TPairSeq, key, val: RootRef) =
   var h: THash = hashNode(key) and high(data)
-  while data[h].key != nil: 
+  while data[h].key != nil:
     assert(data[h].key != key)
     h = nextTry(h, high(data))
   assert(data[h].key == nil)
   data[h].key = key
   data[h].val = val
 
-proc tableEnlarge(t: var TTable) = 
+proc tableEnlarge(t: var TTable) =
   var n: TPairSeq
   newSeq(n, len(t.data) * GrowthFactor)
-  for i in countup(0, high(t.data)): 
+  for i in countup(0, high(t.data)):
     if t.data[i].key != nil: tableRawInsert(n, t.data[i].key, t.data[i].val)
   swap(t.data, n)
 
-proc tablePut(t: var TTable, key, val: RootRef) = 
+proc tablePut(t: var TTable, key, val: RootRef) =
   var index = tableRawGet(t, key)
-  if index >= 0: 
+  if index >= 0:
     t.data[index].val = val
-  else: 
+  else:
     if mustRehash(len(t.data), t.counter): tableEnlarge(t)
     tableRawInsert(t.data, key, val)
     inc(t.counter)
 
-proc strTableContains(t: TStrTable, n: PSym): bool = 
+proc strTableContains(t: TStrTable, n: PSym): bool =
   var h: THash = n.name.h and high(t.data) # start with real hash value
-  while t.data[h] != nil: 
-    if (t.data[h] == n): 
+  while t.data[h] != nil:
+    if (t.data[h] == n):
       return true
     h = nextTry(h, high(t.data))
   result = false
 
-proc strTableRawInsert(data: var TSymSeq, n: PSym) = 
+proc strTableRawInsert(data: var TSymSeq, n: PSym) =
   var h: THash = n.name.h and high(data)
   if sfImmediate notin n.flags:
     # fast path:
@@ -614,18 +613,18 @@ proc symTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) =
       return
     h = nextTry(h, high(data))
   assert false
- 
+
 proc symTabReplace*(t: var TStrTable, prevSym: PSym, newSym: PSym) =
   symTabReplaceRaw(t.data, prevSym, newSym)
 
-proc strTableEnlarge(t: var TStrTable) = 
+proc strTableEnlarge(t: var TStrTable) =
   var n: TSymSeq
   newSeq(n, len(t.data) * GrowthFactor)
-  for i in countup(0, high(t.data)): 
+  for i in countup(0, high(t.data)):
     if t.data[i] != nil: strTableRawInsert(n, t.data[i])
   swap(t.data, n)
 
-proc strTableAdd(t: var TStrTable, n: PSym) = 
+proc strTableAdd(t: var TStrTable, n: PSym) =
   if mustRehash(len(t.data), t.counter): strTableEnlarge(t)
   strTableRawInsert(t.data, n)
   inc(t.counter)
@@ -666,103 +665,103 @@ proc strTableIncl*(t: var TStrTable, n: PSym): bool {.discardable.} =
   inc(t.counter)
   result = false
 
-proc strTableGet(t: TStrTable, name: PIdent): PSym = 
+proc strTableGet(t: TStrTable, name: PIdent): PSym =
   var h: THash = name.h and high(t.data)
-  while true: 
+  while true:
     result = t.data[h]
-    if result == nil: break 
-    if result.name.id == name.id: break 
+    if result == nil: break
+    if result.name.id == name.id: break
     h = nextTry(h, high(t.data))
 
-proc initIdentIter(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym = 
+proc initIdentIter(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym =
   ti.h = s.h
   ti.name = s
   if tab.counter == 0: result = nil
   else: result = nextIdentIter(ti, tab)
-  
-proc nextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym = 
+
+proc nextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym =
   var h = ti.h and high(tab.data)
   var start = h
   result = tab.data[h]
-  while result != nil: 
-    if result.name.id == ti.name.id: break 
+  while result != nil:
+    if result.name.id == ti.name.id: break
     h = nextTry(h, high(tab.data))
-    if h == start: 
+    if h == start:
       result = nil
-      break 
+      break
     result = tab.data[h]
   ti.h = nextTry(h, high(tab.data))
-  
-proc nextIdentExcluding*(ti: var TIdentIter, tab: TStrTable, 
+
+proc nextIdentExcluding*(ti: var TIdentIter, tab: TStrTable,
                          excluding: IntSet): PSym =
   var h: THash = ti.h and high(tab.data)
   var start = h
   result = tab.data[h]
-  while result != nil: 
-    if result.name.id == ti.name.id and not contains(excluding, result.id): 
+  while result != nil:
+    if result.name.id == ti.name.id and not contains(excluding, result.id):
       break
     h = nextTry(h, high(tab.data))
-    if h == start: 
+    if h == start:
       result = nil
-      break 
+      break
     result = tab.data[h]
   ti.h = nextTry(h, high(tab.data))
   if result != nil and contains(excluding, result.id): result = nil
 
 proc firstIdentExcluding*(ti: var TIdentIter, tab: TStrTable, s: PIdent,
-                          excluding: IntSet): PSym = 
+                          excluding: IntSet): PSym =
   ti.h = s.h
   ti.name = s
   if tab.counter == 0: result = nil
   else: result = nextIdentExcluding(ti, tab, excluding)
 
-proc initTabIter(ti: var TTabIter, tab: TStrTable): PSym = 
+proc initTabIter(ti: var TTabIter, tab: TStrTable): PSym =
   ti.h = 0                    # we start by zero ...
-  if tab.counter == 0: 
+  if tab.counter == 0:
     result = nil              # FIX 1: removed endless loop
-  else: 
+  else:
     result = nextIter(ti, tab)
-  
-proc nextIter(ti: var TTabIter, tab: TStrTable): PSym = 
+
+proc nextIter(ti: var TTabIter, tab: TStrTable): PSym =
   result = nil
-  while (ti.h <= high(tab.data)): 
+  while (ti.h <= high(tab.data)):
     result = tab.data[ti.h]
     inc(ti.h)                 # ... and increment by one always
-    if result != nil: break 
+    if result != nil: break
 
-iterator items*(tab: TStrTable): PSym = 
+iterator items*(tab: TStrTable): PSym =
   var it: TTabIter
   var s = initTabIter(it, tab)
-  while s != nil: 
+  while s != nil:
     yield s
     s = nextIter(it, tab)
 
-proc hasEmptySlot(data: TIdPairSeq): bool = 
-  for h in countup(0, high(data)): 
-    if data[h].key == nil: 
+proc hasEmptySlot(data: TIdPairSeq): bool =
+  for h in countup(0, high(data)):
+    if data[h].key == nil:
       return true
   result = false
 
-proc idTableRawGet(t: TIdTable, key: int): int = 
+proc idTableRawGet(t: TIdTable, key: int): int =
   var h: THash
   h = key and high(t.data)    # start with real hash value
-  while t.data[h].key != nil: 
+  while t.data[h].key != nil:
     if t.data[h].key.id == key:
       return h
     h = nextTry(h, high(t.data))
   result = - 1
 
-proc idTableHasObjectAsKey(t: TIdTable, key: PIdObj): bool = 
+proc idTableHasObjectAsKey(t: TIdTable, key: PIdObj): bool =
   var index = idTableRawGet(t, key.id)
   if index >= 0: result = t.data[index].key == key
   else: result = false
-  
-proc idTableGet(t: TIdTable, key: PIdObj): RootRef = 
+
+proc idTableGet(t: TIdTable, key: PIdObj): RootRef =
   var index = idTableRawGet(t, key.id)
   if index >= 0: result = t.data[index].val
   else: result = nil
-  
-proc idTableGet(t: TIdTable, key: int): RootRef = 
+
+proc idTableGet(t: TIdTable, key: int): RootRef =
   var index = idTableRawGet(t, key)
   if index >= 0: result = t.data[index].val
   else: result = nil
@@ -771,30 +770,30 @@ iterator pairs*(t: TIdTable): tuple[key: int, value: RootRef] =
   for i in 0..high(t.data):
     if t.data[i].key != nil:
       yield (t.data[i].key.id, t.data[i].val)
-  
-proc idTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: RootRef) = 
+
+proc idTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: RootRef) =
   var h: THash
   h = key.id and high(data)
-  while data[h].key != nil: 
+  while data[h].key != nil:
     assert(data[h].key.id != key.id)
     h = nextTry(h, high(data))
   assert(data[h].key == nil)
   data[h].key = key
   data[h].val = val
 
-proc idTablePut(t: var TIdTable, key: PIdObj, val: RootRef) = 
-  var 
+proc idTablePut(t: var TIdTable, key: PIdObj, val: RootRef) =
+  var
     index: int
     n: TIdPairSeq
   index = idTableRawGet(t, key.id)
-  if index >= 0: 
+  if index >= 0:
     assert(t.data[index].key != nil)
     t.data[index].val = val
-  else: 
-    if mustRehash(len(t.data), t.counter): 
+  else:
+    if mustRehash(len(t.data), t.counter):
       newSeq(n, len(t.data) * GrowthFactor)
-      for i in countup(0, high(t.data)): 
-        if t.data[i].key != nil: 
+      for i in countup(0, high(t.data)):
+        if t.data[i].key != nil:
           idTableRawInsert(n, t.data[i].key, t.data[i].val)
       assert(hasEmptySlot(n))
       swap(t.data, n)
@@ -805,7 +804,7 @@ iterator idTablePairs*(t: TIdTable): tuple[key: PIdObj, val: RootRef] =
   for i in 0 .. high(t.data):
     if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val)
 
-proc idNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int = 
+proc idNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int =
   var h: THash
   h = key.id and high(t.data) # start with real hash value
   while t.data[h].key != nil:
@@ -814,7 +813,7 @@ proc idNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int =
     h = nextTry(h, high(t.data))
   result = - 1
 
-proc idNodeTableGet(t: TIdNodeTable, key: PIdObj): PNode = 
+proc idNodeTableGet(t: TIdNodeTable, key: PIdObj): PNode =
   var index: int
   index = idNodeTableRawGet(t, key)
   if index >= 0: result = t.data[index].val
@@ -823,28 +822,28 @@ proc idNodeTableGet(t: TIdNodeTable, key: PIdObj): PNode =
 proc idNodeTableGetLazy*(t: TIdNodeTable, key: PIdObj): PNode =
   if not isNil(t.data):
     result = idNodeTableGet(t, key)
-  
-proc idNodeTableRawInsert(data: var TIdNodePairSeq, key: PIdObj, val: PNode) = 
+
+proc idNodeTableRawInsert(data: var TIdNodePairSeq, key: PIdObj, val: PNode) =
   var h: THash
   h = key.id and high(data)
-  while data[h].key != nil: 
+  while data[h].key != nil:
     assert(data[h].key.id != key.id)
     h = nextTry(h, high(data))
   assert(data[h].key == nil)
   data[h].key = key
   data[h].val = val
 
-proc idNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) = 
+proc idNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) =
   var index = idNodeTableRawGet(t, key)
-  if index >= 0: 
+  if index >= 0:
     assert(t.data[index].key != nil)
     t.data[index].val = val
-  else: 
-    if mustRehash(len(t.data), t.counter): 
+  else:
+    if mustRehash(len(t.data), t.counter):
       var n: TIdNodePairSeq
       newSeq(n, len(t.data) * GrowthFactor)
-      for i in countup(0, high(t.data)): 
-        if t.data[i].key != nil: 
+      for i in countup(0, high(t.data)):
+        if t.data[i].key != nil:
           idNodeTableRawInsert(n, t.data[i].key, t.data[i].val)
       swap(t.data, n)
     idNodeTableRawInsert(t.data, key, val)
@@ -858,46 +857,46 @@ iterator pairs*(t: TIdNodeTable): tuple[key: PIdObj, val: PNode] =
   for i in 0 .. high(t.data):
     if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val)
 
-proc initIITable(x: var TIITable) = 
+proc initIITable(x: var TIITable) =
   x.counter = 0
   newSeq(x.data, StartSize)
   for i in countup(0, StartSize - 1): x.data[i].key = InvalidKey
-  
-proc iiTableRawGet(t: TIITable, key: int): int = 
+
+proc iiTableRawGet(t: TIITable, key: int): int =
   var h: THash
   h = key and high(t.data)    # start with real hash value
-  while t.data[h].key != InvalidKey: 
+  while t.data[h].key != InvalidKey:
     if t.data[h].key == key: return h
     h = nextTry(h, high(t.data))
   result = -1
 
-proc iiTableGet(t: TIITable, key: int): int = 
+proc iiTableGet(t: TIITable, key: int): int =
   var index = iiTableRawGet(t, key)
   if index >= 0: result = t.data[index].val
   else: result = InvalidKey
-  
-proc iiTableRawInsert(data: var TIIPairSeq, key, val: int) = 
+
+proc iiTableRawInsert(data: var TIIPairSeq, key, val: int) =
   var h: THash
   h = key and high(data)
-  while data[h].key != InvalidKey: 
+  while data[h].key != InvalidKey:
     assert(data[h].key != key)
     h = nextTry(h, high(data))
   assert(data[h].key == InvalidKey)
   data[h].key = key
   data[h].val = val
 
-proc iiTablePut(t: var TIITable, key, val: int) = 
+proc iiTablePut(t: var TIITable, key, val: int) =
   var index = iiTableRawGet(t, key)
-  if index >= 0: 
+  if index >= 0:
     assert(t.data[index].key != InvalidKey)
     t.data[index].val = val
-  else: 
-    if mustRehash(len(t.data), t.counter): 
+  else:
+    if mustRehash(len(t.data), t.counter):
       var n: TIIPairSeq
       newSeq(n, len(t.data) * GrowthFactor)
       for i in countup(0, high(n)): n[i].key = InvalidKey
-      for i in countup(0, high(t.data)): 
-        if t.data[i].key != InvalidKey: 
+      for i in countup(0, high(t.data)):
+        if t.data[i].key != InvalidKey:
           iiTableRawInsert(n, t.data[i].key, t.data[i].val)
       swap(t.data, n)
     iiTableRawInsert(t.data, key, val)