q/src/build/core/CompileSwitch.go

56 lines
1.0 KiB
Go

package core
import (
"fmt"
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/ast"
)
// CompileSwitch compiles a multi-branch instruction.
func (f *Function) CompileSwitch(s *ast.Switch) error {
f.count.multiBranch++
end := fmt.Sprintf("%s_switch_%d_end", f.UniqueName, f.count.multiBranch)
for _, branch := range s.Cases {
if branch.Condition == nil {
f.PushScope(branch.Body, f.File.Bytes)
err := f.CompileAST(branch.Body)
if err != nil {
return err
}
f.PopScope()
break
}
f.count.branch++
var (
success = fmt.Sprintf("%s_case_%d_true", f.UniqueName, f.count.branch)
fail = fmt.Sprintf("%s_case_%d_false", f.UniqueName, f.count.branch)
err = f.CompileCondition(branch.Condition, success, fail)
)
if err != nil {
return err
}
f.AddLabel(success)
f.PushScope(branch.Body, f.File.Bytes)
err = f.CompileAST(branch.Body)
if err != nil {
return err
}
f.Jump(asm.JUMP, end)
f.PopScope()
f.AddLabel(fail)
}
f.AddLabel(end)
return nil
}