stmt/for: hoist multiple initial conditions from 3-clause for loops
This commit is contained in:
parent
7dbb523763
commit
90ce6af6dd
@ -19,3 +19,7 @@ for($i = 0; $i < 3; ++$i) {
|
|||||||
|
|
||||||
// Loop with no separate body statement
|
// Loop with no separate body statement
|
||||||
while (true) echo "hello";
|
while (true) echo "hello";
|
||||||
|
|
||||||
|
// Loop with multiple initialiser conditions
|
||||||
|
for ($i = 0, $e = 3; $i < $e; ++$i) {
|
||||||
|
}
|
||||||
|
28
node.go
28
node.go
@ -233,16 +233,32 @@ func convert(n_ node.Node) (string, error) {
|
|||||||
return "return nil, " + child + "\n", nil
|
return "return nil, " + child + "\n", nil
|
||||||
|
|
||||||
case *stmt.For:
|
case *stmt.For:
|
||||||
if len(n.Init) != 1 {
|
|
||||||
|
var preinit, finit string
|
||||||
|
var err error = nil
|
||||||
|
|
||||||
|
if len(n.Init) == 0 {
|
||||||
|
// No initialiser in loop
|
||||||
|
|
||||||
|
} else if len(n.Init) == 1 {
|
||||||
|
finit, err = convert(n.Init[0])
|
||||||
|
if err != nil {
|
||||||
|
return "", parseErr{n, err}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
// We can handle the case of multiple init statements by hoisting them
|
// We can handle the case of multiple init statements by hoisting them
|
||||||
// above the loop. There is no negative impact on PHP scoping rules, but
|
// above the loop. There is no negative impact on PHP scoping rules, but
|
||||||
// it may cause an extra local variable after the loop that may result
|
// it may cause an extra local variable after the loop that may result
|
||||||
// in type mismatch (can be fixed by using an extra scope).
|
// in type mismatch (can be fixed by using an extra scope).
|
||||||
return "", parseErr{n, fmt.Errorf("for loop can only have 1 init clause, found %d", len(n.Init))}
|
for _, initStmt := range n.Init {
|
||||||
}
|
singleInitStmt, err := convert(initStmt)
|
||||||
finit, err := convert(n.Init[0])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", parseErr{n, err}
|
return "", parseErr{initStmt, err}
|
||||||
|
}
|
||||||
|
|
||||||
|
preinit += singleInitStmt + "\n"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(n.Cond) != 1 {
|
if len(n.Cond) != 1 {
|
||||||
@ -275,7 +291,7 @@ func convert(n_ node.Node) (string, error) {
|
|||||||
return "", parseErr{n, err}
|
return "", parseErr{n, err}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "for " + finit + "; " + fcond + "; " + floop + " " + body + "\n", nil
|
return preinit + "for " + finit + "; " + fcond + "; " + floop + " " + body + "\n", nil
|
||||||
|
|
||||||
case *stmt.Foreach:
|
case *stmt.Foreach:
|
||||||
iterand, err := convert(n.Expr)
|
iterand, err := convert(n.Expr)
|
||||||
|
Loading…
Reference in New Issue
Block a user