package compiler import "fmt" // SwitchInfo stores information about a SWITCH statement type SwitchInfo struct { SwitchOperand *OperandInfo // The expression being switched on EndLabel string // Label for end of switch (_ENDSWITCH) NeedsPendingCode bool // True if we need to emit implicit break + skip label PendingSkipLabel string // The skip label that needs to be emitted HasDefault bool // True if DEFAULT has been encountered UseLongJump bool // Whether to use long jumps } // SwitchStack manages the stack of SWITCH contexts type SwitchStack struct { stack []*SwitchInfo } // NewSwitchStack creates a new SwitchStack func NewSwitchStack() *SwitchStack { return &SwitchStack{ stack: make([]*SwitchInfo, 0), } } // Push adds a new SWITCH context to the stack func (ss *SwitchStack) Push(info *SwitchInfo) { ss.stack = append(ss.stack, info) } // Peek returns the top SWITCH context without removing it func (ss *SwitchStack) Peek() (*SwitchInfo, error) { if len(ss.stack) == 0 { return nil, fmt.Errorf("stack underflow: SWITCH stack is empty") } return ss.stack[len(ss.stack)-1], nil } // Pop removes and returns the top SWITCH context func (ss *SwitchStack) Pop() (*SwitchInfo, error) { if len(ss.stack) == 0 { return nil, fmt.Errorf("stack underflow: SWITCH stack is empty") } info := ss.stack[len(ss.stack)-1] ss.stack = ss.stack[:len(ss.stack)-1] return info, nil } // IsEmpty returns true if the stack is empty func (ss *SwitchStack) IsEmpty() bool { return len(ss.stack) == 0 } // Size returns the number of items on the stack func (ss *SwitchStack) Size() int { return len(ss.stack) }