From fad3808c23163d441d0bd09d88be07eb5a09315c Mon Sep 17 00:00:00 2001 From: Houcine EL ADDALI Date: Sun, 17 Dec 2023 14:18:25 +0100 Subject: [PATCH] fix: let&return value parsing --- parser/data/test_data.go | 10 ++++++---- parser/parser.go | 12 ++++++++---- parser/parser_test.go | 19 ++++++++++++++----- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/parser/data/test_data.go b/parser/data/test_data.go index b0c12e7..c4d9457 100644 --- a/parser/data/test_data.go +++ b/parser/data/test_data.go @@ -8,10 +8,11 @@ var ( ` DefStmExpected = []struct { ExpectedIdentifier string + ExpectedValue int }{ - {"num1"}, - {"total"}, - {"a"}, + {"num1", 13}, + {"total", 0}, + {"a", 5321}, } ReturnStm = ` @@ -19,7 +20,8 @@ var ( return 101232; return 0; ` - Identifier = `varName;` + ExpectedReturnValue = []int{545, 101232, 0} + Identifier = `varName;` IntegerLit = "81;" diff --git a/parser/parser.go b/parser/parser.go index 17e0604..028ae81 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -163,7 +163,11 @@ func (p *Parser) parseDefStmt() *ast.DefStatement { return nil } - for !p.currentTokenEquals(token.S_COLON) { + p.NextToken() // move to the expression after = + + stm.Value = p.parseExpression(LOWEST) + + for p.peekTokenEquals(token.S_COLON) { p.NextToken() } @@ -262,9 +266,9 @@ func (p *Parser) parseReturnStmt() *ast.ReturnStatement { stm := &ast.ReturnStatement{Token: p.currToken} p.NextToken() - - //TODO: - for !p.currentTokenEquals(token.S_COLON) { + stm.ReturnValue = p.parseExpression(LOWEST) + // + for p.peekTokenEquals(token.S_COLON) { p.NextToken() } diff --git a/parser/parser_test.go b/parser/parser_test.go index 1b61fee..de6302d 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -29,9 +29,10 @@ func TestDefStatement(t *testing.T) { stm := program.Statements[i] - if !testDefStatement(t, stm, t1.ExpectedIdentifier) { + if !testDefStatement(t, stm, t1.ExpectedIdentifier, t1.ExpectedValue) { return } + } } @@ -39,12 +40,13 @@ func TestDefStatement(t *testing.T) { func TestReturnStatement(t *testing.T) { input := data.ReturnStm - pr, _ := getProg(input) + expectReturnValue := data.ExpectedReturnValue + pr, parser := getProg(input) - //check is length of the program statement slice is 3 + checkParserErrors(parser, t) checkIsProgramStmLengthValid(pr, t, 3) - for _, stm := range pr.Statements { + for i, stm := range pr.Statements { returnStm, ok := stm.(*ast.ReturnStatement) if !ok { t.Errorf("statement not *ast.ReturnStatement type got:%T", stm) @@ -55,6 +57,9 @@ func TestReturnStatement(t *testing.T) { t.Errorf("returnStatement token literal is not 'return' instead got: %s", returnStm.TokenLiteral()) } + if !testLiteralExpression(t, returnStm.ReturnValue, expectReturnValue[i]) { + return + } } } @@ -342,7 +347,7 @@ func checkParserErrors(p *Parser, t *testing.T) { t.FailNow() // mark tests as failed and stop execution } -func testDefStatement(t *testing.T, stm ast.Statement, name string) bool { +func testDefStatement(t *testing.T, stm ast.Statement, name string, val int) bool { if stm.TokenLiteral() != "def" { t.Errorf("s.tokenLiteral is not 'def'. got instead:%q", stm.TokenLiteral()) return false @@ -365,6 +370,10 @@ func testDefStatement(t *testing.T, stm ast.Statement, name string) bool { return false } + if !testLiteralExpression(t, defStm.Value, val) { + return false + } + return true }