Joe Savona ea1a18ec16 Emit labeled ifs/switch/break; gen each block exactly once
The approach is very similar to what BuildHIR does to resolve break and continue 
targets during IR construction: 

* We annotate goto targets as either a break or a continue (during HIR 
construction). This is necessary to reconstruct the right kind in codegen. 

* Codegen continues to work by traversing the IR as if it were a tree, relying 
on the `fallthrough` branches of if/switch to be able to visit the 
consequent/alternate recursively and then emit the fallthrough branch. 

* We track a Set of blocks that are scheduled to be emitted by some parent in 
the tree. Nested ifs may all have the same fallthrough branch, which we only 
want to emit once. This set helps us to know that a parent is already going to 
emit some block, such that children can skip it. 

* We also keep a stack of break targets that are in scope, and use this to 
convert gotos appropriately, as either a break, continue, or nothing at all (for 
example a switch case that falls through has no explicit syntax to model this 
fall-through, the only option is to emit nothing for the goto). 

* Then, if/switch have to carefully check whether each branch should be emitted 
or not. For example, if the alternate is already scheduled to be emitted (by a 
parent), then we emit a block with a break statement instead. 

* Switch in particular is tricky, because we need to know that subsequent cases 
are scheduled, but only for preceding blocks. So we visit the cases in reverse 
order (not surprisingly, we do the same thing during IR construction for similar 
reasons!). 

The bookkeeping is a bit finicky but this works reliably. There are some cases 
where we could try to emit an unlabeled break instead of a labeled break, or 
avoid emitting a label at all (if nothing will explicitly break to that label), 
but overall the generated code is readable enough that i'm inclined to ship and 
iterate. I'm open to feedback though, as always!
2022-11-08 21:14:10 -08:00
S
Description
No description provided
MIT 1.8 GiB
Languages
JavaScript 67.1%
TypeScript 29.4%
HTML 1.5%
CSS 1.1%
C++ 0.6%
Other 0.2%