Fix a bug for 'for' loop without condition: "for {}" (#100)
This commit is contained in:
parent
fc4e3586c4
commit
cb1c8a405e
2 changed files with 144 additions and 5 deletions
|
@ -21,11 +21,14 @@ func (c *Compiler) compileForStmt(stmt *ast.ForStmt) error {
|
|||
preCondPos := len(c.currentInstructions())
|
||||
|
||||
// condition expression
|
||||
if err := c.Compile(stmt.Cond); err != nil {
|
||||
return err
|
||||
postCondPos := -1
|
||||
if stmt.Cond != nil {
|
||||
if err := c.Compile(stmt.Cond); err != nil {
|
||||
return err
|
||||
}
|
||||
// condition jump position
|
||||
postCondPos = c.emit(OpJumpFalsy, 0)
|
||||
}
|
||||
// condition jump position
|
||||
postCondPos := c.emit(OpJumpFalsy, 0)
|
||||
|
||||
// enter loop
|
||||
loop := c.enterLoop()
|
||||
|
@ -53,7 +56,9 @@ func (c *Compiler) compileForStmt(stmt *ast.ForStmt) error {
|
|||
|
||||
// post-statement position
|
||||
postStmtPos := len(c.currentInstructions())
|
||||
c.changeOperand(postCondPos, postStmtPos)
|
||||
if postCondPos >= 0 {
|
||||
c.changeOperand(postCondPos, postStmtPos)
|
||||
}
|
||||
|
||||
// update all break/continue jump positions
|
||||
for _, pos := range loop.Breaks {
|
||||
|
|
|
@ -5,6 +5,40 @@ import (
|
|||
)
|
||||
|
||||
func TestFor(t *testing.T) {
|
||||
expect(t, `
|
||||
for {
|
||||
out++
|
||||
if out == 5 {
|
||||
break
|
||||
}
|
||||
}`, 5)
|
||||
|
||||
expect(t, `
|
||||
for {
|
||||
out++
|
||||
if out == 5 {
|
||||
break
|
||||
}
|
||||
}`, 5)
|
||||
|
||||
expect(t, `
|
||||
a := 0
|
||||
for {
|
||||
a++
|
||||
if a == 3 { continue }
|
||||
if a == 5 { break }
|
||||
out += a
|
||||
}`, 7) // 1 + 2 + 4
|
||||
|
||||
expect(t, `
|
||||
a := 0
|
||||
for {
|
||||
a++
|
||||
if a == 3 { continue }
|
||||
out += a
|
||||
if a == 5 { break }
|
||||
}`, 12) // 1 + 2 + 4 + 5
|
||||
|
||||
expect(t, `
|
||||
for true {
|
||||
out++
|
||||
|
@ -13,6 +47,34 @@ func TestFor(t *testing.T) {
|
|||
}
|
||||
}`, 5)
|
||||
|
||||
expect(t, `
|
||||
a := 0
|
||||
for true {
|
||||
a++
|
||||
if a == 5 {
|
||||
break
|
||||
}
|
||||
}
|
||||
out = a`, 5)
|
||||
|
||||
expect(t, `
|
||||
a := 0
|
||||
for true {
|
||||
a++
|
||||
if a == 3 { continue }
|
||||
if a == 5 { break }
|
||||
out += a
|
||||
}`, 7) // 1 + 2 + 4
|
||||
|
||||
expect(t, `
|
||||
a := 0
|
||||
for true {
|
||||
a++
|
||||
if a == 3 { continue }
|
||||
out += a
|
||||
if a == 5 { break }
|
||||
}`, 12) // 1 + 2 + 4 + 5
|
||||
|
||||
expect(t, `
|
||||
func() {
|
||||
for true {
|
||||
|
@ -35,6 +97,78 @@ func TestFor(t *testing.T) {
|
|||
}
|
||||
}`, 54)
|
||||
|
||||
expect(t, `
|
||||
func() {
|
||||
for {
|
||||
out++
|
||||
if out == 5 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()`, 5)
|
||||
|
||||
expect(t, `
|
||||
func() {
|
||||
for true {
|
||||
out++
|
||||
if out == 5 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()`, 5)
|
||||
|
||||
expect(t, `
|
||||
out = func() {
|
||||
a := 0
|
||||
for {
|
||||
a++
|
||||
if a == 5 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return a
|
||||
}()`, 5)
|
||||
|
||||
expect(t, `
|
||||
out = func() {
|
||||
a := 0
|
||||
for true {
|
||||
a++
|
||||
if a== 5 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return a
|
||||
}()`, 5)
|
||||
|
||||
expect(t, `
|
||||
out = func() {
|
||||
a := 0
|
||||
func() {
|
||||
for {
|
||||
a++
|
||||
if a == 5 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
return a
|
||||
}()`, 5)
|
||||
|
||||
expect(t, `
|
||||
out = func() {
|
||||
a := 0
|
||||
func() {
|
||||
for true {
|
||||
a++
|
||||
if a == 5 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
return a
|
||||
}()`, 5)
|
||||
|
||||
expect(t, `
|
||||
out = func() {
|
||||
sum := 0
|
||||
|
|
Loading…
Reference in a new issue