|
@@ -37,6 +37,17 @@ type (
|
|
infixParseFn func(ast.Expression) ast.Expression
|
|
infixParseFn func(ast.Expression) ast.Expression
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+var precedences = map[token.TokenType]int{
|
|
|
|
+ token.EQ: EQUALS,
|
|
|
|
+ token.NOT_EQ: EQUALS,
|
|
|
|
+ token.LT: LESSGREATER,
|
|
|
|
+ token.GT: LESSGREATER,
|
|
|
|
+ token.PLUS: SUM,
|
|
|
|
+ token.MINUS: SUM,
|
|
|
|
+ token.SLASH: PRODUCT,
|
|
|
|
+ token.ASTERISK: PRODUCT,
|
|
|
|
+}
|
|
|
|
+
|
|
// New returns a new Parser instance with the first two parser tokens already
|
|
// New returns a new Parser instance with the first two parser tokens already
|
|
// loaded.
|
|
// loaded.
|
|
func New(l *lexer.Lexer) *Parser {
|
|
func New(l *lexer.Lexer) *Parser {
|
|
@@ -45,6 +56,20 @@ func New(l *lexer.Lexer) *Parser {
|
|
errors: []string{},
|
|
errors: []string{},
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ p.infixParseFns = make(map[token.TokenType]infixParseFn)
|
|
|
|
+ for _, tok := range []token.TokenType{
|
|
|
|
+ token.ASTERISK,
|
|
|
|
+ token.EQ,
|
|
|
|
+ token.GT,
|
|
|
|
+ token.LT,
|
|
|
|
+ token.MINUS,
|
|
|
|
+ token.NOT_EQ,
|
|
|
|
+ token.PLUS,
|
|
|
|
+ token.SLASH,
|
|
|
|
+ } {
|
|
|
|
+ p.registerInfix(tok, p.parseInfixExpression)
|
|
|
|
+ }
|
|
|
|
+
|
|
p.prefixParseFns = make(map[token.TokenType]prefixParseFn)
|
|
p.prefixParseFns = make(map[token.TokenType]prefixParseFn)
|
|
p.registerPrefix(token.BANG, p.parsePrefixExpression)
|
|
p.registerPrefix(token.BANG, p.parsePrefixExpression)
|
|
p.registerPrefix(token.IDENT, p.parseIdentifier)
|
|
p.registerPrefix(token.IDENT, p.parseIdentifier)
|
|
@@ -80,6 +105,16 @@ func (p *Parser) ParseProgram() *ast.Program {
|
|
return program
|
|
return program
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Return the precedence for the current token without advancing.
|
|
|
|
+func (p *Parser) curPrecedence() int {
|
|
|
|
+ if p, ok := precedences[p.curToken.Type]; ok {
|
|
|
|
+ return p
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return LOWEST
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
// Is the current token in the parser of the given type ?
|
|
// Is the current token in the parser of the given type ?
|
|
func (p *Parser) curTokenIs(t token.TokenType) bool {
|
|
func (p *Parser) curTokenIs(t token.TokenType) bool {
|
|
return p.curToken.Type == t
|
|
return p.curToken.Type == t
|
|
@@ -122,6 +157,15 @@ func (p *Parser) peekError(t token.TokenType) {
|
|
p.errors = append(p.errors, msg)
|
|
p.errors = append(p.errors, msg)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Look forward for the precedence of the next token without advancing.
|
|
|
|
+func (p *Parser) peekPrecedence() int {
|
|
|
|
+ if p, ok := precedences[p.peekToken.Type]; ok {
|
|
|
|
+ return p
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return LOWEST
|
|
|
|
+}
|
|
|
|
+
|
|
// Is the next token in the parser of the given type ? Don't consume it.
|
|
// Is the next token in the parser of the given type ? Don't consume it.
|
|
func (p *Parser) peekTokenIs(t token.TokenType) bool {
|
|
func (p *Parser) peekTokenIs(t token.TokenType) bool {
|
|
return p.peekToken.Type == t
|
|
return p.peekToken.Type == t
|