Moved the parseAST magics to evals.nim
Added string interpolation helper routines in parserutils
Added a proof-of-concept string interpolation user-land macros (currently, only as a test case):
the interpolated expression could either be transformed to
concat("literal string ", $(interpolated), " end") or
"literal string $1 end" % [$(interpolated)]
Added a very initial definition of Optional[T] generic type
A new overload of ParseIdent was added in hope to get around the fact that the
old one doesn't work correctly in macros, but the problem persists.
This commit is contained in:
parent
a28cf4e9cb
commit
dbcca9b3b9
6 changed files with 216 additions and 40 deletions
82
tests/accept/run/tstringinterp.nim
Normal file
82
tests/accept/run/tstringinterp.nim
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
discard """
|
||||
file: "tstringinterp.nim"
|
||||
output: "Hello Alice \$ 64 | Hello Bob, 10"
|
||||
"""
|
||||
|
||||
import macros, parseutils, strutils
|
||||
|
||||
proc concat(strings: openarray[string]) : string =
|
||||
result = newString(0)
|
||||
for s in items(strings): result.add(s)
|
||||
|
||||
# This will run though the intee
|
||||
template ProcessInterpolations(e: expr) =
|
||||
var
|
||||
s = e[1].strVal
|
||||
stringStart = 0
|
||||
|
||||
for i in interpolatedFragments(s):
|
||||
var leadingString = s[stringStart..i.interpStart-1]
|
||||
var interpolatedExpr = s[i.exprStart..i.exprEnd]
|
||||
|
||||
addString(leadingString)
|
||||
|
||||
var interpTargetAst = parseExpr("$(x)")
|
||||
interpTargetAst[1][0] = parseExpr(interpolatedExpr)
|
||||
addExpr(interpTargetAst)
|
||||
|
||||
stringStart = i.interpEnd + 1
|
||||
|
||||
if stringStart != s.len:
|
||||
var endingString = s[stringStart..s.len]
|
||||
addString(endingString)
|
||||
|
||||
macro formatStyleInterpolation(e: expr): expr =
|
||||
var
|
||||
formatString = ""
|
||||
arrayNode = newNimNode(nnkBracket)
|
||||
idx = 1
|
||||
|
||||
proc addString(s: string) =
|
||||
formatString.add(s)
|
||||
|
||||
proc addExpr(e: expr) =
|
||||
arrayNode.add(e)
|
||||
formatString.add("$" & $(idx))
|
||||
inc idx
|
||||
|
||||
ProcessInterpolations(e)
|
||||
|
||||
result = parseExpr("\"x\" % [y]")
|
||||
result[1].strVal = formatString
|
||||
result[2] = arrayNode
|
||||
|
||||
macro concatStyleInterpolation(e: expr): expr =
|
||||
var args : seq[PNimrodNode]
|
||||
newSeq(args, 0)
|
||||
|
||||
proc addString(s: string) = args.add(newStrLitNode(s))
|
||||
proc addExpr(e: expr) = args.add(e)
|
||||
|
||||
ProcessInterpolations(e)
|
||||
|
||||
result = newCall("concat", args)
|
||||
|
||||
###
|
||||
|
||||
proc sum(a, b, c: int): int =
|
||||
return (a + b + c)
|
||||
|
||||
var
|
||||
alice = "Alice"
|
||||
bob = "Bob"
|
||||
a = 10
|
||||
b = 20
|
||||
c = 34
|
||||
|
||||
var
|
||||
s1 = concatStyleInterpolation"Hello ${alice} \$ ${sum (a, b, c)}"
|
||||
s2 = formatStyleInterpolation"Hello ${bob}, ${sum (alice.len, bob.len, 2)}"
|
||||
|
||||
write(stdout, s1 & " | " & s2)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue