package main import ( "flag" "fmt" "jinx/pkg/lang/compiler" "jinx/pkg/lang/parser" "jinx/pkg/lang/scanner" "jinx/pkg/lang/vm" "os" "os/user" "path" ) func main() { compile := flag.String("c", "", "compile to file") run := flag.Bool("r", false, "run") flag.Parse() if *compile == "" && !*run { exit("nothing to do, either -c or -r is required") } filePath := flag.Arg(0) if filePath == "" { exit("no file specified") } file, err := os.Open(filePath) if err != nil { exit("could not open file: %v", err) } defer file.Close() scanner := scanner.New(file) tokens, err := scanner.Scan() if err != nil { exit("error during scanning: %v", err) } parser := parser.New(tokens) program, err := parser.Parse() if err != nil { exit("error during parsing: %v", err) } comp := compiler.New(path.Base(filePath), getUsername(), program) module, err := comp.Compile() if err != nil { exit("compilation failed: %v", err) } if *compile != "" { output, err := os.Create(*compile) if err != nil { exit("could not create file: %v", err) } defer output.Close() if _, err := output.Write(module.Code().Code()); err != nil { exit("could not write to file: %v", err) } } if *run { vm := vm.New(module, vm.NewConsoleOutput()) if err := vm.Run(); err != nil { exit("execution failed: %v", err) } } } func getUsername() string { me, err := user.Current() if err != nil { return "unknown" } return me.Username } func exit(format string, args ...any) { message := fmt.Sprintf(format, args...) fmt.Printf("error: %s\n", message) os.Exit(1) }