package compiler import ( "c65gm/internal/preproc" ) // CompilerContext holds all shared resources needed by commands during compilation type CompilerContext struct { // Symbol table for variables and constants SymbolTable *SymbolTable // Function handler for FUNC/CALL/FEND commands FunctionHandler *FunctionHandler // Constant string handler ConstStrHandler *ConstantStringHandler // Label stacks for control flow LoopStack *LabelStack // Start of loop (like WHILE) WhileStack *LabelStack // WHILE...WEND IfStack *LabelStack // IF...ENDIF GeneralStack *LabelStack // General purpose (GOSUB, etc) // Pragma access for per-line pragma lookup Pragma *preproc.Pragma } // NewCompilerContext creates a new compiler context with initialized resources func NewCompilerContext(pragma *preproc.Pragma) *CompilerContext { symTable := NewSymbolTable() constStrHandler := NewConstantStringHandler() generalStack := NewLabelStack("_L") ctx := &CompilerContext{ SymbolTable: symTable, ConstStrHandler: constStrHandler, LoopStack: NewLabelStack("_LOOP"), WhileStack: NewLabelStack("_WEND"), IfStack: NewLabelStack("_I"), GeneralStack: generalStack, Pragma: pragma, } // FunctionHandler needs references to other components ctx.FunctionHandler = NewFunctionHandler(symTable, generalStack, constStrHandler, pragma) return ctx } // CurrentScope returns the current function scope(s) for symbol resolution func (ctx *CompilerContext) CurrentScope() []string { funcName := ctx.FunctionHandler.CurrentFunction() if funcName == "" { return nil } return []string{funcName} }