tstringinterp.nim 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. discard """
  2. output: "Hello Alice, 64 | Hello Bob, 10$"
  3. """
  4. import macros, parseutils, strutils
  5. proc concat(strings: varargs[string]): string =
  6. result = newString(0)
  7. for s in items(strings): result.add(s)
  8. template processInterpolations(e) =
  9. var s = e[1].strVal
  10. for f in interpolatedFragments(s):
  11. case f.kind
  12. of ikStr: addString(f.value)
  13. of ikDollar: addDollar()
  14. of ikVar, ikExpr: addExpr(newCall("$", parseExpr(f.value)))
  15. macro formatStyleInterpolation(e: untyped): untyped =
  16. let e = callsite()
  17. var
  18. formatString = ""
  19. arrayNode = newNimNode(nnkBracket)
  20. idx = 1
  21. proc addString(s: string) =
  22. formatString.add(s)
  23. proc addExpr(e: NimNode) =
  24. arrayNode.add(e)
  25. formatString.add("$" & $(idx))
  26. inc idx
  27. proc addDollar() =
  28. formatString.add("$$")
  29. processInterpolations(e)
  30. result = parseExpr("\"x\" % [y]")
  31. result[1].strVal = formatString
  32. result[2] = arrayNode
  33. macro concatStyleInterpolation(e: untyped): untyped =
  34. let e = callsite()
  35. var args: seq[NimNode]
  36. newSeq(args, 0)
  37. proc addString(s: string) = args.add(newStrLitNode(s))
  38. proc addExpr(e: NimNode) = args.add(e)
  39. proc addDollar() = args.add(newStrLitNode"$")
  40. processInterpolations(e)
  41. result = newCall("concat", args)
  42. ###
  43. proc sum(a, b, c: int): int =
  44. return (a + b + c)
  45. var
  46. alice = "Alice"
  47. bob = "Bob"
  48. a = 10
  49. b = 20
  50. c = 34
  51. var
  52. s1 = concatStyleInterpolation"Hello ${alice}, ${sum(a, b, c)}"
  53. s2 = formatStyleInterpolation"Hello ${bob}, ${sum(alice.len, bob.len, 2)}$$"
  54. write(stdout, s1 & " | " & s2)
  55. write(stdout, "\n")