Fix a bug for 'for' loop without condition: "for {}" ()

This commit is contained in:
Daniel 2019-02-12 01:28:23 -08:00 committed by GitHub
parent fc4e3586c4
commit cb1c8a405e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 144 additions and 5 deletions

View file

@ -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 {

View file

@ -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