Case identifier in switch statement can be any expression

This commit is contained in:
Alexander Luzgarev 2018-04-01 11:18:44 +02:00
parent 0b343873fc
commit 161ee42c81
4 changed files with 42 additions and 14 deletions

View File

@ -201,6 +201,7 @@ namespace Parser.Tests
Assert.IsInstanceOf<ArrayLiteralExpressionNode>(actual);
var a = (ArrayLiteralExpressionNode) actual;
Assert.AreEqual(0, a.Elements.Elements.Count);
Assert.AreEqual(text, actual.FullText);
}
[Test]
@ -212,6 +213,7 @@ namespace Parser.Tests
Assert.IsInstanceOf<CellArrayLiteralExpressionNode>(actual);
var a = (CellArrayLiteralExpressionNode) actual;
Assert.AreEqual(3, a.Elements.Elements.Count);
Assert.AreEqual(text, actual.FullText);
}
[Test]
@ -224,6 +226,7 @@ namespace Parser.Tests
var a = (MemberAccessNode) actual;
Assert.IsInstanceOf<IdentifierNameNode>(a.LeftOperand);
Assert.IsInstanceOf<IndirectMemberAccessNode>(a.RightOperand);
Assert.AreEqual(text, actual.FullText);
}
[Test]
@ -236,6 +239,19 @@ namespace Parser.Tests
var m = (MemberAccessNode) actual;
Assert.IsInstanceOf<FunctionCallExpressionNode>(m.LeftOperand);
Assert.IsInstanceOf<IdentifierNameNode>(m.RightOperand);
Assert.AreEqual(text, actual.FullText);
}
[Test]
public void ParseFunctionDeclarationWithoutInputs()
{
var text = "function a = b a = 1";
var sut = CreateParser(text);
var actual = sut.ParseStatement();
Assert.IsInstanceOf<FunctionDeclarationNode>(actual);
var f = (FunctionDeclarationNode) actual;
Assert.AreEqual(f.InputDescription, null);
Assert.AreEqual(text, actual.FullText);
}
}
}

View File

@ -185,13 +185,20 @@ namespace Parser
private FunctionInputDescriptionNode ParseFunctionInputDescription()
{
var openingBracket = EatToken(TokenKind.OpeningBracket);
var parameterList = ParseParameterList();
var closingBracket = EatToken(TokenKind.ClosingBracket);
return Factory.FunctionInputDescription(
new TokenNode(openingBracket),
parameterList,
new TokenNode(closingBracket));
if (CurrentToken.Kind == TokenKind.OpeningBracket)
{
var openingBracket = EatToken(TokenKind.OpeningBracket);
var parameterList = ParseParameterList();
var closingBracket = EatToken(TokenKind.ClosingBracket);
return Factory.FunctionInputDescription(
new TokenNode(openingBracket),
parameterList,
new TokenNode(closingBracket));
}
else
{
return null;
}
}
private TokenNode PossibleSemicolonOrComma()
@ -564,9 +571,9 @@ namespace Parser
private SwitchCaseNode ParseSwitchCase()
{
var caseKeyword = EatIdentifier("case");
var caseId = EatToken(TokenKind.StringLiteral);
var caseId = ParseExpression();
var statementList = ParseStatements();
return Factory.SwitchCase(Factory.Token(caseKeyword), Factory.Token(caseId), statementList);
return Factory.SwitchCase(Factory.Token(caseKeyword), caseId, statementList);
}
private SwitchStatementNode ParseSwitchStatement()
@ -644,7 +651,8 @@ namespace Parser
var ifKeyword = Factory.Token(EatToken());
var condition = ParseExpression();
var commas = new List<TokenNode>();
while (CurrentToken.Kind == TokenKind.Comma)
while (CurrentToken.Kind == TokenKind.Comma
|| CurrentToken.Kind == TokenKind.Semicolon)
{
commas.Add(Factory.Token(EatToken()));
}

View File

@ -32,7 +32,11 @@ namespace Parser
children.Add(outputDescription);
}
children.Add(name);
children.Add(inputDescription);
if (inputDescription != null)
{
children.Add(inputDescription);
}
children.Add(body);
if (end != null)
{
@ -142,7 +146,7 @@ namespace Parser
public SwitchCaseNode SwitchCase(
TokenNode caseKeyword,
TokenNode caseIdentifier,
ExpressionNode caseIdentifier,
StatementListNode statementList)
{
var children = new List<SyntaxNode>

View File

@ -216,13 +216,13 @@ namespace Parser
public class SwitchCaseNode : SyntaxNode
{
public TokenNode CaseKeyword { get; }
public TokenNode CaseIdentifier { get; }
public ExpressionNode CaseIdentifier { get; }
public StatementListNode StatementList { get; }
public SwitchCaseNode(
List<SyntaxNode> children,
TokenNode caseKeyword,
TokenNode caseIdentifier,
ExpressionNode caseIdentifier,
StatementListNode statementList
) : base(children)
{