c65gm/internal/compiler/forstack.go

66 lines
1.5 KiB
Go

package compiler
import "fmt"
// ForLoopInfo stores information about a FOR loop
type ForLoopInfo struct {
VarName string
VarKind VarKind
EndOperand *OperandInfo
StepOperand *OperandInfo
LoopLabel string
SkipLabel string
}
// OperandInfo describes an operand (variable or literal)
type OperandInfo struct {
VarName string
VarKind VarKind
Value uint16
IsVar bool
}
// ForStack manages the stack of FOR loop contexts
type ForStack struct {
stack []*ForLoopInfo
}
// NewForStack creates a new ForStack
func NewForStack() *ForStack {
return &ForStack{
stack: make([]*ForLoopInfo, 0),
}
}
// Push adds a new FOR loop context to the stack
func (fs *ForStack) Push(info *ForLoopInfo) {
fs.stack = append(fs.stack, info)
}
// Peek returns the top FOR loop context without removing it
func (fs *ForStack) Peek() (*ForLoopInfo, error) {
if len(fs.stack) == 0 {
return nil, fmt.Errorf("stack underflow: FOR stack is empty")
}
return fs.stack[len(fs.stack)-1], nil
}
// Pop removes and returns the top FOR loop context
func (fs *ForStack) Pop() (*ForLoopInfo, error) {
if len(fs.stack) == 0 {
return nil, fmt.Errorf("stack underflow: FOR stack is empty")
}
info := fs.stack[len(fs.stack)-1]
fs.stack = fs.stack[:len(fs.stack)-1]
return info, nil
}
// IsEmpty returns true if the stack is empty
func (fs *ForStack) IsEmpty() bool {
return len(fs.stack) == 0
}
// Size returns the number of items on the stack
func (fs *ForStack) Size() int {
return len(fs.stack)
}