-
Notifications
You must be signed in to change notification settings - Fork 373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: switch branch stmts #3043
base: master
Are you sure you want to change the base?
fix: switch branch stmts #3043
Changes from all commits
c5dcb0a
6034015
500197e
1b71268
348b249
26862b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -298,6 +298,11 @@ func initStaticBlocks(store Store, ctx BlockNode, bn BlockNode) { | |
last.Predefine(false, n.VarName) | ||
} | ||
case *SwitchClauseStmt: | ||
blen := len(n.Body) | ||
if blen > 0 { | ||
n.Body[blen-1].SetAttribute(ATTR_LAST_BLOCK_STMT, true) | ||
} | ||
|
||
// parent switch statement. | ||
ss := ns[len(ns)-1].(*SwitchStmt) | ||
// anything declared in ss are copied, | ||
|
@@ -2125,8 +2130,19 @@ func preprocess1(store Store, ctx BlockNode, n Node) Node { | |
|
||
// TRANS_LEAVE ----------------------- | ||
case *BranchStmt: | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. delete this line for consistency. |
||
notAllowedFunc := func(s string) { | ||
_, isFunc := last.(*FuncLitExpr) | ||
|
||
if isFunc { | ||
panic(fmt.Sprintf("%s statement out of place", s)) | ||
} | ||
} | ||
|
||
switch n.Op { | ||
case BREAK: | ||
notAllowedFunc("break") | ||
|
||
if n.Label == "" { | ||
if !findBreakableNode(ns) { | ||
panic("cannot break with no parent loop or switch") | ||
|
@@ -2139,6 +2155,8 @@ func preprocess1(store Store, ctx BlockNode, n Node) Node { | |
} | ||
} | ||
case CONTINUE: | ||
notAllowedFunc("continue") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this logic be merged into |
||
|
||
if n.Label == "" { | ||
if !findContinuableNode(ns) { | ||
panic("cannot continue with no parent loop") | ||
|
@@ -2154,17 +2172,36 @@ func preprocess1(store Store, ctx BlockNode, n Node) Node { | |
n.Depth = depth | ||
n.BodyIndex = index | ||
case FALLTHROUGH: | ||
if swchC, ok := last.(*SwitchClauseStmt); ok { | ||
// last is a switch clause, find its index in the switch and assign | ||
// it to the fallthrough node BodyIndex. This will be used at | ||
// runtime to determine the next switch clause to run. | ||
swch := lastSwitch(ns) | ||
for i := range swch.Clauses { | ||
if &swch.Clauses[i] == swchC { | ||
// switch clause found | ||
n.BodyIndex = i | ||
break | ||
} | ||
swchC, ok := last.(*SwitchClauseStmt) | ||
if !ok { | ||
// fallthrough is only allowed in a switch statement | ||
panic("fallthrough statement out of place") | ||
} | ||
|
||
if n.GetAttribute(ATTR_LAST_BLOCK_STMT) != true { | ||
// no more clause after the one executed, this is not allowed | ||
panic("fallthrough statement out of place") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any test targeting this? |
||
} | ||
|
||
// last is a switch clause, find its index in the switch and assign | ||
// it to the fallthrough node BodyIndex. This will be used at | ||
// runtime to determine the next switch clause to run. | ||
swch := lastSwitch(ns) | ||
|
||
if swch.IsTypeSwitch { | ||
// fallthrough is not allowed in type switches | ||
panic("cannot fallthrough in type switch") | ||
} | ||
|
||
for i := range swch.Clauses { | ||
if i == len(swch.Clauses)-1 { | ||
panic("cannot fallthrough final case in switch") | ||
} | ||
|
||
if &swch.Clauses[i] == swchC { | ||
// switch clause found | ||
n.BodyIndex = i | ||
break | ||
} | ||
} | ||
default: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package main | ||
|
||
func main() { | ||
for i := 0; i < 10; i++ { | ||
if i == 1 { | ||
_ = func() int { | ||
continue | ||
return 11 | ||
}() | ||
} | ||
println(i) | ||
} | ||
println("wat???") | ||
} | ||
|
||
// Error: | ||
// main/files/for21.gno:7:17: continue statement out of place |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package main | ||
|
||
func main() { | ||
for i := 0; i < 10; i++ { | ||
if i == 1 { | ||
_ = func() int { | ||
fallthrough | ||
return 11 | ||
}() | ||
} | ||
println(i) | ||
} | ||
println("wat???") | ||
} | ||
|
||
// Error: | ||
// main/files/for22.gno:7:17: fallthrough statement out of place |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package main | ||
|
||
func main() { | ||
for i := 0; i < 10; i++ { | ||
if i == 1 { | ||
_ = func() int { | ||
break | ||
return 11 | ||
}() | ||
} | ||
println(i) | ||
} | ||
println("wat???") | ||
} | ||
|
||
// Error: | ||
// main/files/for23.gno:7:17: break statement out of place |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a better name?