dollars.nim 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import std/private/since
  2. proc `$`*(x: int): string {.magic: "IntToStr", noSideEffect.}
  3. ## The stringify operator for an integer argument. Returns `x`
  4. ## converted to a decimal string. ``$`` is Nim's general way of
  5. ## spelling `toString`:idx:.
  6. when defined(js):
  7. since (1, 3):
  8. proc `$`*(x: uint): string =
  9. ## Caveat: currently implemented as $(cast[int](x)), tied to current
  10. ## semantics of js' Number type.
  11. # for c, see strmantle.`$`
  12. $(cast[int](x))
  13. proc `$`*(x: uint64): string =
  14. ## Compatibility note:
  15. ## the results may change in future releases if/when js target implements
  16. ## 64bit ints.
  17. # pending https://github.com/nim-lang/RFCs/issues/187
  18. $(cast[int](x))
  19. else:
  20. proc `$`*(x: uint64): string {.noSideEffect, raises: [].} =
  21. ## The stringify operator for an unsigned integer argument. Returns `x`
  22. ## converted to a decimal string.
  23. if x == 0:
  24. result = "0"
  25. else:
  26. result = newString(60)
  27. var i = 0
  28. var n = x
  29. while n != 0:
  30. let nn = n div 10'u64
  31. result[i] = char(n - 10'u64 * nn + ord('0'))
  32. inc i
  33. n = nn
  34. result.setLen i
  35. let half = i div 2
  36. # Reverse
  37. for t in 0 .. half-1: swap(result[t], result[i-t-1])
  38. proc `$`*(x: int64): string {.magic: "Int64ToStr", noSideEffect.}
  39. ## The stringify operator for an integer argument. Returns `x`
  40. ## converted to a decimal string.
  41. proc `$`*(x: float): string {.magic: "FloatToStr", noSideEffect.}
  42. ## The stringify operator for a float argument. Returns `x`
  43. ## converted to a decimal string.
  44. proc `$`*(x: bool): string {.magic: "BoolToStr", noSideEffect.}
  45. ## The stringify operator for a boolean argument. Returns `x`
  46. ## converted to the string "false" or "true".
  47. proc `$`*(x: char): string {.magic: "CharToStr", noSideEffect.}
  48. ## The stringify operator for a character argument. Returns `x`
  49. ## converted to a string.
  50. ##
  51. ## .. code-block:: Nim
  52. ## assert $'c' == "c"
  53. proc `$`*(x: cstring): string {.magic: "CStrToStr", noSideEffect.}
  54. ## The stringify operator for a CString argument. Returns `x`
  55. ## converted to a string.
  56. proc `$`*(x: string): string {.magic: "StrToStr", noSideEffect.}
  57. ## The stringify operator for a string argument. Returns `x`
  58. ## as it is. This operator is useful for generic code, so
  59. ## that ``$expr`` also works if ``expr`` is already a string.
  60. proc `$`*[Enum: enum](x: Enum): string {.magic: "EnumToStr", noSideEffect.}
  61. ## The stringify operator for an enumeration argument. This works for
  62. ## any enumeration type thanks to compiler magic.
  63. ##
  64. ## If a ``$`` operator for a concrete enumeration is provided, this is
  65. ## used instead. (In other words: *Overwriting* is possible.)
  66. proc `$`*(t: typedesc): string {.magic: "TypeTrait".}
  67. ## Returns the name of the given type.
  68. ##
  69. ## For more procedures dealing with ``typedesc``, see
  70. ## `typetraits module <typetraits.html>`_.
  71. ##
  72. ## .. code-block:: Nim
  73. ## doAssert $(typeof(42)) == "int"
  74. ## doAssert $(typeof("Foo")) == "string"
  75. ## static: doAssert $(typeof(@['A', 'B'])) == "seq[char]"
  76. when defined(nimHasIsNamedTuple):
  77. proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait".}
  78. else:
  79. # for bootstrap; remove after release 1.2
  80. proc isNamedTuple(T: typedesc): bool =
  81. # Taken from typetraits.
  82. when T isnot tuple: result = false
  83. else:
  84. var t: T
  85. for name, _ in t.fieldPairs:
  86. when name == "Field0":
  87. return compiles(t.Field0)
  88. else:
  89. return true
  90. return false
  91. proc `$`*[T: tuple|object](x: T): string =
  92. ## Generic ``$`` operator for tuples that is lifted from the components
  93. ## of `x`. Example:
  94. ##
  95. ## .. code-block:: Nim
  96. ## $(23, 45) == "(23, 45)"
  97. ## $(a: 23, b: 45) == "(a: 23, b: 45)"
  98. ## $() == "()"
  99. result = "("
  100. const isNamed = T is object or isNamedTuple(T)
  101. var count = 0
  102. for name, value in fieldPairs(x):
  103. if count > 0: result.add(", ")
  104. when isNamed:
  105. result.add(name)
  106. result.add(": ")
  107. count.inc
  108. when compiles($value):
  109. when value isnot string and value isnot seq and compiles(value.isNil):
  110. if value.isNil: result.add "nil"
  111. else: result.addQuoted(value)
  112. else:
  113. result.addQuoted(value)
  114. else:
  115. result.add("...")
  116. when not isNamed:
  117. if count == 1:
  118. result.add(",") # $(1,) should print as the semantically legal (1,)
  119. result.add(")")
  120. proc collectionToString[T](x: T, prefix, separator, suffix: string): string =
  121. result = prefix
  122. var firstElement = true
  123. for value in items(x):
  124. if firstElement:
  125. firstElement = false
  126. else:
  127. result.add(separator)
  128. when value isnot string and value isnot seq and compiles(value.isNil):
  129. # this branch should not be necessary
  130. if value.isNil:
  131. result.add "nil"
  132. else:
  133. result.addQuoted(value)
  134. else:
  135. result.addQuoted(value)
  136. result.add(suffix)
  137. proc `$`*[T](x: set[T]): string =
  138. ## Generic ``$`` operator for sets that is lifted from the components
  139. ## of `x`. Example:
  140. ##
  141. ## .. code-block:: Nim
  142. ## ${23, 45} == "{23, 45}"
  143. collectionToString(x, "{", ", ", "}")
  144. proc `$`*[T](x: seq[T]): string =
  145. ## Generic ``$`` operator for seqs that is lifted from the components
  146. ## of `x`. Example:
  147. ##
  148. ## .. code-block:: Nim
  149. ## $(@[23, 45]) == "@[23, 45]"
  150. collectionToString(x, "@[", ", ", "]")
  151. proc `$`*[T, U](x: HSlice[T, U]): string =
  152. ## Generic ``$`` operator for slices that is lifted from the components
  153. ## of `x`. Example:
  154. ##
  155. ## .. code-block:: Nim
  156. ## $(1 .. 5) == "1 .. 5"
  157. result = $x.a
  158. result.add(" .. ")
  159. result.add($x.b)
  160. when not defined(nimNoArrayToString):
  161. proc `$`*[T, IDX](x: array[IDX, T]): string =
  162. ## Generic ``$`` operator for arrays that is lifted from the components.
  163. collectionToString(x, "[", ", ", "]")
  164. proc `$`*[T](x: openArray[T]): string =
  165. ## Generic ``$`` operator for openarrays that is lifted from the components
  166. ## of `x`. Example:
  167. ##
  168. ## .. code-block:: Nim
  169. ## $(@[23, 45].toOpenArray(0, 1)) == "[23, 45]"
  170. collectionToString(x, "[", ", ", "]")