diff options
Diffstat (limited to 'cmd/vm')
| -rw-r--r-- | cmd/vm/main.go | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/cmd/vm/main.go b/cmd/vm/main.go new file mode 100644 index 0000000..b844dbc --- /dev/null +++ b/cmd/vm/main.go @@ -0,0 +1,91 @@ +package main + +import ( + "flag" + "fmt" + "io" + "jinx/pkg/lang/vm" + "jinx/pkg/lang/vm/code" + "jinx/pkg/lang/vm/text" + "os" +) + +func main() { + // Take the first argument as the path to the file to be parsed. + compile := flag.String("c", "", "compile to file (if not bytecode)") + run := flag.Bool("r", false, "run") + bytecode := flag.Bool("b", false, "interpret bytecode, without this flag the program will be interpreted in Lang VM text format.") + + flag.Parse() + + if *compile != "" && *bytecode { + exit("-c and -b are mutually exclusive") + } + + if *bytecode && !*run { + exit("-b requires -r") + } + + if *compile == "" && !*run { + exit("nothing to do, either -c or -r is required") + } + + path := flag.Arg(0) + if path == "" { + exit("no file specified") + } + + file, err := os.Open(path) + if err != nil { + exit("could not open file: %v", err) + } + defer file.Close() + + var bc code.Code + if !*bytecode { + comp := text.NewCompiler(file) + bc, 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(bc.Code()); err != nil { + exit("could not write to file: %v", err) + } + } + } else { + content, err := io.ReadAll(file) + if err != nil { + exit("could not read file: %v", err) + } + + bc = code.New(content) + } + + if *run { + vm := vm.New(&bc) + if err := vm.Run(); err != nil { + exit("execution failed: %v", err) + } + + res, err := vm.GetResult() + if err != nil { + exit("could not get result: %v", err) + } + + fmt.Println(res) + } +} + +func exit(format string, args ...any) { + message := fmt.Sprintf(format, args...) + fmt.Printf("error: %s\n", message) + os.Exit(1) +} |
