package optimizer import ( "strconv" "strings" "c65gm/internal/preproc" ) type Config struct { EnableLoad bool EnableImm bool EnableJmp bool EnableSelf bool EnableStoreLoad bool Debug bool ShowMarkers bool IOMap [65536]bool } func NewConfig(ps preproc.PragmaSet) *Config { all := ps.GetPragma("_P_OPT_ALL") != "" && ps.GetPragma("_P_OPT_ALL") != "0" return &Config{ EnableLoad: all || (ps.GetPragma("_P_OPT_LOAD") != "" && ps.GetPragma("_P_OPT_LOAD") != "0"), EnableImm: all || (ps.GetPragma("_P_OPT_IMM") != "" && ps.GetPragma("_P_OPT_IMM") != "0"), EnableJmp: all || (ps.GetPragma("_P_OPT_JMP") != "" && ps.GetPragma("_P_OPT_JMP") != "0"), EnableSelf: all || (ps.GetPragma("_P_OPT_SELF") != "" && ps.GetPragma("_P_OPT_SELF") != "0"), EnableStoreLoad: all || (ps.GetPragma("_P_OPT_STLD") != "" && ps.GetPragma("_P_OPT_STLD") != "0"), Debug: (ps.GetPragma("_P_OPT_DEBUG") != "" && ps.GetPragma("_P_OPT_DEBUG") != "0"), ShowMarkers: (ps.GetPragma("_P_OPT_MARKERS") != "" && ps.GetPragma("_P_OPT_MARKERS") != "0"), } } func (c *Config) Any() bool { return c.EnableLoad || c.EnableImm || c.EnableJmp || c.EnableSelf || c.EnableStoreLoad } // BuildIOMap scans all pragma sets for _P_OPT_IO and marks I/O regions. func (c *Config) BuildIOMap(pragma *preproc.Pragma) { for i := 0; i <= pragma.GetCurrentPragmaSetIndex(); i++ { val := pragma.GetPragmaSetByIndex(i).GetPragma("_P_OPT_IO") if val == "" { continue } parts := strings.Fields(val) if len(parts) >= 2 { start := parsePragmaAddr(parts[0]) end := parsePragmaAddr(parts[1]) if start >= 0 && end >= 0 && start <= end && start < 65536 { for a := start; a <= end && a < 65536; a++ { c.IOMap[a] = true } } } } } func parsePragmaAddr(s string) int { if strings.HasPrefix(s, "$") { v, err := strconv.ParseUint(s[1:], 16, 16) if err != nil { return -1 } return int(v) } v, err := strconv.ParseUint(s, 10, 16) if err != nil { return -1 } return int(v) }