Skip to content

Commit

Permalink
2.8: Set values to let statement and return statement
Browse files Browse the repository at this point in the history
  • Loading branch information
nibral committed Jan 13, 2019
1 parent 05202be commit dd38cef
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 41 deletions.
10 changes: 8 additions & 2 deletions parser/parser.go
Expand Up @@ -163,7 +163,11 @@ func (p *Parser) parseLetStatement() ast.Statement {
return nil
}

for !p.curTokenIs(token.SEMICOLON) {
p.nextToken()

stmt.Value = p.parseExpression(LOWEST)

for p.peekTokenIs(token.SEMICOLON) {
p.nextToken()
}

Expand Down Expand Up @@ -193,7 +197,9 @@ func (p *Parser) parseReturnStatement() *ast.ReturnStatement {

p.nextToken()

for !p.curTokenIs(token.SEMICOLON) {
stmt.ReturnValue = p.parseExpression(LOWEST)

for p.peekTokenIs(token.SEMICOLON) {
p.nextToken()
}

Expand Down
85 changes: 46 additions & 39 deletions parser/parser_test.go
Expand Up @@ -8,36 +8,36 @@ import (
)

func TestLetStatements(t *testing.T) {
input := `
let x = 5;
let y = 10;
let foobar = 838383;
`
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 does not contain 3 statements. got=%d", len(program.Statements))
}

tests := []struct {
input string
expectedIdentifier string
expectedValue interface{}
}{
{"x"},
{"y"},
{"foobar"},
{"let x = 5;", "x", 5},
{"let y = true;", "y", true},
{"let foobar = y;", "foobar", "y"},
}

for i, tt := range tests {
stmt := program.Statements[i]
for _, tt := range tests {
l := lexer.New(tt.input)
p := New(l)
program := p.ParseProgram()
checkParserErrors(t, p)

if len(program.Statements) != 1 {
t.Fatalf("program.Statements does not contain 1 statements. got=%d",
len(program.Statements))
}

stmt := program.Statements[0]
if !testLetStatement(t, stmt, tt.expectedIdentifier) {
return
}

val := stmt.(*ast.LetStatement).Value
if !testLiteralExpression(t, val, tt.expectedValue) {
return
}
}
}

Expand Down Expand Up @@ -77,31 +77,38 @@ func checkParserErrors(t *testing.T, p *Parser) {
}

func TestReturnStatement(t *testing.T) {
input := `
return 5;
return 10;
return 993322;
`
tests := []struct {
input string
expectedValue interface{}
}{
{"return 5;", 5},
{"return true;", true},
{"return foobar;", "foobar"},
}

l := lexer.New(input)
p := New(l)
program := p.ParseProgram()
checkParserErrors(t, p)
for _, tt := range tests {
l := lexer.New(tt.input)
p := New(l)
program := p.ParseProgram()
checkParserErrors(t, p)

if len(program.Statements) != 3 {
t.Fatalf("program.Statements does not contain 3 statements. got=%d",
len(program.Statements))
}
for _, stmt := range program.Statements {
if len(program.Statements) != 1 {
t.Fatalf("program.Statements does not contain 1 statements. got=%d",
len(program.Statements))
}

stmt := program.Statements[0]
returnStmt, ok := stmt.(*ast.ReturnStatement)
if !ok {
t.Errorf("stmt not *ast.returnStatement. got=%T", stmt)
continue
t.Fatalf("stmt not *ast.returnStatement. got=%T", stmt)
}
if returnStmt.TokenLiteral() != "return" {
t.Errorf("returnStmt.TokenLiteral not 'return', got %q",
t.Fatalf("returnStmt.TokenLiteral not 'return', got %q",
returnStmt.TokenLiteral())
}
if testLiteralExpression(t, returnStmt.ReturnValue, tt.expectedValue) {
return
}
}
}

Expand Down

0 comments on commit dd38cef

Please sign in to comment.