summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorcooldome <cdome@bk.ru>2020-01-28 19:05:57 +0000
committerAndreas Rumpf <rumpf_a@web.de>2020-01-28 20:05:57 +0100
commit76ede7c19801c740daa9ece29dcd0150a9a670ad (patch)
tree0e5a503cabe96e570cefe7b113c2f39c7d1f5604
parent92010becbe00b338abd4d9ef1be17739be8f69b8 (diff)
downloadNim-76ede7c19801c740daa9ece29dcd0150a9a670ad.tar.gz
Repr v2 progress (#13268)
* progress on repr_v2

* repr progress

* add ref objects with distrinct

* fix failing tests
-rw-r--r--lib/system.nim7
-rw-r--r--lib/system/repr_v2.nim130
-rw-r--r--tests/arc/trepr.nim34
-rw-r--r--tests/destructor/tfinalizer.nim2
4 files changed, 96 insertions, 77 deletions
diff --git a/lib/system.nim b/lib/system.nim
index a32995350..92470fbce 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1988,10 +1988,6 @@ template unlikely*(val: bool): bool =
 import system/dollars
 export dollars
 
-when defined(nimV2):
-  import system/repr_v2
-  export repr_v2
-
 const
   NimMajor* {.intdefine.}: int = 1
     ## is the major number of Nim's version.
@@ -2620,7 +2616,8 @@ type
     ## Represents a Nim AST node. Macros operate on this type.
 
 when defined(nimV2):
-  proc repr*(x: NimNode): string {.magic: "Repr", noSideEffect.}
+  import system/repr_v2
+  export repr_v2
 
 macro lenVarargs*(x: varargs[untyped]): int {.since: (1, 1).} =
   ## returns number of variadic arguments in `x`
diff --git a/lib/system/repr_v2.nim b/lib/system/repr_v2.nim
index 5f4e7ff87..beca1d842 100644
--- a/lib/system/repr_v2.nim
+++ b/lib/system/repr_v2.nim
@@ -1,3 +1,11 @@
+proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait".}
+  ## imported from typetraits
+
+proc distinctBase(T: typedesc): typedesc {.magic: "TypeTrait".}
+  ## imported from typetraits
+
+proc repr*(x: NimNode): string {.magic: "Repr", noSideEffect.}
+
 proc repr*(x: int): string {.magic: "IntToStr", noSideEffect.}
   ## repr for an integer argument. Returns `x`
   ## converted to a decimal string.
@@ -37,80 +45,68 @@ proc repr*[Enum: enum](x: Enum): string {.magic: "EnumToStr", noSideEffect.}
   ## If a `repr` operator for a concrete enumeration is provided, this is
   ## used instead. (In other words: *Overwriting* is possible.)
 
-template repr(t: typedesc): string = $t
-
-proc isNamedTuple(T: typedesc): bool =
-  # Taken from typetraits.
-  when T isnot tuple: result = false
+proc repr*(p: pointer): string =
+  ## repr of pointer as its hexadecimal value
+  if p == nil: 
+    result = "nil"
   else:
-    var t: T
-    for name, _ in t.fieldPairs:
-      when name == "Field0":
-        return compiles(t.Field0)
-      else:
-        return true
-    return false
+    when nimvm:
+      result = "ptr"
+    else:
+      const HexChars = "0123456789ABCDEF"
+      const len = sizeof(pointer) * 2
+      var n = cast[uint](p)
+      result = newString(len)
+      for j in countdown(len-1, 0):
+        result[j] = HexChars[n and 0xF]
+        n = n shr 4
 
-proc repr*[T: tuple|object](x: T): string =
-  ## Generic `repr` operator for tuples that is lifted from the components
-  ## of `x`. Example:
-  ##
-  ## .. code-block:: Nim
-  ##   $(23, 45) == "(23, 45)"
-  ##   $(a: 23, b: 45) == "(a: 23, b: 45)"
-  ##   $() == "()"
-  when T is object:
-    result = $typeof(x)
-  else:
-    result = ""
-  result.add '('
+template repr*(x: distinct): string =
+  repr(distinctBase(typeof(x))(x))
+
+template repr*(t: typedesc): string = $t
+
+proc reprObject[T: tuple|object](res: var string, x: T) = 
+  res.add '('
   var firstElement = true
   const isNamed = T is object or isNamedTuple(T)
   when not isNamed:
     var count = 0
   for name, value in fieldPairs(x):
-    if not firstElement: result.add(", ")
+    if not firstElement: res.add(", ")
     when isNamed:
-      result.add(name)
-      result.add(": ")
+      res.add(name)
+      res.add(": ")
     else:
       count.inc
-    when compiles($value):
-      when value isnot string and value isnot seq and compiles(value.isNil):
-        if value.isNil: result.add "nil"
-        else: result.addQuoted(value)
-      else:
-        result.addQuoted(value)
-      firstElement = false
-    else:
-      result.add("...")
-      firstElement = false
+    res.add repr(value)
+    firstElement = false
   when not isNamed:
     if count == 1:
-      result.add(',') # $(1,) should print as the semantically legal (1,)
-  result.add(')')
+      res.add(',') # $(1,) should print as the semantically legal (1,)
+  res.add(')')
+
 
-proc repr*[T: (ref object)](x: T): string =
+proc repr*[T: tuple|object](x: T): string =
   ## Generic `repr` operator for tuples that is lifted from the components
-  ## of `x`.
-  if x == nil: return "nil"
-  result = $typeof(x) & "("
-  var firstElement = true
-  for name, value in fieldPairs(x[]):
-    if not firstElement: result.add(", ")
-    result.add(name)
-    result.add(": ")
-    when compiles($value):
-      when value isnot string and value isnot seq and compiles(value.isNil):
-        if value.isNil: result.add "nil"
-        else: result.addQuoted(value)
-      else:
-        result.addQuoted(value)
-      firstElement = false
-    else:
-      result.add("...")
-      firstElement = false
-  result.add(')')
+  ## of `x`. Example:
+  ##
+  ## .. code-block:: Nim
+  ##   $(23, 45) == "(23, 45)"
+  ##   $(a: 23, b: 45) == "(a: 23, b: 45)"
+  ##   $() == "()"
+  when T is object:
+    result = $typeof(x)
+  reprObject(result, x)
+ 
+proc repr*[T](x: ptr T): string =
+  result.add repr(pointer(x)) & " "
+  result.add repr(x[])
+
+proc repr*[T](x: ref T | ptr T): string =
+  if isNil(x): return "nil"
+  result = $typeof(x)
+  reprObject(result, x[])
 
 proc collectionToRepr[T](x: T, prefix, separator, suffix: string): string =
   result = prefix
@@ -120,15 +116,7 @@ proc collectionToRepr[T](x: T, prefix, separator, suffix: string): string =
       firstElement = false
     else:
       result.add(separator)
-
-    when value isnot string and value isnot seq and compiles(value.isNil):
-      # this branch should not be necessary
-      if value.isNil:
-        result.add "nil"
-      else:
-        result.addQuoted(value)
-    else:
-      result.addQuoted(value)
+    result.add repr(value)
   result.add(suffix)
 
 proc repr*[T](x: set[T]): string =
@@ -153,9 +141,9 @@ proc repr*[T, U](x: HSlice[T, U]): string =
   ##
   ## .. code-block:: Nim
   ##  $(1 .. 5) == "1 .. 5"
-  result = $x.a
+  result = repr(x.a)
   result.add(" .. ")
-  result.add($x.b)
+  result.add(repr(x.b))
 
 proc repr*[T, IDX](x: array[IDX, T]): string =
   ## Generic `repr` operator for arrays that is lifted from the components.
diff --git a/tests/arc/trepr.nim b/tests/arc/trepr.nim
new file mode 100644
index 000000000..7a92112ed
--- /dev/null
+++ b/tests/arc/trepr.nim
@@ -0,0 +1,34 @@
+discard """
+  cmd: "nim c --gc:arc $file"
+  nimout: '''(a: true, n: doAssert)
+Table[system.string, trepr.MyType](data: @[], counter: 0)
+nil
+'''
+"""
+import tables
+
+type
+  NimSym = distinct NimNode
+  MyType = tuple
+    a: bool
+    n: NimSym
+
+proc myproc(t: MyType) =
+  echo repr(t)
+
+proc myproc2(t: MyType) =
+  var x = Table[string, t]()
+  echo repr(x)
+
+proc myproc3(t: MyType) =
+  var x: TableRef[string, t]
+  echo repr(x)
+
+
+macro dumpSym(a: typed) =
+  myproc((a: true, n: NimSym(a)))
+  myproc2((a: true, n: NimSym(a)))
+  myproc3((a: true, n: NimSym(a)))
+
+dumpSym(doAssert)
+
diff --git a/tests/destructor/tfinalizer.nim b/tests/destructor/tfinalizer.nim
index eb2cd09af..02a5cef7e 100644
--- a/tests/destructor/tfinalizer.nim
+++ b/tests/destructor/tfinalizer.nim
@@ -1,6 +1,6 @@
 discard """
   cmd: "nim c --gc:arc $file"
-  output: '''Foo(field: "Dick Laurent", k: ka, x: 0.0)
+  output: '''Foo(field: Dick Laurent, k: ka, x: 0.0)
 Nobody is dead
 Dick Laurent is dead'''
 """