66 lines
1.5 KiB
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)
|
|
}
|