Skip to content

Commit

Permalink
Fix a bug for 'for' loop without condition: "for {}" (#100)
Browse files Browse the repository at this point in the history
  • Loading branch information
d5 authored Feb 12, 2019
1 parent fc4e358 commit cb1c8a4
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 5 deletions.
15 changes: 10 additions & 5 deletions compiler/compiler_for.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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 {
Expand Down
134 changes: 134 additions & 0 deletions runtime/vm_for_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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++
Expand All @@ -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 {
Expand All @@ -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
Expand Down

0 comments on commit cb1c8a4

Please sign in to comment.