package commands import ( "fmt" "strings" "c65gm/internal/compiler" "c65gm/internal/preproc" "c65gm/internal/utils" ) // DefaultCommand handles DEFAULT statements within SWITCH // Syntax: DEFAULT type DefaultCommand struct { } func (c *DefaultCommand) WillHandle(line preproc.Line) bool { params, err := utils.ParseParams(line.Text) if err != nil || len(params) == 0 { return false } return strings.ToUpper(params[0]) == "DEFAULT" } func (c *DefaultCommand) Interpret(line preproc.Line, ctx *compiler.CompilerContext) error { params, err := utils.ParseParams(line.Text) if err != nil { return err } if len(params) != 1 { return fmt.Errorf("DEFAULT: expected 1 parameter (DEFAULT), got %d", len(params)) } // Check if we're inside a SWITCH if ctx.SwitchStack.IsEmpty() { return fmt.Errorf("DEFAULT: not inside a SWITCH statement") } switchInfo, err := ctx.SwitchStack.Peek() if err != nil { return fmt.Errorf("DEFAULT: %w", err) } // Check if DEFAULT has already been seen if switchInfo.HasDefault { return fmt.Errorf("DEFAULT: multiple DEFAULT statements in same SWITCH") } return nil } func (c *DefaultCommand) Generate(ctx *compiler.CompilerContext) ([]string, error) { switchInfo, err := ctx.SwitchStack.Peek() if err != nil { return nil, fmt.Errorf("DEFAULT: %w", err) } var asm []string // If there was a previous CASE, emit implicit break and skip label if switchInfo.NeedsPendingCode { // Implicit break: jump to end of switch asm = append(asm, fmt.Sprintf("\tjmp %s", switchInfo.EndLabel)) // Emit the pending skip label (where previous case jumps if not matched) asm = append(asm, switchInfo.PendingSkipLabel) } // Mark that we've seen DEFAULT switchInfo.HasDefault = true // DEFAULT doesn't need a skip label, so clear pending code switchInfo.NeedsPendingCode = false switchInfo.PendingSkipLabel = "" return asm, nil }