dollars.nim 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. ## `$` is Nim's general way of spelling `toString`:idx:.
  2. runnableExamples:
  3. assert $0.1 == "0.1"
  4. assert $(-2*3) == "-6"
  5. import std/private/digitsutils
  6. import system/formatfloat
  7. export addFloat
  8. proc `$`*(x: int): string {.raises: [].} =
  9. ## Outplace version of `addInt`.
  10. result.addInt(x)
  11. proc `$`*(x: int64): string {.raises: [].} =
  12. ## Outplace version of `addInt`.
  13. result.addInt(x)
  14. proc `$`*(x: uint64): string {.raises: [].} =
  15. ## Outplace version of `addInt`.
  16. addInt(result, x)
  17. # same as old `ctfeWhitelist` behavior, whether or not this is a good idea.
  18. template gen(T) =
  19. # xxx simplify this by supporting this in compiler: int{lit} | uint64{lit} | int64{lit}
  20. func `$`*(x: T{lit}): string {.compileTime.} = result.addInt(x)
  21. gen(int)
  22. gen(uint64)
  23. gen(int64)
  24. func `$`*(x: float | float32): string =
  25. ## Outplace version of `addFloat`.
  26. result.addFloat(x)
  27. proc `$`*(x: bool): string {.magic: "BoolToStr", noSideEffect.}
  28. ## The stringify operator for a boolean argument. Returns `x`
  29. ## converted to the string "false" or "true".
  30. proc `$`*(x: char): string {.magic: "CharToStr", noSideEffect.}
  31. ## The stringify operator for a character argument. Returns `x`
  32. ## converted to a string.
  33. ##
  34. ## .. code-block:: Nim
  35. ## assert $'c' == "c"
  36. proc `$`*(x: cstring): string {.magic: "CStrToStr", noSideEffect.}
  37. ## The stringify operator for a CString argument. Returns `x`
  38. ## converted to a string.
  39. proc `$`*(x: string): string {.magic: "StrToStr", noSideEffect.}
  40. ## The stringify operator for a string argument. Returns `x`
  41. ## as it is. This operator is useful for generic code, so
  42. ## that `$expr` also works if `expr` is already a string.
  43. proc `$`*[Enum: enum](x: Enum): string {.magic: "EnumToStr", noSideEffect.}
  44. ## The stringify operator for an enumeration argument. This works for
  45. ## any enumeration type thanks to compiler magic.
  46. ##
  47. ## If a `$` operator for a concrete enumeration is provided, this is
  48. ## used instead. (In other words: *Overwriting* is possible.)
  49. proc `$`*(t: typedesc): string {.magic: "TypeTrait".}
  50. ## Returns the name of the given type.
  51. ##
  52. ## For more procedures dealing with `typedesc`, see
  53. ## `typetraits module <typetraits.html>`_.
  54. ##
  55. ## .. code-block:: Nim
  56. ## doAssert $(typeof(42)) == "int"
  57. ## doAssert $(typeof("Foo")) == "string"
  58. ## static: doAssert $(typeof(@['A', 'B'])) == "seq[char]"
  59. when defined(nimHasIsNamedTuple):
  60. proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait".}
  61. else:
  62. # for bootstrap; remove after release 1.2
  63. proc isNamedTuple(T: typedesc): bool =
  64. # Taken from typetraits.
  65. when T isnot tuple: result = false
  66. else:
  67. var t: T
  68. for name, _ in t.fieldPairs:
  69. when name == "Field0":
  70. return compiles(t.Field0)
  71. else:
  72. return true
  73. return false
  74. proc `$`*[T: tuple|object](x: T): string =
  75. ## Generic `$` operator for tuples that is lifted from the components
  76. ## of `x`. Example:
  77. ##
  78. ## .. code-block:: Nim
  79. ## $(23, 45) == "(23, 45)"
  80. ## $(a: 23, b: 45) == "(a: 23, b: 45)"
  81. ## $() == "()"
  82. result = "("
  83. const isNamed = T is object or isNamedTuple(T)
  84. var count {.used.} = 0
  85. for name, value in fieldPairs(x):
  86. if count > 0: result.add(", ")
  87. when isNamed:
  88. result.add(name)
  89. result.add(": ")
  90. count.inc
  91. when compiles($value):
  92. when value isnot string and value isnot seq and compiles(value.isNil):
  93. if value.isNil: result.add "nil"
  94. else: result.addQuoted(value)
  95. else:
  96. result.addQuoted(value)
  97. else:
  98. result.add("...")
  99. when not isNamed:
  100. if count == 1:
  101. result.add(",") # $(1,) should print as the semantically legal (1,)
  102. result.add(")")
  103. proc collectionToString[T](x: T, prefix, separator, suffix: string): string =
  104. result = prefix
  105. var firstElement = true
  106. for value in items(x):
  107. if firstElement:
  108. firstElement = false
  109. else:
  110. result.add(separator)
  111. when value isnot string and value isnot seq and compiles(value.isNil):
  112. # this branch should not be necessary
  113. if value.isNil:
  114. result.add "nil"
  115. else:
  116. result.addQuoted(value)
  117. else:
  118. result.addQuoted(value)
  119. result.add(suffix)
  120. proc `$`*[T](x: set[T]): string =
  121. ## Generic `$` operator for sets that is lifted from the components
  122. ## of `x`. Example:
  123. ##
  124. ## .. code-block:: Nim
  125. ## ${23, 45} == "{23, 45}"
  126. collectionToString(x, "{", ", ", "}")
  127. proc `$`*[T](x: seq[T]): string =
  128. ## Generic `$` operator for seqs that is lifted from the components
  129. ## of `x`. Example:
  130. ##
  131. ## .. code-block:: Nim
  132. ## $(@[23, 45]) == "@[23, 45]"
  133. collectionToString(x, "@[", ", ", "]")
  134. proc `$`*[T, U](x: HSlice[T, U]): string =
  135. ## Generic `$` operator for slices that is lifted from the components
  136. ## of `x`. Example:
  137. ##
  138. ## .. code-block:: Nim
  139. ## $(1 .. 5) == "1 .. 5"
  140. result = $x.a
  141. result.add(" .. ")
  142. result.add($x.b)
  143. when not defined(nimNoArrayToString):
  144. proc `$`*[T, IDX](x: array[IDX, T]): string =
  145. ## Generic `$` operator for arrays that is lifted from the components.
  146. collectionToString(x, "[", ", ", "]")
  147. proc `$`*[T](x: openArray[T]): string =
  148. ## Generic `$` operator for openarrays that is lifted from the components
  149. ## of `x`. Example:
  150. ##
  151. ## .. code-block:: Nim
  152. ## $(@[23, 45].toOpenArray(0, 1)) == "[23, 45]"
  153. collectionToString(x, "[", ", ", "]")