diff options
Diffstat (limited to 'parser/parser.go')
| -rw-r--r-- | parser/parser.go | 64 |
1 files changed, 40 insertions, 24 deletions
diff --git a/parser/parser.go b/parser/parser.go index a4472b2..4fa36b1 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -18,6 +18,7 @@ const ( PRODUCT // * PREFIX // -X or !X CALL // myFunction(X) + INDEX // array[index] ) var precedences = map[tokens.TokenType]int{ @@ -30,6 +31,7 @@ var precedences = map[tokens.TokenType]int{ tokens.SLASH: PRODUCT, tokens.ASTERISK: PRODUCT, tokens.LPAREN: CALL, + tokens.LBRACKET: INDEX, } type ( @@ -85,6 +87,7 @@ func New(l *lexer.Lexer) *Parser { p.registerInfix(tokens.LT, p.parseInfixExpression) p.registerInfix(tokens.GT, p.parseInfixExpression) p.registerInfix(tokens.LPAREN, p.parseCallExpression) + p.registerInfix(tokens.LBRACKET, p.parseIndexExpression) return p } @@ -117,9 +120,9 @@ func (p *Parser) ParseProgram() *ast.Program { // Parse the statement and append it to the program. var stmt ast.Statement = p.parseStatement() - if stmt != nil { - program.Statements = append(program.Statements, stmt) - } + // if stmt != nil { + program.Statements = append(program.Statements, stmt) + // } // Advance to the next token. p.nextToken() @@ -334,9 +337,9 @@ func (p *Parser) parseBlockStatement() *ast.BlockStatement { for !p.curTokenIs(tokens.RBRACE) && !p.curTokenIs(tokens.EOF) { stmt := p.parseStatement() - if stmt != nil { - block.Statements = append(block.Statements, stmt) - } + // if stmt != nil { + block.Statements = append(block.Statements, stmt) + // } p.nextToken() } @@ -414,29 +417,29 @@ func (p *Parser) parseCallExpression(function ast.Expression) ast.Expression { } // parseCallArguments parses call arguments. -func (p *Parser) parseCallArguments() []ast.Expression { - args := []ast.Expression{} +// func (p *Parser) parseCallArguments() []ast.Expression { +// args := []ast.Expression{} - if p.peekTokenIs(tokens.RPAREN) { - p.nextToken() - return args - } +// if p.peekTokenIs(tokens.RPAREN) { +// p.nextToken() +// return args +// } - p.nextToken() - args = append(args, p.parseExpression(LOWEST)) +// p.nextToken() +// args = append(args, p.parseExpression(LOWEST)) - for p.peekTokenIs(tokens.COMMA) { - p.nextToken() - p.nextToken() - args = append(args, p.parseExpression(LOWEST)) - } +// for p.peekTokenIs(tokens.COMMA) { +// p.nextToken() +// p.nextToken() +// args = append(args, p.parseExpression(LOWEST)) +// } - if !p.expectPeek(tokens.RPAREN) { - return nil - } +// if !p.expectPeek(tokens.RPAREN) { +// return nil +// } - return args -} +// return args +// } func (p *Parser) parseStringLiteral() ast.Expression { return &ast.StringLiteral{ @@ -478,6 +481,19 @@ func (p *Parser) parseExpressionList(end tokens.TokenType) []ast.Expression { return list } +func (p *Parser) parseIndexExpression(left ast.Expression) ast.Expression { + exp := &ast.IndexExpression{Token: p.curToken, Left: left} + + p.nextToken() + exp.Index = p.parseExpression(LOWEST) + + if !p.expectPeek(tokens.RBRACKET) { + return nil + } + + return exp +} + // curTokenIs returns true if the current token is of the given type. func (p *Parser) curTokenIs(t tokens.TokenType) bool { return p.curToken.Type == t |
