mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-04 04:02:41 +00:00
bugfixes and improvements for term rewriting macros
This commit is contained in:
@@ -135,7 +135,7 @@ proc checkForSideEffects(n: PNode): TSideEffectAnalysis =
|
||||
# only calls can produce side effects:
|
||||
let op = n.sons[0]
|
||||
if op.kind == nkSym and isRoutine(op.sym):
|
||||
let s = n.sym
|
||||
let s = op.sym
|
||||
if sfSideEffect in s.flags:
|
||||
return seSideEffect
|
||||
# assume no side effect:
|
||||
|
||||
@@ -53,15 +53,15 @@ proc sameTrees(a, b: PNode): bool =
|
||||
result = true
|
||||
|
||||
proc inSymChoice(sc, x: PNode): bool =
|
||||
if sc.kind == nkClosedSymChoice:
|
||||
for i in 0.. <sc.len:
|
||||
if sc.sons[i].sym == x.sym: return true
|
||||
elif sc.kind == nkOpenSymChoice:
|
||||
if sc.kind == nkOpenSymChoice:
|
||||
# same name suffices for open sym choices!
|
||||
result = sc.sons[0].sym.name.id == x.sym.name.id
|
||||
elif sc.kind == nkClosedSymChoice:
|
||||
for i in 0.. <sc.len:
|
||||
if sc.sons[i].sym == x.sym: return true
|
||||
|
||||
proc checkTypes(c: PPatternContext, p: PSym, n: PNode): bool =
|
||||
# check param constraints first here as this quite optimized:
|
||||
# check param constraints first here as this is quite optimized:
|
||||
if p.typ.constraint != nil:
|
||||
result = matchNodeKinds(p.typ.constraint, n)
|
||||
if not result: return
|
||||
@@ -147,11 +147,20 @@ proc matches(c: PPatternContext, p, n: PNode): bool =
|
||||
if isPatternParam(c, v) and v.sym.typ.kind == tyVarargs:
|
||||
for i in countup(0, plen - 2):
|
||||
if not matches(c, p.sons[i], n.sons[i]): return
|
||||
var arglist = newNodeI(nkArgList, n.info, sonsLen(n) - plen + 1)
|
||||
# f(1, 2, 3)
|
||||
# p(X)
|
||||
for i in countup(0, sonsLen(n) - plen):
|
||||
arglist.sons[i] = n.sons[i + plen - 1]
|
||||
|
||||
var arglist: PNode
|
||||
if plen == sonsLen(n) and lastSon(n).kind == nkHiddenStdConv and
|
||||
lastSon(n).sons[1].kind == nkBracket:
|
||||
# unpack varargs:
|
||||
let n = lastSon(n).sons[1]
|
||||
arglist = newNodeI(nkArgList, n.info, n.len)
|
||||
for i in 0.. <n.len: arglist.sons[i] = n.sons[i]
|
||||
else:
|
||||
arglist = newNodeI(nkArgList, n.info, sonsLen(n) - plen + 1)
|
||||
# f(1, 2, 3)
|
||||
# p(X)
|
||||
for i in countup(0, sonsLen(n) - plen):
|
||||
arglist.sons[i] = n.sons[i + plen - 1]
|
||||
# check or bind 'X':
|
||||
return bindOrCheck(c, v.sym, arglist)
|
||||
if plen == sonsLen(n):
|
||||
|
||||
@@ -432,7 +432,9 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
|
||||
elif templToExpand(s):
|
||||
result = semPatternBody(c, semTemplateExpr(c.c, n, s, false))
|
||||
else:
|
||||
result = symChoice(c.c, n, s, scOpen)
|
||||
# we use 'scForceOpen' here so that e.g. "writeln" (which is a
|
||||
# non ambiguous generic) will match its instantiations:
|
||||
result = symChoice(c.c, n, s, scForceOpen)
|
||||
else:
|
||||
result = n
|
||||
|
||||
@@ -504,7 +506,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
|
||||
if s != nil:
|
||||
if Contains(c.toBind, s.id):
|
||||
return symChoice(c.c, n, s, scClosed)
|
||||
return symChoice(c.c, n, s, scOpen)
|
||||
return symChoice(c.c, n, s, scForceOpen)
|
||||
of nkPar:
|
||||
if n.len == 1: return semPatternBody(c, n.sons[0])
|
||||
else: nil
|
||||
|
||||
@@ -15,5 +15,5 @@ template optConc{ `&&` * a }(a: expr): expr = &&a
|
||||
let space = " "
|
||||
echo "my" && (space & "awe" && "some " ) && "concat"
|
||||
|
||||
# check that it's been properly optimized:
|
||||
# check that it's been optimized properly:
|
||||
doAssert calls == 1
|
||||
|
||||
@@ -5,14 +5,14 @@ discard """
|
||||
"""
|
||||
|
||||
template optWrite{
|
||||
write(stdout, x)
|
||||
write(stdout, y)
|
||||
}(x, y: string) =
|
||||
write(stdout, "|", x, y, "|")
|
||||
write(f, x)
|
||||
((write|writeln){w})(f, y)
|
||||
}(x, y: varargs[expr], f, w: expr) =
|
||||
w(f, "|", x, y, "|")
|
||||
|
||||
if true:
|
||||
echo "0"
|
||||
write stdout, "1"
|
||||
write stdout, "2"
|
||||
writeln stdout, "2"
|
||||
write stdout, "3"
|
||||
echo "4"
|
||||
|
||||
Reference in New Issue
Block a user