1
0
Protocol/opcodes/gen/main.go

85 lines
1.6 KiB
Go

//go:build ignore
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"os"
"sort"
"strings"
"text/template"
)
const outputTemplate = `// Code generated by gen/main.go; DO NOT EDIT.
package opcodes
// initializeNameMappings populates nameToEmu from constants
func (om *OpcodeManager) initializeNameMappings() {
{{- range . }}
om.nameToEmu["{{ .Name }}"] = {{ .Name }}
{{- end }}
}
`
type OpcodeInfo struct {
Name string
}
func main() {
opcodes := []OpcodeInfo{}
// Parse each source file for OP_ constants
files := []string{"login.go", "emu.go"}
for _, filename := range files {
fset := token.NewFileSet()
node, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to parse %s: %v\n", filename, err)
continue
}
// Find all OP_ and LS_ constants
ast.Inspect(node, func(n ast.Node) bool {
spec, ok := n.(*ast.ValueSpec)
if !ok {
return true
}
for _, name := range spec.Names {
if strings.HasPrefix(name.Name, "OP_") || strings.HasPrefix(name.Name, "LS_") {
opcodes = append(opcodes, OpcodeInfo{Name: name.Name})
}
}
return true
})
}
// Sort for consistent output
sort.Slice(opcodes, func(i, j int) bool {
return opcodes[i].Name < opcodes[j].Name
})
// Generate output
tmpl, err := template.New("opcodes").Parse(outputTemplate)
if err != nil {
panic(err)
}
file, err := os.Create("generated.go")
if err != nil {
panic(err)
}
defer file.Close()
if err := tmpl.Execute(file, opcodes); err != nil {
panic(err)
}
fmt.Printf("Generated %d opcode mappings\n", len(opcodes))
}