activated tests for tr macros
This commit is contained in:
parent
30c00aba07
commit
355ae07b8f
7 changed files with 62 additions and 24 deletions
|
|
@ -101,7 +101,7 @@ proc compileConstraints(p: PNode, result: var TPatternCode) =
|
||||||
InternalAssert int(high(TNodeKind)) < 255
|
InternalAssert int(high(TNodeKind)) < 255
|
||||||
for i in low(TNodeKind)..high(TNodeKind):
|
for i in low(TNodeKind)..high(TNodeKind):
|
||||||
if cmpIgnoreStyle($i, spec) == 0:
|
if cmpIgnoreStyle($i, spec) == 0:
|
||||||
result.add(ppSymKind)
|
result.add(ppNodeKind)
|
||||||
result.add(chr(i.ord))
|
result.add(chr(i.ord))
|
||||||
return
|
return
|
||||||
patternError(p)
|
patternError(p)
|
||||||
|
|
@ -199,7 +199,8 @@ proc matchNodeKinds*(p, n: PNode): bool =
|
||||||
let kind = TNodeKind(code[pc+1])
|
let kind = TNodeKind(code[pc+1])
|
||||||
push n.kind == kind
|
push n.kind == kind
|
||||||
inc pc
|
inc pc
|
||||||
of ppSideEffect: push checkForSideEffects(n) != seNoSideEffect
|
of ppSideEffect: push checkForSideEffects(n) == seSideEffect
|
||||||
of ppNoSideEffect: push checkForSideEffects(n) == seNoSideEffect
|
of ppNoSideEffect: push checkForSideEffects(n) != seSideEffect
|
||||||
inc pc
|
inc pc
|
||||||
result = stack[sp-1]
|
result = stack[sp-1]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,12 @@ proc sameTrees(a, b: PNode): bool =
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc inSymChoice(sc, x: PNode): bool =
|
proc inSymChoice(sc, x: PNode): bool =
|
||||||
if sc.kind == nkOpenSymChoice:
|
if sc.kind == nkClosedSymChoice:
|
||||||
# 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:
|
for i in 0.. <sc.len:
|
||||||
if sc.sons[i].sym == x.sym: return true
|
if sc.sons[i].sym == x.sym: return true
|
||||||
|
elif sc.kind == nkOpenSymChoice:
|
||||||
|
# same name suffices for open sym choices!
|
||||||
|
result = sc.sons[0].sym.name.id == x.sym.name.id
|
||||||
|
|
||||||
proc checkTypes(c: PPatternContext, p: PSym, n: PNode): bool =
|
proc checkTypes(c: PPatternContext, p: PSym, n: PNode): bool =
|
||||||
# check param constraints first here as this is quite optimized:
|
# check param constraints first here as this is quite optimized:
|
||||||
|
|
@ -86,7 +86,7 @@ proc bindOrCheck(c: PPatternContext, param: PSym, n: PNode): bool =
|
||||||
IdNodeTablePutLazy(c.mapping, param, n)
|
IdNodeTablePutLazy(c.mapping, param, n)
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc matchStar(c: PPatternContext, p, n: PNode): bool =
|
proc matchNested(c: PPatternContext, p, n: PNode): bool =
|
||||||
# match ``op*param``
|
# match ``op*param``
|
||||||
|
|
||||||
proc matchStarAux(c: PPatternContext, op, n, arglist: PNode) =
|
proc matchStarAux(c: PPatternContext, op, n, arglist: PNode) =
|
||||||
|
|
@ -109,6 +109,8 @@ proc matches(c: PPatternContext, p, n: PNode): bool =
|
||||||
# hidden conversions (?)
|
# hidden conversions (?)
|
||||||
if isPatternParam(c, p):
|
if isPatternParam(c, p):
|
||||||
result = bindOrCheck(c, p.sym, n)
|
result = bindOrCheck(c, p.sym, n)
|
||||||
|
elif n.kind == nkSym and p.kind == nkIdent:
|
||||||
|
result = p.ident.id == n.sym.name.id
|
||||||
elif n.kind == nkSym and inSymChoice(p, n):
|
elif n.kind == nkSym and inSymChoice(p, n):
|
||||||
result = true
|
result = true
|
||||||
elif n.kind == nkSym and n.sym.kind == skConst:
|
elif n.kind == nkSym and n.sym.kind == skConst:
|
||||||
|
|
@ -120,7 +122,7 @@ proc matches(c: PPatternContext, p, n: PNode): bool =
|
||||||
let opr = p.sons[0].ident.s
|
let opr = p.sons[0].ident.s
|
||||||
case opr
|
case opr
|
||||||
of "|": result = matchChoice(c, p, n)
|
of "|": result = matchChoice(c, p, n)
|
||||||
of "*": result = matchStar(c, p, n)
|
of "*": result = matchNested(c, p, n)
|
||||||
of "~": result = not matches(c, p.sons[1], n)
|
of "~": result = not matches(c, p.sons[1], n)
|
||||||
else: InternalError(p.info, "invalid pattern")
|
else: InternalError(p.info, "invalid pattern")
|
||||||
# template {add(a, `&` * b)}(a: string{noalias}, b: varargs[string]) =
|
# template {add(a, `&` * b)}(a: string{noalias}, b: varargs[string]) =
|
||||||
|
|
@ -142,13 +144,12 @@ proc matches(c: PPatternContext, p, n: PNode): bool =
|
||||||
var plen = sonsLen(p)
|
var plen = sonsLen(p)
|
||||||
# special rule for p(X) ~ f(...); this also works for stuff like
|
# special rule for p(X) ~ f(...); this also works for stuff like
|
||||||
# partial case statements, etc! - Not really ... :-/
|
# partial case statements, etc! - Not really ... :-/
|
||||||
if plen <= sonsLen(n):
|
let v = lastSon(p)
|
||||||
let v = lastSon(p)
|
if isPatternParam(c, v) and v.sym.typ.kind == tyVarargs:
|
||||||
if isPatternParam(c, v) and v.sym.typ.kind == tyVarargs:
|
var arglist: PNode
|
||||||
|
if plen <= sonsLen(n):
|
||||||
for i in countup(0, plen - 2):
|
for i in countup(0, plen - 2):
|
||||||
if not matches(c, p.sons[i], n.sons[i]): return
|
if not matches(c, p.sons[i], n.sons[i]): return
|
||||||
|
|
||||||
var arglist: PNode
|
|
||||||
if plen == sonsLen(n) and lastSon(n).kind == nkHiddenStdConv and
|
if plen == sonsLen(n) and lastSon(n).kind == nkHiddenStdConv and
|
||||||
lastSon(n).sons[1].kind == nkBracket:
|
lastSon(n).sons[1].kind == nkBracket:
|
||||||
# unpack varargs:
|
# unpack varargs:
|
||||||
|
|
@ -161,7 +162,11 @@ proc matches(c: PPatternContext, p, n: PNode): bool =
|
||||||
# p(X)
|
# p(X)
|
||||||
for i in countup(0, sonsLen(n) - plen):
|
for i in countup(0, sonsLen(n) - plen):
|
||||||
arglist.sons[i] = n.sons[i + plen - 1]
|
arglist.sons[i] = n.sons[i + plen - 1]
|
||||||
# check or bind 'X':
|
return bindOrCheck(c, v.sym, arglist)
|
||||||
|
elif plen-1 == sonsLen(n):
|
||||||
|
for i in countup(0, plen - 2):
|
||||||
|
if not matches(c, p.sons[i], n.sons[i]): return
|
||||||
|
arglist = newNodeI(nkArgList, n.info)
|
||||||
return bindOrCheck(c, v.sym, arglist)
|
return bindOrCheck(c, v.sym, arglist)
|
||||||
if plen == sonsLen(n):
|
if plen == sonsLen(n):
|
||||||
for i in countup(0, sonsLen(p) - 1):
|
for i in countup(0, sonsLen(p) - 1):
|
||||||
|
|
|
||||||
|
|
@ -423,6 +423,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
s.kind == skTemplate and (s.typ.len == 1 or sfImmediate in s.flags)
|
s.kind == skTemplate and (s.typ.len == 1 or sfImmediate in s.flags)
|
||||||
|
|
||||||
proc handleSym(c: var TemplCtx, n: PNode, s: PSym): PNode =
|
proc handleSym(c: var TemplCtx, n: PNode, s: PSym): PNode =
|
||||||
|
result = n
|
||||||
if s != nil:
|
if s != nil:
|
||||||
if s.owner == c.owner and s.kind == skParam:
|
if s.owner == c.owner and s.kind == skParam:
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
|
|
@ -432,11 +433,9 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
elif templToExpand(s):
|
elif templToExpand(s):
|
||||||
result = semPatternBody(c, semTemplateExpr(c.c, n, s, false))
|
result = semPatternBody(c, semTemplateExpr(c.c, n, s, false))
|
||||||
else:
|
else:
|
||||||
# we use 'scForceOpen' here so that e.g. "writeln" (which is a
|
nil
|
||||||
# non ambiguous generic) will match its instantiations:
|
# we keep the ident unbound for matching instantiated symbols and
|
||||||
result = symChoice(c.c, n, s, scForceOpen)
|
# more flexibility
|
||||||
else:
|
|
||||||
result = n
|
|
||||||
|
|
||||||
proc expectParam(c: var TemplCtx, n: PNode): PNode =
|
proc expectParam(c: var TemplCtx, n: PNode): PNode =
|
||||||
let s = QualifiedLookUp(c.c, n, {})
|
let s = QualifiedLookUp(c.c, n, {})
|
||||||
|
|
@ -506,7 +505,8 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
if s != nil:
|
if s != nil:
|
||||||
if Contains(c.toBind, s.id):
|
if Contains(c.toBind, s.id):
|
||||||
return symChoice(c.c, n, s, scClosed)
|
return symChoice(c.c, n, s, scClosed)
|
||||||
return symChoice(c.c, n, s, scForceOpen)
|
else:
|
||||||
|
return newIdentNode(s.name, n.info)
|
||||||
of nkPar:
|
of nkPar:
|
||||||
if n.len == 1: return semPatternBody(c, n.sons[0])
|
if n.len == 1: return semPatternBody(c, n.sons[0])
|
||||||
else: nil
|
else: nil
|
||||||
|
|
|
||||||
13
tests/patterns/tcse.nim
Normal file
13
tests/patterns/tcse.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
discard """
|
||||||
|
output: "4"
|
||||||
|
"""
|
||||||
|
|
||||||
|
template cse{f(a, a, x)}(a: expr{(nkDotExpr|call|nkBracketExpr)&noSideEffect},
|
||||||
|
f: expr, x: varargs[expr]): expr =
|
||||||
|
let aa = a
|
||||||
|
f(aa, aa, x)+4
|
||||||
|
|
||||||
|
var
|
||||||
|
a: array[0..10, int]
|
||||||
|
i = 3
|
||||||
|
echo a[i] + a[i]
|
||||||
16
tests/patterns/tnoalias.nim
Normal file
16
tests/patterns/tnoalias.nim
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
discard """
|
||||||
|
output: "23"
|
||||||
|
"""
|
||||||
|
|
||||||
|
template optslice{a = b + c}(a: expr{noalias}, b, c: expr): stmt =
|
||||||
|
a = b
|
||||||
|
inc a, c
|
||||||
|
|
||||||
|
var
|
||||||
|
x = 12
|
||||||
|
y = 10
|
||||||
|
z = 13
|
||||||
|
|
||||||
|
x = y+z
|
||||||
|
|
||||||
|
echo x
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''0
|
output: '''0
|
||||||
|12|34
|
|12|
|
||||||
|
34
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,6 @@ proc runGcTests(r: var TResults, options: string) =
|
||||||
test "gcleak"
|
test "gcleak"
|
||||||
test "gcleak2"
|
test "gcleak2"
|
||||||
test "gctest"
|
test "gctest"
|
||||||
# disabled for now as it somehow runs very slowly ('delete' bug?) but works:
|
|
||||||
test "gcleak3"
|
test "gcleak3"
|
||||||
test "weakrefs"
|
test "weakrefs"
|
||||||
|
|
||||||
|
|
@ -188,6 +187,9 @@ proc runSpecialTests(r: var TResults, options: string) =
|
||||||
runThreadTests(r, options & " --threads:on")
|
runThreadTests(r, options & " --threads:on")
|
||||||
runIOTests(r, options)
|
runIOTests(r, options)
|
||||||
|
|
||||||
|
for t in os.walkFiles("tests/patterns/t*.nim"):
|
||||||
|
runSingleTest(r, t, options)
|
||||||
|
|
||||||
proc rejectSpecialTests(r: var TResults, options: string) =
|
proc rejectSpecialTests(r: var TResults, options: string) =
|
||||||
rejectThreadTests(r, options)
|
rejectThreadTests(r, options)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue