Added lexing and parsing of LAMBDA to monkey2 version

main
oabrivard 2 years ago
parent 8a5d7ab5d3
commit f69fa28995

@ -0,0 +1,3 @@
module gitea.paas.celticinfo.fr/oabrivard/monkeylang/monkey2
go 1.21.0

@ -33,7 +33,14 @@ func (l *Lexer) NextToken() token.Token {
case '+': case '+':
tok = newToken(token.PLUS, l.ch) tok = newToken(token.PLUS, l.ch)
case '-': case '-':
if l.peekChar() == '>' {
ch := l.ch
l.readChar()
literal := string(ch) + string(l.ch)
tok = token.Token{Type: token.LAMBDA, Literal: literal}
} else {
tok = newToken(token.MINUS, l.ch) tok = newToken(token.MINUS, l.ch)
}
case '!': case '!':
if l.peekChar() == '=' { if l.peekChar() == '=' {
ch := l.ch ch := l.ch

@ -14,6 +14,8 @@ let add = fn(x, y) {
x + y; x + y;
}; };
let addlambda = fn(x,y) -> x + y;
let result = add(five, ten); let result = add(five, ten);
!-/*5; !-/*5;
5 < 10 > 5; 5 < 10 > 5;
@ -59,6 +61,20 @@ if (5 < 10) {
{token.RBRACE, "}"}, {token.RBRACE, "}"},
{token.SEMICOLON, ";"}, {token.SEMICOLON, ";"},
{token.LET, "let"}, {token.LET, "let"},
{token.IDENT, "addlambda"},
{token.ASSIGN, "="},
{token.FUNCTION, "fn"},
{token.LPAREN, "("},
{token.IDENT, "x"},
{token.COMMA, ","},
{token.IDENT, "y"},
{token.RPAREN, ")"},
{token.LAMBDA, "->"},
{token.IDENT, "x"},
{token.PLUS, "+"},
{token.IDENT, "y"},
{token.SEMICOLON, ";"},
{token.LET, "let"},
{token.IDENT, "result"}, {token.IDENT, "result"},
{token.ASSIGN, "="}, {token.ASSIGN, "="},
{token.IDENT, "add"}, {token.IDENT, "add"},

@ -357,11 +357,28 @@ func (p *Parser) parseFunctionLiteral() ast.Expression {
lit.Parameters = p.parseFunctionParameters() lit.Parameters = p.parseFunctionParameters()
if p.peekTokenIs(token.LAMBDA) {
// parse fn() with lambda syntax
p.nextToken()
p.nextToken()
block := &ast.BlockStatement{Token: p.curToken}
block.Statements = []ast.Statement{}
exp := p.parseExpressionStatement()
if exp != nil {
block.Statements = append(block.Statements, exp)
}
lit.Body = block
} else {
// parse fn() with bloc statement syntax
if !p.expectPeek(token.LBRACE) { if !p.expectPeek(token.LBRACE) {
return nil return nil
} }
lit.Body = p.parseBlockStatement() lit.Body = p.parseBlockStatement()
}
return lit return lit
} }

@ -503,9 +503,16 @@ func TestIfElseExpression(t *testing.T) {
} }
func TestFunctionLiteralParsing(t *testing.T) { func TestFunctionLiteralParsing(t *testing.T) {
input := `fn(x, y) { x + y; }` tests := []struct {
input string
}{
{"fn(x, y) { x + y; }"},
{"fn(x, y) -> x + y;"},
}
l := lexer.New(input) for _, tt := range tests {
l := lexer.New(tt.input)
p := New(l) p := New(l)
program := p.ParseProgram() program := p.ParseProgram()
checkParserErrors(t, p) checkParserErrors(t, p)
@ -548,6 +555,7 @@ func TestFunctionLiteralParsing(t *testing.T) {
testInfixExpression(t, bodyStmt.Expression, "x", "+", "y") testInfixExpression(t, bodyStmt.Expression, "x", "+", "y")
} }
}
func TestFunctionParameterParsing(t *testing.T) { func TestFunctionParameterParsing(t *testing.T) {
tests := []struct { tests := []struct {

@ -33,6 +33,8 @@ const (
LBRACE = "{" LBRACE = "{"
RBRACE = "}" RBRACE = "}"
LAMBDA = "->"
// Keywords // Keywords
FUNCTION = "FUNCTION" FUNCTION = "FUNCTION"
LET = "LET" LET = "LET"

Loading…
Cancel
Save