package commands import ( "strings" "c65gm/internal/compiler" "c65gm/internal/preproc" "c65gm/internal/utils" ) // CallCommand handles function calls // Syntax: // // CALL funcname # void call // CALL funcname ( arg1 arg2 ) # call with arguments // funcname # implicit call syntax // funcname ( arg1 arg2 ) # implicit call with args // // Arguments can be: // - Variables: varname // - Constants: 123, $FF // - Labels: @labelname // - Strings: "text" type CallCommand struct { funcHandler *compiler.FunctionHandler asmOutput []string } // NewCallCommand creates a CallCommand with access to function registry func NewCallCommand(funcHandler *compiler.FunctionHandler) *CallCommand { return &CallCommand{ funcHandler: funcHandler, } } func (c *CallCommand) WillHandle(line preproc.Line) bool { params, err := utils.ParseParams(line.Text) if err != nil || len(params) == 0 { return false } // Check if starts with CALL keyword if strings.ToUpper(params[0]) == "CALL" { return true } // Check if first token is a declared function if c.funcHandler.FuncExists(params[0]) { return true } // For intuitive syntax like "funcname(args)", extract function name // by looking for '(' and taking everything before it firstToken := params[0] if idx := strings.IndexByte(firstToken, '('); idx > 0 { funcName := firstToken[:idx] return c.funcHandler.FuncExists(funcName) } return false } func (c *CallCommand) Interpret(line preproc.Line, ctx *compiler.CompilerContext) error { c.asmOutput = nil asm, err := ctx.FunctionHandler.HandleFuncCall(line) if err != nil { return err } c.asmOutput = asm return nil } func (c *CallCommand) Generate(_ *compiler.CompilerContext) ([]string, error) { return c.asmOutput, nil }