bind expression (:=) instead of let
Some checks failed
Build / build (push) Successful in 10m26s
Test / build (push) Failing after 16m44s

This commit is contained in:
Chuck Smith
2024-03-21 17:43:03 -04:00
parent 66d5453ecc
commit 6282075e66
36 changed files with 425 additions and 583 deletions

View File

@@ -11,7 +11,7 @@ import (
const (
_ int = iota
LOWEST
ASSIGN // =
ASSIGN // := or =
EQUALS // ==
LESSGREATER // > or <
SUM // +
@@ -22,6 +22,7 @@ const (
)
var precedences = map[token.TokenType]int{
token.BIND: ASSIGN,
token.ASSIGN: ASSIGN,
token.EQ: EQUALS,
token.NOT_EQ: EQUALS,
@@ -89,6 +90,7 @@ func New(l *lexer.Lexer) *Parser {
p.registerInfix(token.GTE, p.parseInfixExpression)
p.registerInfix(token.LPAREN, p.parseCallExpression)
p.registerInfix(token.LBRACKET, p.parseIndexExpression)
p.registerInfix(token.BIND, p.parseBindExpression)
p.registerInfix(token.ASSIGN, p.parseAssignmentExpression)
p.registerInfix(token.DOT, p.parseSelectorExpression)
@@ -161,8 +163,6 @@ func (p *Parser) parseStatement() ast.Statement {
switch p.curToken.Type {
case token.COMMENT:
return p.parseComment()
case token.LET:
return p.parseLetStatement()
case token.RETURN:
return p.parseReturnStatement()
default:
@@ -170,34 +170,6 @@ func (p *Parser) parseStatement() ast.Statement {
}
}
func (p *Parser) parseLetStatement() *ast.LetStatement {
stmt := &ast.LetStatement{Token: p.curToken}
if !p.expectPeek(token.IDENT) {
return nil
}
stmt.Name = &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}
if !p.expectPeek(token.ASSIGN) {
return nil
}
p.nextToken()
stmt.Value = p.parseExpression(LOWEST)
if fl, ok := stmt.Value.(*ast.FunctionLiteral); ok {
fl.Name = stmt.Name.Value
}
if p.peekTokenIs(token.SEMICOLON) {
p.nextToken()
}
return stmt
}
func (p *Parser) parseReturnStatement() *ast.ReturnStatement {
stmt := &ast.ReturnStatement{Token: p.curToken}
@@ -578,3 +550,26 @@ func (p *Parser) parseSelectorExpression(expression ast.Expression) ast.Expressi
index := &ast.StringLiteral{Token: p.curToken, Value: p.curToken.Literal}
return &ast.IndexExpression{Left: expression, Index: index}
}
func (p *Parser) parseBindExpression(expression ast.Expression) ast.Expression {
switch node := expression.(type) {
case *ast.Identifier:
default:
msg := fmt.Sprintf("expected identifier opn left but got %T %#v", node, expression)
p.errors = append(p.errors, msg)
return nil
}
be := &ast.BindExpression{Token: p.curToken, Left: expression}
p.nextToken()
be.Value = p.parseExpression(LOWEST)
if fl, ok := be.Value.(*ast.FunctionLiteral); ok {
ident := be.Left.(*ast.Identifier)
fl.Name = ident.Value
}
return be
}