diff --git a/parser/parser.go b/parser/parser.go index 44d324e..80a60cc 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -175,18 +175,22 @@ 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} - if !l_parser.expect_peek(token.IDENT) { + + statement := &ast.LetStatement{ Token: l_parser.current_token } + + 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 } - // TODO(tijani): Skipping the expressins until there is a semicolon - for !l_parser.current_token_is(token.SEMICOLON) { + l_parser.next_token() + statement.Value = l_parser.parse_expression(LOWEST) + + if l_parser.peek_token_is(token.SEMICOLON){ l_parser.next_token() } return statement @@ -194,11 +198,13 @@ 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() - // TODO(tijani): Skipping the expression until there is semicolon - for !l_parser.current_token_is(token.SEMICOLON) { + statement.ReturnValue = l_parser.parse_expression(LOWEST) + + if l_parser.peek_token_is(token.SEMICOLON) { l_parser.next_token() } return statement diff --git a/parser/parser_test.go b/parser/parser_test.go index 8ce4eb7..fb79a30 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -624,6 +624,40 @@ func TestCallExpressionParameterParsing(l_test *testing.T) { } } +func TestLetStatements(l_test *testing.T) { + tests := []struct { + input string + expected_identifier string + expected_value interface{} + }{ + {"let x = 5;", "x", 5}, + {"let y = true;", "y", true}, + {"let foobar = y;", "foobar", "y"}, + } + + for _, tt := range tests { + l_lexer := lexer.New(tt.input) + l_parser := New(l_lexer) + program := l_parser.ParseProgram() + check_parser_errors(l_test, l_parser) + + if len(program.Statements) != 1 { + l_test.Fatalf("program.Statements does not contain 1 statements, got=%d", + len(program.Statements)) + } + + statement := program.Statements[0] + if !testLetStatement(l_test, statement, tt.expected_identifier){ + return + } + + val := statement.(*ast.LetStatement).Value + if !testLiteralExpression(l_test, val, tt.expected_value){ + return + } + } +} + // Helpers func check_parser_errors(l_test *testing.T, l_parser *Parser) {