package commands import ( "fmt" "strings" "c65gm/internal/compiler" "c65gm/internal/preproc" "c65gm/internal/utils" ) // SwitchCommand handles SWITCH statements // Syntax: SWITCH type SwitchCommand struct { } func (c *SwitchCommand) WillHandle(line preproc.Line) bool { params, err := utils.ParseParams(line.Text) if err != nil || len(params) == 0 { return false } return strings.ToUpper(params[0]) == "SWITCH" } func (c *SwitchCommand) Interpret(line preproc.Line, ctx *compiler.CompilerContext) error { params, err := utils.ParseParams(line.Text) if err != nil { return err } if len(params) != 2 { return fmt.Errorf("SWITCH: expected 2 parameters (SWITCH ), got %d", len(params)) } scope := ctx.CurrentScope() constLookup := func(name string) (int64, bool) { sym := ctx.SymbolTable.Lookup(name, scope) if sym != nil && sym.IsConst() { return int64(sym.Value), true } return 0, false } // Parse the switch variable/expression varName, varKind, value, isVar, err := compiler.ParseOperandParam( params[1], ctx.SymbolTable, scope, constLookup) if err != nil { return fmt.Errorf("SWITCH: %w", err) } // Check pragma for long jumps ps := ctx.Pragma.GetPragmaSetByIndex(line.PragmaSetIndex) longJumpPragma := ps.GetPragma("_P_USE_LONG_JUMP") useLongJump := longJumpPragma != "" && longJumpPragma != "0" // Create end label endLabel := ctx.GeneralStack.Push() // Create and push switch info switchInfo := &compiler.SwitchInfo{ SwitchOperand: &compiler.OperandInfo{ VarName: varName, VarKind: varKind, Value: value, IsVar: isVar, }, EndLabel: endLabel, NeedsPendingCode: false, PendingSkipLabel: "", HasDefault: false, UseLongJump: useLongJump, } ctx.SwitchStack.Push(switchInfo) return nil } func (c *SwitchCommand) Generate(ctx *compiler.CompilerContext) ([]string, error) { // SWITCH itself generates no assembly code // The variable will be loaded and compared by each CASE return []string{}, nil }