repl.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package repl
  2. import (
  3. "bufio"
  4. "fmt"
  5. "github/runnignwater/monkey/evaluator"
  6. "github/runnignwater/monkey/lexer"
  7. "github/runnignwater/monkey/object"
  8. "github/runnignwater/monkey/parser"
  9. "io"
  10. "log"
  11. )
  12. /**
  13. * @Author: simon
  14. * @Author: ynwdlxm@163.com
  15. * @Date: 2022/10/2 下午5:41
  16. * @Desc: REPL that tokenizes Monkey source code and prints the tokens
  17. */
  18. const PROMPT = ">>> "
  19. func Start(in io.Reader, out io.Writer) {
  20. scanner := bufio.NewScanner(in)
  21. env := object.NewEnvironment()
  22. for {
  23. fmt.Printf(PROMPT)
  24. scan := scanner.Scan()
  25. if !scan {
  26. return
  27. }
  28. line := scanner.Text()
  29. l := lexer.New(line)
  30. p := parser.New(l)
  31. program := p.ParseProgram()
  32. if len(p.Errors()) != 0 {
  33. printParserErrors(out, p.Errors())
  34. continue
  35. }
  36. evaluated := evaluator.Eval(program, env)
  37. if evaluated != nil {
  38. if _, err := io.WriteString(out, evaluated.Inspect()); err != nil {
  39. panic(err)
  40. }
  41. if _, err := io.WriteString(out, "\n"); err != nil {
  42. panic(err)
  43. }
  44. }
  45. }
  46. }
  47. func printParserErrors(out io.Writer, errors []string) {
  48. if _, err := io.WriteString(out, "Woops! we ran into some monkey business here!\n"); err != nil {
  49. log.Fatal(err)
  50. }
  51. if _, err := io.WriteString(out, " parser errors:\n"); err != nil {
  52. log.Fatal(err)
  53. }
  54. for _, msg := range errors {
  55. _, err := io.WriteString(out, "\t"+msg+"\n")
  56. if err != nil {
  57. return
  58. }
  59. }
  60. }