diff --git a/parser/parser.go b/parser/parser.go index 80a60cc..1f81799 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -176,21 +176,21 @@ func (l_parser *Parser) parse_statement() ast.Statement { func (l_parser *Parser) parse_let_statement() *ast.LetStatement { defer untrace(trace("parse_let_statement")) - statement := &ast.LetStatement{ Token: l_parser.current_token } + statement := &ast.LetStatement{Token: l_parser.current_token} - if !l_parser.expect_peek(token.IDENT){ + if !l_parser.expect_peek(token.IDENT) { return nil } - statement.Name = &ast.Identifier{ Token: l_parser.current_token, Value: l_parser.current_token.Literal } - if !l_parser.expect_peek(token.ASSIGN){ + statement.Name = &ast.Identifier{Token: l_parser.current_token, Value: l_parser.current_token.Literal} + if !l_parser.expect_peek(token.ASSIGN) { return nil } l_parser.next_token() statement.Value = l_parser.parse_expression(LOWEST) - if l_parser.peek_token_is(token.SEMICOLON){ + if l_parser.peek_token_is(token.SEMICOLON) { l_parser.next_token() } return statement @@ -198,12 +198,12 @@ func (l_parser *Parser) parse_let_statement() *ast.LetStatement { func (l_parser *Parser) parse_return_statement() *ast.ReturnStatement { defer untrace(trace("parse_return_statement")) - + statement := &ast.ReturnStatement{Token: l_parser.current_token} l_parser.next_token() statement.ReturnValue = l_parser.parse_expression(LOWEST) - + if l_parser.peek_token_is(token.SEMICOLON) { l_parser.next_token() } diff --git a/parser/parser_test.go b/parser/parser_test.go index fb79a30..daf2e01 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -647,12 +647,12 @@ func TestLetStatements(l_test *testing.T) { } statement := program.Statements[0] - if !testLetStatement(l_test, statement, tt.expected_identifier){ + if !testLetStatement(l_test, statement, tt.expected_identifier) { return } val := statement.(*ast.LetStatement).Value - if !testLiteralExpression(l_test, val, tt.expected_value){ + if !testLiteralExpression(l_test, val, tt.expected_value) { return } } diff --git a/repl/repl.go b/repl/repl.go index 1c36ba7..e69e5ae 100644 --- a/repl/repl.go +++ b/repl/repl.go @@ -4,11 +4,23 @@ import ( "bufio" "fmt" "io" - "monkey/lexer" - "monkey/token" + "monkey/parser" ) +const MONKEY_FACE = ` __,__ + .--. .-" "-. .--. + / .. \/ .-. .-. \/ .. \ + | | '| / Y \ |' | | + | \ \ \ 0 | 0 / / / | + \ '- ,\.-"""""""-./, -' / + ''-' /_ ^ ^ _\ '-'' + | \._ _./ | + \ \ '~' / / + '._ '-=-' _.' + '-----' +` + const PROMPT = ">> " func Start(in io.Reader, out io.Writer) { @@ -22,10 +34,25 @@ func Start(in io.Reader, out io.Writer) { } line := scanner.Text() - l := lexer.New(line) + l_lexer := lexer.New(line) + l_parser := parser.New(l_lexer) + program := l_parser.ParseProgram() - for tok := l.NextToken(); tok.Type != token.EOF; tok = l.NextToken() { - fmt.Fprintf(out, "%+v\n", tok) + if len(l_parser.Errors()) != 0 { + print_parser_errors(out, l_parser.Errors()) + continue } + + io.WriteString(out, program.String()) + 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") } }