diff options
| author | Mel <einebeere@gmail.com> | 2022-05-20 01:43:55 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-05-20 01:43:55 +0200 |
| commit | 20d84ae7ffd8a8e4c9397470e5b0459fec9a86ba (patch) | |
| tree | 426a72eb7f78d70945f450f1756ee6bb72c2bfaa | |
| parent | abebfa047e3ef9bc8fb06d73d0d39d393e51c92c (diff) | |
| download | jinx-20d84ae7ffd8a8e4c9397470e5b0459fec9a86ba.tar.zst jinx-20d84ae7ffd8a8e4c9397470e5b0459fec9a86ba.zip | |
Add VM cli tool
| -rw-r--r-- | Taskfile.yml | 7 | ||||
| -rw-r--r-- | cmd/vm/main.go | 91 |
2 files changed, 98 insertions, 0 deletions
diff --git a/Taskfile.yml b/Taskfile.yml index 9c3e6d3..86f6a8d 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -7,6 +7,7 @@ tasks: desc: "Builds Jinx binaries." cmds: - go build -o build/bot jinx/cmd/bot + - go build -o build/vm jinx/cmd/vm run: desc: "Runs Jinx bot binary." @@ -14,6 +15,12 @@ tasks: cmds: - build/bot + run-vm: + desc: "Runs VM compiler and runtime." + deps: [build] + cmds: + - build/vm {{.CLI_ARGS}} + test: desc: "Tests all packages." cmds: 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) +} |
