diff options
author | cooldome <cdome@bk.ru> | 2020-01-28 19:05:57 +0000 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2020-01-28 20:05:57 +0100 |
commit | 76ede7c19801c740daa9ece29dcd0150a9a670ad (patch) | |
tree | 0e5a503cabe96e570cefe7b113c2f39c7d1f5604 | |
parent | 92010becbe00b338abd4d9ef1be17739be8f69b8 (diff) | |
download | Nim-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.nim | 7 | ||||
-rw-r--r-- | lib/system/repr_v2.nim | 130 | ||||
-rw-r--r-- | tests/arc/trepr.nim | 34 | ||||
-rw-r--r-- | tests/destructor/tfinalizer.nim | 2 |
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''' """ |