package repl import ( "bufio" "fmt" "github/runnignwater/monkey/evaluator" "github/runnignwater/monkey/lexer" "github/runnignwater/monkey/object" "github/runnignwater/monkey/parser" "io" "log" ) /** * @Author: simon * @Author: ynwdlxm@163.com * @Date: 2022/10/2 下午5:41 * @Desc: REPL that tokenizes Monkey source code and prints the tokens */ const PROMPT = ">>> " func Start(in io.Reader, out io.Writer) { scanner := bufio.NewScanner(in) env := object.NewEnvironment() for { fmt.Printf(PROMPT) scan := scanner.Scan() if !scan { return } line := scanner.Text() l := lexer.New(line) p := parser.New(l) program := p.ParseProgram() if len(p.Errors()) != 0 { printParserErrors(out, p.Errors()) continue } evaluated := evaluator.Eval(program, env) if evaluated != nil { if _, err := io.WriteString(out, evaluated.Inspect()); err != nil { panic(err) } if _, err := io.WriteString(out, "\n"); err != nil { panic(err) } } } } func printParserErrors(out io.Writer, errors []string) { if _, err := io.WriteString(out, "Woops! we ran into some monkey business here!\n"); err != nil { log.Fatal(err) } if _, err := io.WriteString(out, " parser errors:\n"); err != nil { log.Fatal(err) } for _, msg := range errors { _, err := io.WriteString(out, "\t"+msg+"\n") if err != nil { return } } }