commit a3ffc702a1a99f9d827ec0cb0097a5e60d4c7ec2
parent c1e17a9489c559cf491fe0761a412b19d7e96427
Author: bsandro <email@bsandro.tech>
Date: Tue, 21 Jun 2022 03:29:02 +0300
expressions in return statements
Diffstat:
2 files changed, 29 insertions(+), 26 deletions(-)
diff --git a/parser/parser.go b/parser/parser.go
@@ -123,8 +123,9 @@ func (p *Parser) parseLetStatement() *ast.LetStatement {
if !p.expectPeek(token.ASSIGN) {
return nil
}
-
- for !p.curTokenIs(token.SEMICOLON) {
+ p.nextToken()
+ statement.Value = p.parseExpression(LOWEST)
+ if p.peekTokenIs(token.SEMICOLON) {
p.nextToken()
}
@@ -134,8 +135,8 @@ func (p *Parser) parseLetStatement() *ast.LetStatement {
func (p *Parser) parseReturnStatement() *ast.ReturnStatement {
statement := &ast.ReturnStatement{Token: p.curToken}
p.nextToken()
-
- for !p.curTokenIs(token.SEMICOLON) {
+ statement.ReturnValue = p.parseExpression(LOWEST)
+ for p.peekTokenIs(token.SEMICOLON) {
p.nextToken()
}
diff --git a/parser/parser_test.go b/parser/parser_test.go
@@ -8,36 +8,38 @@ import (
)
func TestLetStatements(t *testing.T) {
- input := `
-let x = 5;
-let y = 10;
-let foo = 112233;
-`
- l := lexer.New(input)
- p := New(l)
- program := p.ParseProgram()
- checkParserErrors(t, p)
-
- if program == nil {
- t.Fatalf("ParseProgram() returned nil")
- }
- if len(program.Statements) != 3 {
- t.Fatalf("program.Statements has not 3 elements but %d", len(program.Statements))
- }
-
tests := []struct {
+ input string
expectedIdentifier string
+ expectedValue interface{}
}{
- {"x"},
- {"y"},
- {"foo"},
+ {"let x = 5;", "x", 5},
+ {"let y = true;", "y", true},
+ {"let foo = y;", "foo", "y"},
}
- for i, tt := range tests {
- statement := program.Statements[i]
+ for _, tt := range tests {
+ l := lexer.New(tt.input)
+ p := New(l)
+ prg := p.ParseProgram()
+ checkParserErrors(t, p)
+
+ if prg == nil {
+ t.Fatalf("ParseProgram() returned nil")
+ }
+ if len(prg.Statements) != 1 {
+ t.Fatalf("program.Statements has not 1 elements but %d", len(prg.Statements))
+ }
+
+ statement := prg.Statements[0]
if !testLetStatement(t, statement, tt.expectedIdentifier) {
return
}
+
+ val := statement.(*ast.LetStatement).Value
+ if !testLiteralExpression(t, val, tt.expectedValue) {
+ return
+ }
}
}