package repl import ( "bufio" _ "embed" "fmt" "io" "monkey/evaluator" "monkey/lexer" "monkey/object" "monkey/parser" ) const prompt = ">> " func Start(in io.Reader, out io.Writer) { scanner := bufio.NewScanner(in) env := object.NewEnvironment() macroEnv := object.NewEnvironment() for { fmt.Print(prompt) if !scanner.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 } evaluator.DefineMacros(program, macroEnv) expanded := evaluator.ExpandMacros(program, macroEnv) evaluated := evaluator.Eval(expanded, env) if evaluated != nil { io.WriteString(out, evaluated.Inspect()) io.WriteString(out, "\n") } } } //go:embed face.txt var monkeyFace string func printParserErrors(out io.Writer, errors []error) { fmt.Fprintln(out, monkeyFace) for _, err := range errors { fmt.Fprintln(out, err) } }