tformatopt.nim 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. discard """
  2. output: '''(a: 3
  3. b: 4
  4. s: abc
  5. )'''
  6. """
  7. import macros
  8. proc invalidFormatString() =
  9. echo "invalidFormatString"
  10. template formatImpl(handleChar: untyped) =
  11. var i = 0
  12. while i < f.len:
  13. if f[i] == '$':
  14. case f[i+1]
  15. of '1'..'9':
  16. var j = 0
  17. i += 1
  18. while f[i] in {'0'..'9'}:
  19. j = j * 10 + ord(f[i]) - ord('0')
  20. i += 1
  21. result.add(a[j-1])
  22. else:
  23. invalidFormatString()
  24. else:
  25. result.add(handleChar(f[i]))
  26. i += 1
  27. proc `%`*(f: string, a: openArray[string]): string =
  28. template identity(x: untyped): untyped = x
  29. result = ""
  30. formatImpl(identity)
  31. macro optFormat{`%`(f, a)}(f: string{lit}, a: openArray[string]): untyped =
  32. result = newNimNode(nnkBracket)
  33. let f = f.strVal
  34. formatImpl(newLit)
  35. result = nestList(newIdentNode("&"), result)
  36. template optAdd1{x = y; add(x, z)}(x, y, z: string) =
  37. x = y & z
  38. proc `/&` [T: object](x: T): string =
  39. result = "("
  40. for name, value in fieldPairs(x):
  41. result.add("$1: $2\n" % [name, $value])
  42. result.add(")")
  43. type
  44. MyObject = object
  45. a, b: int
  46. s: string
  47. let obj = MyObject(a: 3, b: 4, s: "abc")
  48. echo(/&obj)