package commands import ( "fmt" "strings" "c65gm/internal/compiler" "c65gm/internal/preproc" "c65gm/internal/utils" ) // OriginCommand handles ORIGIN declarations // Syntax: ORIGIN
// Sets the assembly origin address (ACME: *= address) type OriginCommand struct { address uint16 } func (c *OriginCommand) WillHandle(line preproc.Line) bool { params, err := utils.ParseParams(line.Text) if err != nil || len(params) == 0 { return false } upper := strings.ToUpper(params[0]) return upper == "ORIGIN" || upper == "ORGIN" // Support common typo } func (c *OriginCommand) Interpret(line preproc.Line, ctx *compiler.CompilerContext) error { params, err := utils.ParseParams(line.Text) if err != nil { return err } if len(params) != 2 { return fmt.Errorf("ORIGIN: expected 2 parameters, got %d", len(params)) } scope := ctx.CurrentScope() constLookup := func(name string) (int64, bool) { sym := ctx.SymbolTable.Lookup(name, scope) if sym != nil && sym.IsConst() { return int64(sym.Value), true } return 0, false } val, err := utils.EvaluateExpression(params[1], constLookup) if err != nil { return fmt.Errorf("ORIGIN: invalid address expression: %w", err) } if val < 0 || val > 65535 { return fmt.Errorf("ORIGIN: address %d out of range (0-65535)", val) } c.address = uint16(val) return nil } func (c *OriginCommand) Generate(_ *compiler.CompilerContext) ([]string, error) { return []string{fmt.Sprintf("*= $%04x", c.address)}, nil }