Parse lambda expressions
This commit is contained in:
parent
efbecd67d9
commit
d359527cf8
@ -356,9 +356,23 @@ namespace Parser.Tests
|
|||||||
var text = "@sqrt";
|
var text = "@sqrt";
|
||||||
var sut = CreateParser(text);
|
var sut = CreateParser(text);
|
||||||
var actual = sut.ParseExpression();
|
var actual = sut.ParseExpression();
|
||||||
Assert.IsInstanceOf<FunctionHandleNode>(actual);
|
Assert.IsInstanceOf<NamedFunctionHandleNode>(actual);
|
||||||
var f = (FunctionHandleNode) actual;
|
var f = (NamedFunctionHandleNode) actual;
|
||||||
Assert.AreEqual("sqrt", f.IdentifierName.Token.PureToken.LiteralText);
|
Assert.AreEqual("sqrt", f.IdentifierName.Token.PureToken.LiteralText);
|
||||||
|
Assert.AreEqual(text, actual.FullText);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ParseLambda()
|
||||||
|
{
|
||||||
|
var text = "@(x, y) x + y";
|
||||||
|
var sut = CreateParser(text);
|
||||||
|
var actual = sut.ParseExpression();
|
||||||
|
Assert.IsInstanceOf<LambdaNode>(actual);
|
||||||
|
var f = (LambdaNode) actual;
|
||||||
|
Assert.AreEqual(2, f.Input.Parameters.Parameters.Count);
|
||||||
|
Assert.IsInstanceOf<BinaryOperationExpressionNode>(f.Body);
|
||||||
|
Assert.AreEqual(text, actual.FullText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -553,10 +553,19 @@ namespace Parser
|
|||||||
private FunctionHandleNode ParseFunctionHandle()
|
private FunctionHandleNode ParseFunctionHandle()
|
||||||
{
|
{
|
||||||
var atSign = EatToken();
|
var atSign = EatToken();
|
||||||
|
if (CurrentToken.Kind == TokenKind.Identifier)
|
||||||
|
{
|
||||||
var identifierName = EatToken(TokenKind.Identifier);
|
var identifierName = EatToken(TokenKind.Identifier);
|
||||||
return Factory.FunctionHandle(
|
return Factory.NamedFunctionHandle(
|
||||||
Factory.Token(atSign),
|
Factory.Token(atSign),
|
||||||
Factory.IdentifierName(identifierName));
|
Factory.IdentifierName(identifierName));
|
||||||
|
} else if (CurrentToken.Kind == TokenKind.OpeningBracket)
|
||||||
|
{
|
||||||
|
var inputs = ParseFunctionInputDescription();
|
||||||
|
var body = ParseExpression();
|
||||||
|
return Factory.Lambda(Factory.Token(atSign), inputs, body);
|
||||||
|
}
|
||||||
|
throw new ParsingException($"Unexpected token {CurrentToken.PureToken} while parsing function handle at {CurrentToken.PureToken.Position}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExpressionNode ParseSubExpression(ParseOptions options, Precedence precedence)
|
private ExpressionNode ParseSubExpression(ParseOptions options, Precedence precedence)
|
||||||
|
@ -542,7 +542,7 @@ namespace Parser
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FunctionHandleNode FunctionHandle(
|
public NamedFunctionHandleNode NamedFunctionHandle(
|
||||||
TokenNode atSign,
|
TokenNode atSign,
|
||||||
IdentifierNameNode identifierName)
|
IdentifierNameNode identifierName)
|
||||||
{
|
{
|
||||||
@ -551,7 +551,7 @@ namespace Parser
|
|||||||
atSign,
|
atSign,
|
||||||
identifierName
|
identifierName
|
||||||
};
|
};
|
||||||
var result = new FunctionHandleNode(
|
var result = new NamedFunctionHandleNode(
|
||||||
children,
|
children,
|
||||||
atSign,
|
atSign,
|
||||||
identifierName);
|
identifierName);
|
||||||
@ -559,5 +559,24 @@ namespace Parser
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LambdaNode Lambda(
|
||||||
|
TokenNode atSign,
|
||||||
|
FunctionInputDescriptionNode input,
|
||||||
|
ExpressionNode body)
|
||||||
|
{
|
||||||
|
var children = new List<SyntaxNode>
|
||||||
|
{
|
||||||
|
atSign,
|
||||||
|
input,
|
||||||
|
body
|
||||||
|
};
|
||||||
|
var result = new LambdaNode(
|
||||||
|
children,
|
||||||
|
atSign,
|
||||||
|
input,
|
||||||
|
body);
|
||||||
|
SetParent(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -587,12 +587,20 @@ namespace Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FunctionHandleNode : ExpressionNode
|
public abstract class FunctionHandleNode : ExpressionNode
|
||||||
|
{
|
||||||
|
protected FunctionHandleNode(
|
||||||
|
List<SyntaxNode> children) : base(children)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NamedFunctionHandleNode : FunctionHandleNode
|
||||||
{
|
{
|
||||||
public TokenNode AtSign { get; }
|
public TokenNode AtSign { get; }
|
||||||
public IdentifierNameNode IdentifierName { get; }
|
public IdentifierNameNode IdentifierName { get; }
|
||||||
|
|
||||||
public FunctionHandleNode(
|
public NamedFunctionHandleNode(
|
||||||
List<SyntaxNode> children,
|
List<SyntaxNode> children,
|
||||||
TokenNode atSign,
|
TokenNode atSign,
|
||||||
IdentifierNameNode identifierName) : base(children)
|
IdentifierNameNode identifierName) : base(children)
|
||||||
@ -602,5 +610,21 @@ namespace Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class LambdaNode : FunctionHandleNode
|
||||||
|
{
|
||||||
|
public TokenNode AtSign { get; }
|
||||||
|
public FunctionInputDescriptionNode Input { get; }
|
||||||
|
public ExpressionNode Body { get; }
|
||||||
|
|
||||||
|
public LambdaNode(
|
||||||
|
List<SyntaxNode> children,
|
||||||
|
TokenNode atSign,
|
||||||
|
FunctionInputDescriptionNode input,
|
||||||
|
ExpressionNode body) : base(children)
|
||||||
|
{
|
||||||
|
AtSign = atSign;
|
||||||
|
Input = input;
|
||||||
|
Body = body;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user