From 4241593b42bffac2f8fcb63f1e88621fe025e360 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Mon, 4 Sep 2023 16:58:15 +0200 Subject: codegen: add interpreter tests Also simplify project structure. The executable is now produced in the root directory. Work in progress. --- main.go | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 main.go (limited to 'main.go') diff --git a/main.go b/main.go new file mode 100644 index 0000000..037614c --- /dev/null +++ b/main.go @@ -0,0 +1,71 @@ +package main + +import ( + "bufio" + "errors" + "fmt" + "io" + "log" + "os" + + "github.com/gnolang/parscan/codegen" + "github.com/gnolang/parscan/lang/golang" + "github.com/gnolang/parscan/scanner" + "github.com/gnolang/parscan/vm0" +) + +type Interpreter interface { + Eval(string) (any, error) +} + +func main() { + log.SetFlags(log.Lshortfile) + var interp Interpreter = vm0.New(golang.GoParser) + if len(os.Args) > 1 && os.Args[1] == "1" { + interp = codegen.NewInterpreter(golang.GoParser) + interp.(*codegen.Interpreter).AddSym(fmt.Println, "println") + } + in := os.Stdin + + if isatty(in) { + // Provide an interactive line oriented Read Eval Print Loop (REPL). + liner := bufio.NewScanner(in) + text, prompt := "", "> " + fmt.Print(prompt) + for liner.Scan() { + text += liner.Text() + res, err := interp.Eval(text + "\n") + if err == nil { + if res != nil { + fmt.Println(": ", res) + } + text, prompt = "", "> " + } else if errors.Is(err, scanner.ErrBlock) { + prompt = ">> " + } else { + fmt.Println("Error:", err) + text, prompt = "", "> " + } + fmt.Print(prompt) + } + return + } + + buf, err := io.ReadAll(in) + if err != nil { + log.Fatal(err) + } + if _, err := interp.Eval(string(buf)); err != nil { + log.Fatal(err) + } +} + +// isatty returns true if the input stream is a tty (i.e. a character device). +func isatty(in io.Reader) bool { + s, ok := in.(interface{ Stat() (os.FileInfo, error) }) + if !ok { + return false + } + stat, err := s.Stat() + return err == nil && stat.Mode()&os.ModeCharDevice != 0 +} -- cgit v1.2.3