c65gm/internal/compiler/switchstack.go

58 lines
1.7 KiB
Go

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)
}