From be05c459c07ae9e14f6c09fd3f820d8a459f3254 Mon Sep 17 00:00:00 2001 From: Bobby Date: Wed, 24 Jan 2024 21:26:00 +0000 Subject: fn literals --- parser/parser.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'parser/parser.go') diff --git a/parser/parser.go b/parser/parser.go index e38e54c..afbdf24 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -68,6 +68,7 @@ func New(l *lexer.Lexer) *Parser { p.registerPrefix(tokens.TRUE, p.parseBoolean) p.registerPrefix(tokens.FALSE, p.parseBoolean) p.registerPrefix(tokens.IF, p.parseIfExpression) + p.registerPrefix(tokens.FUNCTION, p.parseFunctionLiteral) // Initialize the infix parse functions. p.infixParseFns = make(map[tokens.TokenType]infixParseFn) @@ -330,6 +331,48 @@ func (p *Parser) parseBlockStatement() *ast.BlockStatement { return block } +// parseFunctionLiteral parses a function literal. +func (p *Parser) parseFunctionLiteral() ast.Expression { + lit := &ast.FunctionLiteral{Token: p.curToken} + + if !p.expectPeek(tokens.LPAREN) { return nil } + + lit.Parameters = p.parseFunctionParameters() + + if !p.expectPeek(tokens.LBRACE) { return nil } + + lit.Body = p.parseBlockStatement() + + return lit + +} + +// parseFunctionParameters parses function parameters. +func (p *Parser) parseFunctionParameters() []*ast.Identifier { + identifiers := []*ast.Identifier{} + + if p.peekTokenIs(tokens.RPAREN) { + p.nextToken() + return identifiers + } + + p.nextToken() + + ident := &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal} + identifiers = append(identifiers, ident) + + for p.peekTokenIs(tokens.COMMA) { + p.nextToken() + p.nextToken() + ident := &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal} + identifiers = append(identifiers, ident) + } + + if !p.expectPeek(tokens.RPAREN) { return nil } + + return identifiers +} + // 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 -- cgit v1.2.3