package repl import ( "bufio" "fmt" "io" "monna/evaluator" "monna/lexer" "monna/object" "monna/parser" ) const MONKEY_FACE = ` __,__ .--. .-" "-. .--. / .. \/ .-. .-. \/ .. \ | | '| / Y \ |' | | | \ \ \ 0 | 0 / / / | \ '- ,\.-"""""""-./, -' / ''-' /_ ^ ^ _\ '-'' | \._ _./ | \ \ '~' / / '._ '-=-' _.' '-----' ` const PROMPT = ">> " func Start(in io.Reader, out io.Writer) { scanner := bufio.NewScanner(in) env := object.NewEnvironment() for { fmt.Fprintf(out, PROMPT) scanned := scanner.Scan() if !scanned { return } line := scanner.Text() l_lexer := lexer.New(line) l_parser := parser.New(l_lexer) program := l_parser.ParseProgram() if len(l_parser.Errors()) != 0 { print_parser_errors(out, l_parser.Errors()) continue } evaluated := evaluator.Eval(program, env) if evaluated != nil { io.WriteString(out, evaluated.Inspect()) io.WriteString(out, "\n") } } } func print_parser_errors(out io.Writer, errors []string) { io.WriteString(out, MONKEY_FACE) io.WriteString(out, "Woops! I ran into some monkey business here!\n") io.WriteString(out, " parser errors:\n") for _, message := range errors { io.WriteString(out, "\t"+message+"\n") } }