repl.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package repl
  2. import (
  3. "bufio"
  4. "fmt"
  5. "github/runnignwater/monkey/compiler"
  6. "github/runnignwater/monkey/lexer"
  7. "github/runnignwater/monkey/parser"
  8. "github/runnignwater/monkey/vm"
  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. comp := compiler.New()
  46. err := comp.Compile(program)
  47. if err != nil {
  48. _, err := fmt.Fprintf(out, "Woops! Compilation failed:\n %s\n", err)
  49. if err != nil {
  50. return
  51. }
  52. continue
  53. }
  54. machine := vm.New(comp.ByteCode())
  55. err = machine.Run()
  56. if err != nil {
  57. _, err := fmt.Fprintf(out, "Woops! Executing bytecode failed:\n %s\n", err)
  58. if err != nil {
  59. return
  60. }
  61. continue
  62. }
  63. lastPopped := machine.LastPopStackElem()
  64. _, err = io.WriteString(out, lastPopped.Inspect())
  65. if err != nil {
  66. return
  67. }
  68. _, err = io.WriteString(out, "\n")
  69. if err != nil {
  70. return
  71. }
  72. }
  73. }
  74. func printParserErrors(out io.Writer, errors []string) {
  75. if _, err := io.WriteString(out, "Woops! we ran into some monkey business here!\n"); err != nil {
  76. log.Fatal(err)
  77. }
  78. if _, err := io.WriteString(out, " parser errors:\n"); err != nil {
  79. log.Fatal(err)
  80. }
  81. for _, msg := range errors {
  82. _, err := io.WriteString(out, "\t"+msg+"\n")
  83. if err != nil {
  84. return
  85. }
  86. }
  87. }