repl.go 1.2 KB

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