| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- package repl
- import (
- "bufio"
- "fmt"
- "github/runnignwater/monkey/compiler"
- "github/runnignwater/monkey/lexer"
- "github/runnignwater/monkey/parser"
- "github/runnignwater/monkey/vm"
- "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)
- // }
- // }
- comp := compiler.New()
- err := comp.Compile(program)
- if err != nil {
- _, err := fmt.Fprintf(out, "Woops! Compilation failed:\n %s\n", err)
- if err != nil {
- return
- }
- continue
- }
- machine := vm.New(comp.ByteCode())
- err = machine.Run()
- if err != nil {
- _, err := fmt.Fprintf(out, "Woops! Executing bytecode failed:\n %s\n", err)
- if err != nil {
- return
- }
- continue
- }
- lastPopped := machine.LastPopStackElem()
- _, err = io.WriteString(out, lastPopped.Inspect())
- if err != nil {
- return
- }
- _, err = io.WriteString(out, "\n")
- if err != nil {
- return
- }
- }
- }
- 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
- }
- }
- }
|