using System.Collections.Generic; using System.Linq; using Lexer; namespace Parser { public class SyntaxFactory { private static List RemoveNulls(List children) { return children.Where(x => x != null).ToList(); } public FunctionDeclarationNode FunctionDeclaration( TokenNode functionKeyword, FunctionOutputDescriptionNode outputDescription, TokenNode name, FunctionInputDescriptionNode inputDescription, StatementListNode body, TokenNode end, TokenNode semicolonOrComma = null) { var children = new List { functionKeyword, outputDescription, name, inputDescription, body, end, semicolonOrComma }; return new FunctionDeclarationNode( RemoveNulls(children), functionKeyword, outputDescription, name, inputDescription, body, end, semicolonOrComma); } public FunctionOutputDescriptionNode FunctionOutputDescription( List nodes, TokenNode equalitySign) { var children = new List(nodes); children.Add(equalitySign); return new FunctionOutputDescriptionNode( children, children .Where(node => node is TokenNode tokenNode && tokenNode.Token.Kind == TokenKind.Identifier) .Select(node => (TokenNode)node) .ToList(), equalitySign ); } public ParameterListNode ParameterList(List nodes) { return new ParameterListNode( nodes, nodes .Where( node => node is TokenNode tokenNode && tokenNode.Token.Kind != TokenKind.Comma ) .ToList()); } public StatementListNode StatementList(List nodes) { return new StatementListNode(nodes); } public FunctionInputDescriptionNode FunctionInputDescription( TokenNode openingBracket, ParameterListNode parameterList, TokenNode closingBracket) { var children = new List { openingBracket, parameterList, closingBracket }; return new FunctionInputDescriptionNode(children, openingBracket, parameterList, closingBracket); } public TokenNode Token(Token token) { return new TokenNode(token); } public SwitchStatementNode SwitchStatement( TokenNode switchKeyword, ExpressionNode switchExpression, List cases, TokenNode endKeyword, List optionalCommasAfterExpression, TokenNode semicolonOrComma = null) { var children = new List { switchKeyword, switchExpression }; children.AddRange(optionalCommasAfterExpression); children.AddRange(cases); children.Add(endKeyword); children.Add(semicolonOrComma); return new SwitchStatementNode( RemoveNulls(children), switchKeyword, switchExpression, cases, endKeyword, semicolonOrComma, optionalCommasAfterExpression); } public SwitchCaseNode SwitchCase( TokenNode caseKeyword, ExpressionNode caseIdentifier, StatementListNode statementList, List optionalCommasAfterIdentifier) { var children = new List { caseKeyword, caseIdentifier }; children.AddRange(optionalCommasAfterIdentifier); children.Add(statementList); return new SwitchCaseNode( RemoveNulls(children), caseKeyword, caseIdentifier, statementList, optionalCommasAfterIdentifier); } public AssignmentExpressionNode AssignmentExpression( ExpressionNode lhs, TokenNode assignmentSign, ExpressionNode rhs) { var children = new List { lhs, assignmentSign, rhs }; return new AssignmentExpressionNode(children, lhs, assignmentSign, rhs); } public UnaryPrefixOperationExpressionNode UnaryPrefixOperationExpression( TokenNode operation, ExpressionNode operand) { var children = new List { operation, operand }; return new UnaryPrefixOperationExpressionNode(children, operation, operand); } public UnaryPostfixOperationExpressionNode UnaryPostfixOperationExpression( ExpressionNode operand, TokenNode operation) { var children = new List { operand, operation }; return new UnaryPostfixOperationExpressionNode(children, operand, operation); } public BinaryOperationExpressionNode BinaryOperationExpression( ExpressionNode lhs, TokenNode operation, ExpressionNode rhs) { var children = new List { lhs, operation, rhs }; return new BinaryOperationExpressionNode(children, lhs, operation, rhs); } public IdentifierNameNode IdentifierName( Token identifier) { return new IdentifierNameNode(identifier); } public NumberLiteralNode NumberLiteral( Token numberLiteral) { return new NumberLiteralNode(numberLiteral); } public StringLiteralNode StringLiteral( Token stringLiteral) { return new StringLiteralNode(stringLiteral); } public DoubleQuotedStringLiteralNode DoubleQuotedStringLiteral( Token stringLiteral) { return new DoubleQuotedStringLiteralNode(stringLiteral); } public UnquotedStringLiteralNode UnquotedStringLiteral( Token stringLiteral) { return new UnquotedStringLiteralNode(stringLiteral); } public ExpressionStatementNode ExpressionStatement(ExpressionNode expression, TokenNode semicolonOrComma) { var children = new List {expression, semicolonOrComma}; return new ExpressionStatementNode( RemoveNulls(children), expression, semicolonOrComma); } public CellArrayElementAccessExpressionNode CellArrayElementAccessExpression( ExpressionNode cellArray, TokenNode openingBrace, ArrayElementListNode indices, TokenNode closingBrace) { var children = new List {cellArray, openingBrace, indices, closingBrace}; return new CellArrayElementAccessExpressionNode( children, cellArray, openingBrace, indices, closingBrace); } public FunctionCallExpressionNode FunctionCallExpression( ExpressionNode functionName, TokenNode openingBracket, FunctionCallParameterListNode parameters, TokenNode closingBracket) { var children = new List { functionName, openingBracket, parameters, closingBracket }; return new FunctionCallExpressionNode( children, functionName, openingBracket, parameters, closingBracket); } public FunctionCallParameterListNode FunctionCallParameterList(List nodes) { return new FunctionCallParameterListNode( nodes, nodes .OfType() .ToList()); } public ArrayElementListNode ArrayElementList(List nodes) { return new ArrayElementListNode( nodes, nodes .OfType() .ToList()); } public CompoundNameNode CompoundName(List nodes) { return new CompoundNameNode( nodes, nodes .OfType() .ToList()); } public ArrayLiteralExpressionNode ArrayLiteralExpression( TokenNode openingSquareBracket, ArrayElementListNode elements, TokenNode closingSquareBracket) { var children = new List { openingSquareBracket, elements, closingSquareBracket }; return new ArrayLiteralExpressionNode( children, openingSquareBracket, elements, closingSquareBracket); } public CellArrayLiteralExpressionNode CellArrayLiteralExpression( TokenNode openingBrace, ArrayElementListNode elements, TokenNode closingBrace) { var children = new List { openingBrace, elements, closingBrace }; return new CellArrayLiteralExpressionNode( children, openingBrace, elements, closingBrace); } public EmptyExpressionNode EmptyExpression() { return new EmptyExpressionNode(); } public MemberAccessNode MemberAccess( SyntaxNode leftOperand, TokenNode dot, SyntaxNode rightOperand) { var children = new List { leftOperand, dot, rightOperand }; return new MemberAccessNode( children, leftOperand, dot, rightOperand); } public WhileStatementNode WhileStatement( TokenNode whileKeyword, ExpressionNode condition, List optionalCommasAfterCondition, StatementListNode body, TokenNode end, TokenNode semicolonOrComma) { var children = new List { whileKeyword, condition, }; children.AddRange(optionalCommasAfterCondition); children.Add(body); children.Add(end); children.Add(semicolonOrComma); return new WhileStatementNode( RemoveNulls(children), whileKeyword, condition, optionalCommasAfterCondition, body, end, semicolonOrComma); } public StatementNode AppendSemicolonOrComma(StatementNode statement, TokenNode semicolonOrComma) { statement.SemicolonOrComma = semicolonOrComma; statement.Children.Add(semicolonOrComma); statement.Children[statement.Children.Count - 1].Parent = statement; return statement; } public IfStatementNode IfStatement( TokenNode ifKeyword, ExpressionNode condition, List optionalCommasAfterCondition, StatementListNode body, TokenNode elseKeyword, StatementListNode elseBody, TokenNode endKeyword, TokenNode possibleSemicolonOrComma) { var children = new List { ifKeyword, condition }; children.AddRange(optionalCommasAfterCondition); children.Add(body); children.Add(elseKeyword); children.Add(elseBody); children.Add(endKeyword); children.Add(possibleSemicolonOrComma); return new IfStatementNode( RemoveNulls(children), ifKeyword, condition, optionalCommasAfterCondition, body, elseKeyword, elseBody, endKeyword, possibleSemicolonOrComma); } public ParenthesizedExpressionNode ParenthesizedExpression( TokenNode openParen, ExpressionNode expression, TokenNode closeParen) { var children = new List { openParen, expression, closeParen }; return new ParenthesizedExpressionNode( children, openParen, expression, closeParen); } public ForStatementNode ForStatement( TokenNode forKeyword, AssignmentExpressionNode forAssignment, StatementListNode body, TokenNode endKeyword, List optionalCommasAfterAssignment) { var children = new List { forKeyword, forAssignment, }; children.AddRange(optionalCommasAfterAssignment); children.Add(body); children.Add(endKeyword); return new ForStatementNode( RemoveNulls(children), forKeyword, forAssignment, body, endKeyword, optionalCommasAfterAssignment); } public IndirectMemberAccessNode IndirectMemberAccess( TokenNode openingBracket, ExpressionNode indirectMemberName, TokenNode closingBracket) { var children = new List { openingBracket, indirectMemberName, closingBracket }; return new IndirectMemberAccessNode( children, openingBracket, indirectMemberName, closingBracket); } public NamedFunctionHandleNode NamedFunctionHandle( TokenNode atSign, CompoundNameNode functionName) { var children = new List { atSign, functionName }; return new NamedFunctionHandleNode( children, atSign, functionName); } public LambdaNode Lambda( TokenNode atSign, FunctionInputDescriptionNode input, ExpressionNode body) { var children = new List { atSign, input, body }; return new LambdaNode( children, atSign, input, body); } public TryCatchStatementNode TryCatchStatement( TokenNode tryKeyword, StatementListNode tryBody, TokenNode catchKeyword, StatementListNode catchBody, TokenNode endKeyword) { var children = new List { tryKeyword, tryBody, catchKeyword, catchBody, endKeyword }; return new TryCatchStatementNode( children, tryKeyword, tryBody, catchKeyword, catchBody, endKeyword); } public TryCatchStatementNode TryCatchStatement( TokenNode tryKeyword, StatementListNode tryBody, TokenNode endKeyword) { var children = new List { tryKeyword, tryBody, endKeyword }; return new TryCatchStatementNode( children, tryKeyword, tryBody, null, null, endKeyword); } public CommandExpressionNode CommandExpression( IdentifierNameNode identifierName, List arguments) { var children = new List { identifierName }; children.AddRange(arguments); return new CommandExpressionNode( children, identifierName, arguments); } public BaseClassInvokationNode BaseClassInvokation( IdentifierNameNode methodName, TokenNode atToken, ExpressionNode baseClassNameAndArguments) { var children = new List { methodName, atToken, baseClassNameAndArguments }; return new BaseClassInvokationNode( children, methodName, atToken, baseClassNameAndArguments); } } }