Parses infix expressions.

Signed-off-by: jmug <u.g.a.mariano@gmail.com>
This commit is contained in:
Mariano Uvalle 2025-01-04 17:56:10 -08:00
parent f286a88039
commit 5fa7b2481a
4 changed files with 201 additions and 4 deletions

View file

@ -30,10 +30,20 @@ func New(l *lexer.Lexer) *Parser {
prefixParseFns: map[token.TokenType]prefixParseFn{},
infixParseFns: map[token.TokenType]infixParseFn{},
}
// Prefix registrations
p.registerPrefix(token.IDENT, p.parseIdentifier)
p.registerPrefix(token.INT, p.parseIntegerLiteral)
p.registerPrefix(token.MINUS, p.parsePrefixExpression)
p.registerPrefix(token.BANG, p.parsePrefixExpression)
// Infix registrations
p.registerInfix(token.PLUS, p.parseInfixExpression)
p.registerInfix(token.MINUS, p.parseInfixExpression)
p.registerInfix(token.ASTERISK, p.parseInfixExpression)
p.registerInfix(token.SLASH, p.parseInfixExpression)
p.registerInfix(token.GT, p.parseInfixExpression)
p.registerInfix(token.LT, p.parseInfixExpression)
p.registerInfix(token.EQ, p.parseInfixExpression)
p.registerInfix(token.NOT_EQ, p.parseInfixExpression)
// TODO: figure out why this can't be done from `parseProgram`
p.nextToken()
p.nextToken()
@ -111,9 +121,16 @@ func (p *Parser) parseExpression(precedence int) ast.Expression {
p.noPrefixParseFnError(p.curToken.Type)
return nil
}
leftExpr := prefix()
return leftExpr
curExpr := prefix()
for !p.peekTokenIs(token.SEMICOLON) && precedence < p.peekPrecedence() {
infix := p.infixParseFns[p.peekToken.Type]
if infix == nil {
return curExpr
}
p.nextToken()
curExpr = infix(curExpr)
}
return curExpr
}
func (p *Parser) parseIdentifier() ast.Expression {
@ -141,6 +158,18 @@ func (p *Parser) parsePrefixExpression() ast.Expression {
return exp
}
func (p *Parser) parseInfixExpression(left ast.Expression) ast.Expression {
exp := &ast.InfixExpression{
Token: p.curToken,
Operator: p.curToken.Literal,
Left: left,
}
precedence := p.curPrecedence()
p.nextToken()
exp.Right = p.parseExpression(precedence)
return exp
}
func (p *Parser) curTokenIs(typ token.TokenType) bool {
return p.curToken.Type == typ
}