From 4bd0027c702c9fcebebb969bd4ea03fba7a67ba2 Mon Sep 17 00:00:00 2001 From: Zorchenhimer Date: Sat, 6 Sep 2025 22:53:33 -0400 Subject: [PATCH] [script] Add some statisticts tracking Track the statistics of used instructions for the script. --- cmd/script-decode.go | 15 ++++++++++++ script/script.go | 32 ++++++++++++++++++++++++- script/stats.go | 56 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 script/stats.go diff --git a/cmd/script-decode.go b/cmd/script-decode.go index 722a146..44ddb0a 100644 --- a/cmd/script-decode.go +++ b/cmd/script-decode.go @@ -17,6 +17,7 @@ type Arguments struct { Input string `arg:"positional,required"` Output string `arg:"positional"` StartAddr string `arg:"--start" default:"0x6000" help:"base address for the start of the script"` + StatsFile string `arg:"--stats" help:"file to write some statistics to"` LabelFile string `arg:"--labels" help:"file containing address/label pairs"` start int @@ -78,6 +79,20 @@ func run(args *Arguments) error { fmt.Fprintln(outfile, token.String(scr.Labels)) } + if args.StatsFile != "" { + statfile, err := os.Create(args.StatsFile) + if err != nil { + return fmt.Errorf("Unable to create stats file: %w", err) + } + defer statfile.Close() + + //err = scr.WriteStats(statfile) + _, err = scr.Stats().WriteTo(statfile) + if err != nil { + return fmt.Errorf("Error writing stats: %w", err) + } + } + return nil } diff --git a/script/script.go b/script/script.go index 35a5693..2ac1529 100644 --- a/script/script.go +++ b/script/script.go @@ -1,6 +1,7 @@ package script import ( + "fmt" ) type Script struct { @@ -10,6 +11,35 @@ type Script struct { StartAddress int StackAddress int - //Labels map[int]string Labels map[int]*Label } + +type InstrStat struct { + Instr *Instruction + Count int +} + +func (is InstrStat) String() string { + return fmt.Sprintf("0x%02X %3d %s", is.Instr.Opcode, is.Count, is.Instr.String()) +} + +func (s *Script) Stats() Stats { + st := make(Stats) + + for _, t := range s.Tokens { + if t.Instruction == nil { + continue + } + + op := t.Instruction.Opcode + if _, ok := st[op]; !ok { + st[op] = &InstrStat{ + Instr: t.Instruction, + Count: 0, + } + } + st[op].Count++ + } + + return st +} diff --git a/script/stats.go b/script/stats.go new file mode 100644 index 0000000..8139e2a --- /dev/null +++ b/script/stats.go @@ -0,0 +1,56 @@ +package script + +import ( + "io" + "slices" + "maps" + "fmt" +) + +type Stats map[byte]*InstrStat + +func (this Stats) Add(that Stats) { + for _, st := range that { + op := st.Instr.Opcode + if _, ok := this[op]; !ok { + this[op] = st + } else { + this[op].Count += that[op].Count + } + } +} + +func (s Stats) WriteTo(w io.Writer) (int64, error) { + count := int64(0) + keys := slices.Sorted(maps.Keys(s)) + + unknownInstr := 0 + unknownUses := 0 + + for _, key := range keys { + n, err := fmt.Fprintln(w, s[key]) + count += int64(n) + if err != nil { + return count, err + } + + if s[key].Instr.Name == "" { + unknownInstr++ + unknownUses += s[key].Count + } + } + + n, err := fmt.Fprintln(w, "\nUnknown uses:", unknownUses) + count += int64(n) + if err != nil { + return count, err + } + + n, err = fmt.Fprintln(w, "Unknown instructions:", unknownInstr) + count += int64(n) + if err != nil { + return count, err + } + + return count, nil +}