repl.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package repl
  2. import (
  3. "bufio"
  4. "fmt"
  5. "github/runnignwater/monkey/compiler"
  6. "github/runnignwater/monkey/lexer"
  7. "github/runnignwater/monkey/object"
  8. "github/runnignwater/monkey/parser"
  9. "github/runnignwater/monkey/vm"
  10. "io"
  11. "log"
  12. )
  13. /**
  14. * @Author: simon
  15. * @Author: ynwdlxm@163.com
  16. * @Date: 2022/10/2 下午5:41
  17. * @Desc: REPL that tokenizes Monkey source code and prints the tokens
  18. */
  19. const PROMPT = ">>> "
  20. func Start(in io.Reader, out io.Writer) {
  21. scanner := bufio.NewScanner(in)
  22. // env := object.NewEnvironment()
  23. var constants []object.Object
  24. globals := make([]object.Object, vm.GlobalSize)
  25. symbolTable := compiler.NewSymbolTable()
  26. for {
  27. fmt.Printf(PROMPT)
  28. scan := scanner.Scan()
  29. if !scan {
  30. return
  31. }
  32. line := scanner.Text()
  33. l := lexer.New(line)
  34. p := parser.New(l)
  35. program := p.ParseProgram()
  36. if len(p.Errors()) != 0 {
  37. printParserErrors(out, p.Errors())
  38. continue
  39. }
  40. // evaluated := evaluator.Eval(program, env)
  41. // if evaluated != nil {
  42. // if _, err := io.WriteString(out, evaluated.Inspect()); err != nil {
  43. // panic(err)
  44. // }
  45. // if _, err := io.WriteString(out, "\n"); err != nil {
  46. // panic(err)
  47. // }
  48. // }
  49. comp := compiler.NewWithState(symbolTable, constants)
  50. err := comp.Compile(program)
  51. if err != nil {
  52. _, err := fmt.Fprintf(out, "Woops! Compilation failed:\n %s\n", err)
  53. if err != nil {
  54. return
  55. }
  56. continue
  57. }
  58. code := comp.ByteCode()
  59. constants = code.Constants
  60. machine := vm.NewWithGlobalsStore(code, globals)
  61. err = machine.Run()
  62. if err != nil {
  63. _, err := fmt.Fprintf(out, "Woops! Executing bytecode failed:\n %s\n", err)
  64. if err != nil {
  65. return
  66. }
  67. continue
  68. }
  69. lastPopped := machine.LastPopStackElem()
  70. _, err = io.WriteString(out, lastPopped.Inspect())
  71. if err != nil {
  72. return
  73. }
  74. _, err = io.WriteString(out, "\n")
  75. if err != nil {
  76. return
  77. }
  78. }
  79. }
  80. func printParserErrors(out io.Writer, errors []string) {
  81. if _, err := io.WriteString(out, "Woops! we ran into some monkey business here!\n"); err != nil {
  82. log.Fatal(err)
  83. }
  84. if _, err := io.WriteString(out, " parser errors:\n"); err != nil {
  85. log.Fatal(err)
  86. }
  87. for _, msg := range errors {
  88. _, err := io.WriteString(out, "\t"+msg+"\n")
  89. if err != nil {
  90. return
  91. }
  92. }
  93. }