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:
Zahary Karadjov 2011-09-07 22:05:21 +03:00
commit dbcca9b3b9
6 changed files with 216 additions and 40 deletions

View 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)