Skip to content

Commit

Permalink
Pop the deco stack when handling `next'.
Browse files Browse the repository at this point in the history
This lets us recurse correctly or we keep walking the same block when a nested
deco is created.
  • Loading branch information
jaqx0r committed Jan 16, 2020
1 parent 5898858 commit 6a1c0a0
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
9 changes: 7 additions & 2 deletions internal/vm/codegen/codegen.go
Expand Up @@ -280,19 +280,24 @@ func (c *codegen) VisitBefore(node ast.Node) (ast.Visitor, ast.Node) {

case *ast.DecoStmt:
// Put the current block on the stack
decoLen := len(c.decos)
c.decos = append(c.decos, n)
if n.Decl == nil {
c.errorf(n.Pos(), "No definition found for decorator %q", n.Name)
return nil, n
}
// then iterate over the decorator's nodes
ast.Walk(c, n.Decl.Block)
c.decos = c.decos[:len(c.decos)-1]
if len(c.decos) > decoLen {
glog.V(1).Info("Too many blocks on stack, was there no `next' in the last one?")
}
return nil, n

case *ast.NextStmt:
// Visit the 'next' block on the decorated block stack
deco := c.decos[len(c.decos)-1]
top := len(c.decos) - 1
deco := c.decos[top]
c.decos = c.decos[:top]
ast.Walk(c, deco.Block)
return nil, n

Expand Down
12 changes: 12 additions & 0 deletions internal/vm/codegen/codegen_test.go
Expand Up @@ -850,6 +850,18 @@ stop
{code.Stop, nil, 2},
{code.Setmatched, true, 1},
}},

{"nested decorators",
`def b {
def b {
next
}
@b {
next
}
}
@b {
}`, nil},
}

func TestCodegen(t *testing.T) {
Expand Down

0 comments on commit 6a1c0a0

Please sign in to comment.