package main import ( "fmt" "go/token" "net/http" "github.com/sbinet/go-eval/pkg/eval" ) var fset = token.NewFileSet() var world = eval.NewWorld() func evalHandler(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { codeSource := r.FormValue("codeSource") code, err := world.Compile(fset, codeSource) if err != nil { w.Write([]byte(err.Error())) return } result, err := code.Run() if err != nil { w.Write([]byte(err.Error())) return } if result != nil { w.Write([]byte(result.String())) return }
func main() { flag.Parse() w := eval.NewWorld() if *filename != "" { data, err := ioutil.ReadFile(*filename) if err != nil { fmt.Println(err.Error()) os.Exit(1) } file, err := parser.ParseFile(fset, *filename, data, 0) if err != nil { fmt.Println(err.Error()) os.Exit(1) } files := []*ast.File{file} code, err := w.CompilePackage(fset, files, "main") if err != nil { if list, ok := err.(scanner.ErrorList); ok { for _, e := range list { fmt.Println(e.Error()) } } else { fmt.Println(err.Error()) } os.Exit(1) } code, err = w.Compile(fset, "main()") if err != nil { fmt.Println(err.Error()) os.Exit(1) } _, err = code.Run() if err != nil { fmt.Println(err.Error()) os.Exit(1) } os.Exit(0) } fmt.Println(":: welcome to go-eval...") fd := int(os.Stdin.Fd()) oldState, err := terminal.MakeRaw(fd) if err != nil { panic(err) } defer terminal.Restore(fd, oldState) term := terminal.NewTerminal(&shell{r: os.Stdin, w: os.Stdout}, "> ") if term == nil { panic(errors.New("could not create terminal")) } for { line, err := term.ReadLine() if err != nil { break } code, err := w.Compile(fset, line) if err != nil { term.Write([]byte(err.Error() + "\n")) continue } v, err := code.Run() if err != nil { term.Write([]byte(err.Error() + "\n")) continue } if v != nil { term.Write([]byte(v.String() + "\n")) } } }
func main() { defer atexit() flag.Parse() w := eval.NewWorld() if *filename != "" { data, err := ioutil.ReadFile(*filename) if err != nil { fmt.Println(err.Error()) os.Exit(1) } file, err := parser.ParseFile(fset, *filename, data, 0) if err != nil { fmt.Println(err.Error()) os.Exit(1) } files := []*ast.File{file} code, err := w.CompilePackage(fset, files, "main") if err != nil { if list, ok := err.(scanner.ErrorList); ok { for _, e := range list { fmt.Println(e.Error()) } } else { fmt.Println(err.Error()) } os.Exit(1) } code, err = w.Compile(fset, "main()") if err != nil { fmt.Println(err.Error()) os.Exit(1) } _, err = code.Run() if err != nil { fmt.Println(err.Error()) os.Exit(1) } os.Exit(0) } var ierr error = nil // previous interpreter error ps1 := "igo> " ps2 := "... " prompt := &ps1 codelet := "" // initialize main package { codelet := "package main\n" f, err := parser.ParseFile(fset, "input", codelet, 0) code, err := w.CompilePackage(fset, []*ast.File{f}, "main") if err == nil { code.Run() } } for { line, err := term.Prompt(*prompt) if err != nil { if err != io.EOF { ierr = err } else { ierr = nil } break //os.Exit(0) } if line == "" || line == ";" { // no more input prompt = &ps1 } codelet += line if codelet != "" { for _, ll := range strings.Split(codelet, "\n") { term.AppendHistory(ll) } } code, err := w.Compile(fset, codelet+";") if err != nil { if ierr != nil && prompt == &ps1 { fmt.Println(err.Error()) fmt.Printf("(error %T)\n", err) // reset state codelet = "" ierr = nil prompt = &ps1 continue } // maybe multi-line command ? prompt = &ps2 ierr = err codelet += "\n" continue } v, err := code.Run() if err != nil { fmt.Println(err.Error()) fmt.Printf("(error %T)\n", err) codelet = "" continue } if v != nil { fmt.Println(v.String()) } // resetstate: // reset state codelet = "" ierr = nil } }