parent
1ee4acbdbc
commit
40bacc6775
2 changed files with 40 additions and 0 deletions
|
@ -499,6 +499,9 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
return nil
|
||||
|
||||
case *ast.IfStmt:
|
||||
c.scope.vars.newScope()
|
||||
defer c.scope.vars.dropScope()
|
||||
|
||||
lIf := c.newLabel()
|
||||
lElse := c.newLabel()
|
||||
lElseEnd := c.newLabel()
|
||||
|
@ -553,6 +556,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
}
|
||||
}
|
||||
|
||||
c.scope.vars.newScope()
|
||||
|
||||
c.setLabel(lStart)
|
||||
last := len(cc.Body) - 1
|
||||
for j, stmt := range cc.Body {
|
||||
|
@ -564,6 +569,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
}
|
||||
emit.Jmp(c.prog.BinWriter, opcode.JMPL, switchEnd)
|
||||
c.setLabel(lEnd)
|
||||
|
||||
c.scope.vars.dropScope()
|
||||
}
|
||||
|
||||
c.setLabel(switchEnd)
|
||||
|
@ -884,6 +891,9 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
return nil
|
||||
|
||||
case *ast.ForStmt:
|
||||
c.scope.vars.newScope()
|
||||
defer c.scope.vars.dropScope()
|
||||
|
||||
fstart, label := c.generateLabel(labelStart)
|
||||
fend := c.newNamedLabel(labelEnd, label)
|
||||
fpost := c.newNamedLabel(labelPost, label)
|
||||
|
@ -926,6 +936,9 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
return nil
|
||||
|
||||
case *ast.RangeStmt:
|
||||
c.scope.vars.newScope()
|
||||
defer c.scope.vars.dropScope()
|
||||
|
||||
start, label := c.generateLabel(labelStart)
|
||||
end := c.newNamedLabel(labelEnd, label)
|
||||
post := c.newNamedLabel(labelPost, label)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package compiler_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
@ -55,3 +56,29 @@ func TestMultiDeclarationLocalCompound(t *testing.T) {
|
|||
}`
|
||||
eval(t, src, big.NewInt(6))
|
||||
}
|
||||
|
||||
func TestShadow(t *testing.T) {
|
||||
srcTmpl := `package foo
|
||||
func Main() int {
|
||||
x := 1
|
||||
y := 10
|
||||
%s
|
||||
x += 1 // increase old local
|
||||
x := 30 // introduce new local
|
||||
y += x // make sure is means something
|
||||
}
|
||||
return x+y
|
||||
}`
|
||||
|
||||
runCase := func(b string) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
src := fmt.Sprintf(srcTmpl, b)
|
||||
eval(t, src, big.NewInt(42))
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("If", runCase("if true {"))
|
||||
t.Run("For", runCase("for i := 0; i < 1; i++ {"))
|
||||
t.Run("Range", runCase("for range []int{1} {"))
|
||||
t.Run("Switch", runCase("switch true {\ncase false: x += 2\ncase true:"))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue