node: implement switch, break, continue (basic)
This commit is contained in:
parent
cbcfb46de7
commit
78bd54ad13
16
fixtures/0014-switch.php
Normal file
16
fixtures/0014-switch.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
$x = true;
|
||||
switch($x) {
|
||||
case true:
|
||||
echo "true";
|
||||
break;
|
||||
echo "unreached";
|
||||
|
||||
case false:
|
||||
echo "false";
|
||||
// fallthrough
|
||||
|
||||
default:
|
||||
echo "default";
|
||||
}
|
63
node.go
63
node.go
@ -845,6 +845,69 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error)
|
||||
|
||||
return ret, nil
|
||||
|
||||
case *stmt.Switch:
|
||||
cond, err := this.convert(n.Cond)
|
||||
if err != nil {
|
||||
return "", parseErr{n, err}
|
||||
}
|
||||
|
||||
cases := make([]string, 0, len(n.CaseList.Cases))
|
||||
for _, ncase := range n.CaseList.Cases {
|
||||
switch ncase.(type) {
|
||||
case *stmt.Default, *stmt.Case:
|
||||
caseStr, err := this.convert(ncase)
|
||||
if err != nil {
|
||||
return "", parseErr{n, err}
|
||||
}
|
||||
cases = append(cases, caseStr)
|
||||
|
||||
default:
|
||||
return "", parseErr{ncase, fmt.Errorf("expected Case/Default")}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO use dead code elimination after `break` to clean up redundant fallthrough statements
|
||||
return "switch " + cond + " {\n" + strings.Join(cases, "\n") + "}\n", nil
|
||||
|
||||
case *stmt.Case:
|
||||
// Add a `fallthrough` to the end
|
||||
// TODO then use dead code elimination to clean them up
|
||||
stmtBody, err := this.convert(stmt.NewStmtList(n.Stmts))
|
||||
if err != nil {
|
||||
return "", parseErr{n, err}
|
||||
}
|
||||
|
||||
cond, err := this.convert(n.Cond)
|
||||
if err != nil {
|
||||
return "", parseErr{n, err}
|
||||
}
|
||||
|
||||
return "case " + cond + ":\n" + stmtBody + "\nfallthrough\n", nil
|
||||
|
||||
case *stmt.Default:
|
||||
// Add a `fallthrough` to the end
|
||||
// TODO then use dead code elimination to clean them up
|
||||
stmtBody, err := this.convert(stmt.NewStmtList(n.Stmts))
|
||||
if err != nil {
|
||||
return "", parseErr{n, err}
|
||||
}
|
||||
|
||||
return "default: " + stmtBody + "\nfallthrough\n", nil
|
||||
|
||||
case *stmt.Break:
|
||||
if n.Expr != nil {
|
||||
return "", parseErr{n, fmt.Errorf("break {expr} is not yet supported")} // TODO implement numbered break
|
||||
}
|
||||
|
||||
return "break\n", nil
|
||||
|
||||
case *stmt.Continue:
|
||||
if n.Expr != nil {
|
||||
return "", parseErr{n, fmt.Errorf("continue {expr} is not yet supported")} // TODO implement numbered continue
|
||||
}
|
||||
|
||||
return "continue\n", nil
|
||||
|
||||
case *stmt.Try:
|
||||
|
||||
// Generate an if err != nil {} block that we can bring up whenever
|
||||
|
Loading…
Reference in New Issue
Block a user