|
|
@@ -52,6 +52,8 @@ func New(l *lexer.Lexer) *Parser {
|
|
|
p.prefixParseFns = make(map[token.TypeToken]prefixParseFn)
|
|
|
p.registerPrefix(token.IDENT, p.parseIdentifier)
|
|
|
p.registerPrefix(token.INT, p.parseIntegerLiteral)
|
|
|
+ p.registerPrefix(token.BANG, p.parsePrefixExpression)
|
|
|
+ p.registerPrefix(token.MINUS, p.parsePrefixExpression)
|
|
|
|
|
|
// Read two tokens, so curToken and peekToken are both set
|
|
|
p.nextToken()
|
|
|
@@ -63,6 +65,31 @@ func New(l *lexer.Lexer) *Parser {
|
|
|
func (p *Parser) parseIdentifier() ast.Expression {
|
|
|
return &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}
|
|
|
}
|
|
|
+func (p *Parser) parseIntegerLiteral() ast.Expression {
|
|
|
+ lit := &ast.IntegerLiteral{Token: p.curToken}
|
|
|
+
|
|
|
+ value, err := strconv.ParseInt(p.curToken.Literal, 0, 64)
|
|
|
+ if err != nil {
|
|
|
+ msg := fmt.Sprintf("could not parse %q as integer", p.curToken.Literal)
|
|
|
+ p.errors = append(p.errors, msg)
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ lit.Value = value
|
|
|
+
|
|
|
+ return lit
|
|
|
+}
|
|
|
+func (p *Parser) parsePrefixExpression() ast.Expression {
|
|
|
+ exp := &ast.PrefixExpression{
|
|
|
+ Token: p.curToken,
|
|
|
+ Operator: p.curToken.Literal,
|
|
|
+ }
|
|
|
+
|
|
|
+ p.nextToken()
|
|
|
+
|
|
|
+ exp.Right = p.parseExpression(PREFIX)
|
|
|
+
|
|
|
+ return exp
|
|
|
+}
|
|
|
|
|
|
func (p *Parser) Errors() []string {
|
|
|
return p.errors
|
|
|
@@ -160,6 +187,7 @@ func (p *Parser) parseExpressionStatement() *ast.ExpressionStatement {
|
|
|
func (p *Parser) parseExpression(precedence int) ast.Expression {
|
|
|
prefix := p.prefixParseFns[p.curToken.Type]
|
|
|
if prefix == nil {
|
|
|
+ p.noPrefixParseFnError(p.curToken.Type)
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
@@ -167,19 +195,6 @@ func (p *Parser) parseExpression(precedence int) ast.Expression {
|
|
|
|
|
|
return leftExp
|
|
|
}
|
|
|
-func (p *Parser) parseIntegerLiteral() ast.Expression {
|
|
|
- lit := &ast.IntegerLiteral{Token: p.curToken}
|
|
|
-
|
|
|
- value, err := strconv.ParseInt(p.curToken.Literal, 0, 64)
|
|
|
- if err != nil {
|
|
|
- msg := fmt.Sprintf("could not parse %q as integer", p.curToken.Literal)
|
|
|
- p.errors = append(p.errors, msg)
|
|
|
- return nil
|
|
|
- }
|
|
|
- lit.Value = value
|
|
|
-
|
|
|
- return lit
|
|
|
-}
|
|
|
|
|
|
func (p *Parser) curTokenIs(t token.TypeToken) bool {
|
|
|
return p.curToken.Type == t
|
|
|
@@ -206,3 +221,8 @@ func (p *Parser) registerPrefix(tokenType token.TypeToken, fn prefixParseFn) {
|
|
|
func (p *Parser) registerInfix(tokenType token.TypeToken, fn infixParseFn) {
|
|
|
p.infixParseFns[tokenType] = fn
|
|
|
}
|
|
|
+
|
|
|
+func (p *Parser) noPrefixParseFnError(t token.TypeToken) {
|
|
|
+ msg := fmt.Sprintf("no prefix parse function for %s found", t)
|
|
|
+ p.errors = append(p.errors, msg)
|
|
|
+}
|