package main import ( "flag" "fmt" "os" "strings" "c65gm/internal/commands" "c65gm/internal/compiler" "c65gm/internal/preproc" ) // c65gm - A 6502 Cross-Compiler for the ACME Cross-Assembler // Copyright (C) 1999, 2025 Mattias Hansson // Distributed under GPL. func main() { fmt.Println("c65gm - A 6502 Cross-Compiler for the ACME Cross-Assembler.") fmt.Println("Copyright (C) 1999, 2025 Mattias Hansson. v1.0.0") fmt.Println("Distributed under GPL.") fmt.Println() inFile := flag.String("in", "", "input source file (required)") outFile := flag.String("out", "", "output assembly file (required)") flag.Parse() if *inFile == "" || *outFile == "" { _, _ = fmt.Fprintln(os.Stderr, "Error: -in and -out are required") flag.Usage() os.Exit(1) } if err := run(*inFile, *outFile); err != nil { if _, ok := err.(preproc.HaltError); ok { fmt.Println("Halted by #HALT directive") os.Exit(2) } _, _ = fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } fmt.Println("Compilation successful.") } func run(inFile, outFile string) error { // Preprocess lines, pragma, err := preproc.PreProcess(inFile) if err != nil { return fmt.Errorf("preprocessing failed: %w", err) } fmt.Printf("Preprocessed %d lines\n", len(lines)) // Create compiler and register commands comp := compiler.NewCompiler(pragma) registerCommands(comp) // Compile asmLines, err := comp.Compile(lines) if err != nil { return fmt.Errorf("compilation failed: %w", err) } fmt.Printf("Generated %d lines of assembly\n", len(asmLines)) // Write output if err := writeOutput(outFile, asmLines); err != nil { return fmt.Errorf("failed to write output: %w", err) } return nil } func registerCommands(comp *compiler.Compiler) { // Register all command handlers here // This is the single place where all commands are wired up comp.Registry().Register(&commands.ByteCommand{}) comp.Registry().Register(&commands.WordCommand{}) comp.Registry().Register(&commands.AddCommand{}) comp.Registry().Register(&commands.AndCommand{}) comp.Registry().Register(&commands.OrCommand{}) comp.Registry().Register(&commands.XorCommand{}) comp.Registry().Register(&commands.SubtractCommand{}) } func writeOutput(filename string, lines []string) error { return os.WriteFile(filename, []byte(strings.Join(lines, "\n")+"\n"), 0644) }