Skip to content

Commit

Permalink
fix codegen bug due to changing existing symbol declaration in templa…
Browse files Browse the repository at this point in the history
…te (#14666)
  • Loading branch information
jcosborn authored Jun 15, 2020
1 parent d749c8c commit 5a22d6b
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler/semtempl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
if s != nil and s.owner == c.owner and sfGenSym in s.flags:
onUse(n.info, s)
replaceIdentBySym(c.c, n, newSymNode(s, n.info))
elif not (n.kind == nkSym and sfGenSym in n.sym.flags):
elif n.kind != nkSym:
let local = newGenSym(k, ident, c)
addPrelimDecl(c.c, local)
styleCheckDef(c.c.config, n.info, local)
Expand Down
106 changes: 106 additions & 0 deletions tests/template/template_various.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,28 @@ bar7
4true
132
20
1
-1
4
11
26
57
-1-1-1
4
4
4
11
11
4
11
26
26
4
11
26
57
57
-1-1-1
'''
"""

Expand Down Expand Up @@ -245,3 +267,87 @@ template parse9(body: untyped): untyped =

parse9:
echo val9("1")


block gensym1:
template x: untyped = -1
template t1() =
template x: untyped {.gensym.} = 1
echo x() # 1
template t2() =
template x: untyped = 1 # defaults to {.inject.}
echo x() # -1 injected x not available during template definition
t1()
t2()

block gensym2:
let x,y,z = -1
template `!`(xx,yy: typed): untyped =
template x: untyped {.gensym.} = xx
template y: untyped {.gensym.} = yy
let z = x + x + y
z
var
a = 1
b = 2
c = 3
d = 4
e = 5
echo a ! b
echo a ! b ! c
echo a ! b ! c ! d
echo a ! b ! c ! d ! e
echo x,y,z

block gensym3:
macro liftStmts(body: untyped): auto =
# convert
# template x: untyped {.gensym.} =
# let z = a + a + b
# echo z
# z
# to
# let z = a + a + b
# echo z
# template x: untyped {.gensym.} =
# z
#echo body.repr
body.expectKind nnkStmtList
result = newNimNode nnkStmtList
for s in body:
s.expectKind nnkTemplateDef
var sle = s[6]
while sle.kind == nnkStmtList:
doAssert(sle.len==1)
sle = sle[0]
if sle.kind == nnkStmtListExpr:
let n = sle.len
for i in 0..(n-2):
result.add sle[i]
var td = newNimNode nnkTemplateDef
for i in 0..5:
td.add s[i]
td.add sle[n-1]
result.add td
else:
result.add s
#echo result.repr
let x,y,z = -1
template `!`(xx,yy: typed): untyped =
liftStmts:
template x: untyped {.gensym.} = xx
template y: untyped {.gensym.} = yy
let z = x + x + y
echo " ", z
z
var
a = 1
b = 2
c = 3
d = 4
e = 5
echo a ! b
echo a ! b ! c
echo a ! b ! c ! d
echo a ! b ! c ! d ! e
echo x,y,z

0 comments on commit 5a22d6b

Please sign in to comment.