public override Node VisitStatements(MetaCodeParser.StatementsContext context)
 {
     return StatementFactory.Block(context.statement()
         .Select(statement => statement.Accept(this) as StatementNodeBase)
         .ToArray()
     );
 }
        public override Node VisitBlockStatement(MetaCodeParser.BlockStatementContext context)
        {
            var attributes = GetAttributes(context.attribute());
            var body = context.statement()
                              .Select(stmt => stmt.Accept(this) as StatementNodeBase)
                              .ToArray();

            return StatementFactory.Block(body, attributes);
        }
        public override Node VisitWhileStatement(MetaCodeParser.WhileStatementContext context)
        {
            var attributes = GetAttributes(context.attribute());
            var condition = context.ConditionExpression.Accept(this) as ExpressionNode;

            var body = context.Body.Accept(this) as StatementNodeBase;

            return StatementFactory.While(condition, body, attributes);
        }
        private Node VisitUnaryOperands(MetaCodeParser.ExpressionContext expression, IToken @operator)
        {
            if (new object[] { expression, @operator }.Any(value => value == null))
                return null;

            var expr = expression.Accept(this) as ExpressionNode;
            var op = @operator.Text;

            return ExpressionFactory.UnaryOperand(expr, op);
        }
        public override Node VisitArrayConstant(MetaCodeParser.ArrayConstantContext context)
        {
            var text = context.GetText();
            var expressions = context.expression()
                                     .Select(expression => expression.Accept(this))
                                     .OfType<ExpressionNode>()
                                     .ToArray();

            return ConstantLiteralFactory.Array(expressions);
        }
        public override Node VisitConstant(MetaCodeParser.ConstantContext context)
        {
            if (context.Null != null)
                return new NullConstantLiteralNode();

            return GetNodeFromContext(context.String,
                                      context.Number,
                                      context.Boolean,
                                      context.Array,
                                      context.Interval);
        }
        public override Node VisitExpression(MetaCodeParser.ExpressionContext context)
        {
            var result = GetNodeFromContext(
                context.PrimaryExpression,
                context.FunctionCallExpression,
                context.MacroCallExpression,
                context.MemberExpression) ??
                VisitBinaryOperands(context.Left, context.Right, context.Operator) ??
                VisitUnaryOperands(context.Expression, context.Operator);

            return result;
        }
        private Node VisitBinaryOperands(MetaCodeParser.ExpressionContext left, MetaCodeParser.ExpressionContext right,
            IToken @operator)
        {
            if (new object[] { left, right, @operator }.Any(obj => obj == null))
                return null;

            var leftExpression = left.Accept(this) as ExpressionNode;
            var rightExpression = right.Accept(this) as ExpressionNode;
            var operatorText = @operator.Text;

            return ExpressionFactory.BinaryOperand(leftExpression, rightExpression, operatorText);
        }
        public override Node VisitIfStatement(MetaCodeParser.IfStatementContext context)
        {
            var attributes = GetAttributes(context.attribute());
            var condition = context.Condition.Accept(this) as ExpressionNode;
            var statements = context.Statements.Accept(this) as BlockStatementNode;
            var elseIfStatements = context.elseIfStatement()
                                          .Select(elseIf => elseIf.Accept(this) as IfStatementNode)
                                          .ToArray();
            var elseStatements = context.ElseStatements.With(statement => statement.Accept(this)) as BlockStatementNode;

            return StatementFactory.IfThenElse(condition, statements, elseIfStatements, elseStatements, attributes);
        }
        public override Node VisitTypeName(MetaCodeParser.TypeNameContext context)
        {
            var attributes = context.attribute()
                                    .Select(attribute => attribute.Accept(this) as AttributeNode)
                                    .ToArray();

            var identifiers = context.ID()
                                     .Select(id => id.GetText())
                                     .ToArray();
            
            return ExpressionFactory.Type(string.Join(".", identifiers), attributes);
        }
 public override Node VisitStatement(MetaCodeParser.StatementContext context)
 {
     return GetNodeFromContext(
         context.Block,
         context.If,
         context.While,
         context.Foreach,
         context.Skip,
         context.VariableDeclaration,
         context.FunctionDeclaration,
         context.ObjectDeclaration,
         context.AttributeDeclaration,
         context.MacroDeclaration,
         context.Return
     ) ?? new ExpressionStatementNode(context.Expression.Accept(this) as ExpressionNode);
 }
        public override Node VisitFormalParameter(MetaCodeParser.FormalParameterContext context)
        {
            var parameterName = context.Name.Text;
            var typeName = context.Type.Accept(this) as TypeNameNode;
            var attributes = context.attribute()
                                    .Select(attribute => attribute.Accept(this) as AttributeNode)
                                    .ToArray();

            return StatementFactory.FormalParameter(parameterName, typeName, attributes);
        }
        public override Node VisitMacroCallExpression(MetaCodeParser.MacroCallExpressionContext context)
        {
            var macroName = context.macroName.Text;
            var statements = context.statement()
                                    .Select(statement => statement.Accept(this) as StatementNodeBase)
                                    .ToArray();

            return ExpressionFactory.MacroCall(macroName, statements);
        }
        public override Node VisitInit(MetaCodeParser.InitContext context)
        {
            var result = base.VisitInit(context) as BlockStatementNode;

            return StatementFactory.CompilationUnit(result);
        }
        public override Node VisitAttributeDeclaration(MetaCodeParser.AttributeDeclarationContext context)
        {
            var attributes = GetAttributes(context.attribute());
            var attributeName = context.AttributeName.Text;
            var parameters = context.formalParameter()
                                    .Select(parameter => parameter.Accept(this) as FormalParameterNode)
                                    .ToArray();

            return StatementFactory.Attribute(attributeName, parameters, attributes);
        }
 public override Node VisitStringConstant(MetaCodeParser.StringConstantContext context)
 {
     return new StringConstantLiteralNode(context.GetText().Trim('"').Trim('\''));
 }
        public override Node VisitReturnStatement(MetaCodeParser.ReturnStatementContext context)
        {
            var expression = context.ReturnExpression.Accept(this) as ExpressionNode;

            return StatementFactory.Return(expression);
        }
        public override Node VisitMacroFormalParameter(MetaCodeParser.MacroFormalParameterContext context)
        {
            var identifier = context.Name.Text;
            var treeSelector = context.Selector.Text;

            return new MacroFormalParameterNode(identifier, treeSelector);
        }
 public override Node VisitSkipStatement(MetaCodeParser.SkipStatementContext context)
 {
     return StatementFactory.Skip();
 }
 public override Node VisitElseIfStatement(MetaCodeParser.ElseIfStatementContext context)
 {
     var condition = context.Condition.Accept(this) as ExpressionNode;
     var statements = context.Statements.Accept(this) as BlockStatementNode;
     return StatementFactory.IfThenElse(condition, statements, new AttributeNode[0]);
 }
        /*public override Node VisitFunctionExpression(MetaCodeParser.FunctionExpressionContext context)
        {
            var identifier = context.FunctionName.With(functionName => functionName.Text);
            var returnType = context.ReturnType.Accept(this) as TypeNameNode;

            var parameters = context.Parameters;

            var formalParameters = new Func<FormalParameterNode[]>(() => {
                if (parameters == null)
                    return new FormalParameterNode[0];

                var result = parameters.formalParameter().Select(param => {
                    return ExpressionFactory.FormalParameter(param.Identifier.Text,
                        param.VariableType.With(type => type.Accept(this) as TypeNameNode),
                        null);
                });

                return result.ToArray();
            })();

            if (context.BodyExpression != null)
                return ExpressionFactory.Function(identifier,
                                                  returnType.VariableType,
                                                  formalParameters,
                                                  new Lazy<ExpressionNode>(() => context.BodyExpression.Accept(this) as ExpressionNode));

            return ExpressionFactory.Function(identifier,
                                              returnType.VariableType,
                                              formalParameters,
                                              new Lazy<BlockStatementNode>(() => context.BodyStatements.Accept(this) as BlockStatementNode));
        }*/

        public override Node VisitPrimaryExpression(MetaCodeParser.PrimaryExpressionContext context)
        {
            var attributes = context.attribute()
                                    .Select(attribute => attribute.Accept(this) as AttributeNode)
                                    .ToArray();

            if (context.Constant != null)
            {
                var constant = context.Constant.Accept(this) as ConstantLiteralNode;
                return ExpressionFactory.Constant(constant, attributes);
            }

            if (context.Id != null)
                return ExpressionFactory.Identifier(context.Id.Text, attributes);

            if (context.Assignment != null)
            {
                var assignment = context.Assignment;
                var member = assignment.LeftValue.With(leftValue => leftValue.Accept(this) as MemberExpressionNode) ??
                             ExpressionFactory.Member(new[] { assignment.VariableName.Text });

                var value = assignment.RightValue.Accept(this) as ExpressionNode;

                return ExpressionFactory.Assignment(member, value, attributes);
            }

            if (context.InnerExpression != null)
                return ExpressionFactory.InnerExpression(context.InnerExpression.Accept(this) as ExpressionNode, attributes);

            return base.VisitPrimaryExpression(context);
        }
        public override Node VisitFunctionStatement(MetaCodeParser.FunctionStatementContext context)
        {
            var attributes = GetAttributes(context.attribute());

            var functionName = context.FunctionName.Text;
            var returnType = context.ReturnType.With(type => type.Accept(this) as TypeNameNode);
            var parameters = context.formalParameter()
                                    .Select(parameter => parameter.Accept(this) as FormalParameterNode)
                                    .ToArray();
            var body = context.BodyStatements.Accept(this) as BlockStatementNode;

            return StatementFactory.Function(functionName, returnType, parameters, body, attributes);
        }
        public override Node VisitNumberConstant(MetaCodeParser.NumberConstantContext context)
        {
            var text = context.GetText();

            return ConstantLiteralFactory.Number(text);
        }
        public override Node VisitMemberExpression(MetaCodeParser.MemberExpressionContext context)
        {
            var ids = context.ID().Select(id => id.GetText()).ToArray();

            return ExpressionFactory.Member(ids);
        }
        public override Node VisitBooleanConstant(MetaCodeParser.BooleanConstantContext context)
        {
            var text = context.GetText();

            return ConstantLiteralFactory.Logical(text);
        }
        public override Node VisitFunctionCallExpression(MetaCodeParser.FunctionCallExpressionContext context)
        {
            var functionName = context.functionName.Text;
            var expressions = context.expression()
                                     .Select(expression => expression.Accept(this) as ExpressionNode)
                                     .ToArray();


            return ExpressionFactory.FunctionCall(functionName, expressions);
        }
        public override Node VisitForeachStatement(MetaCodeParser.ForeachStatementContext context)
        {
            var attributes = GetAttributes(context.attribute());
            var identifier = context.Id.Text;
            var arrayExpression = context.ArrayExpression.Accept(this) as ExpressionNode;
            var variableType = context.VariableType.With(variable => variable.Accept(this)) as TypeNameNode;

            return StatementFactory.Foreach(identifier,
                                            variableType,
                                            arrayExpression,
                                            context.Body.Accept(this) as StatementNodeBase,
                                            attributes);
        }
        public override Node VisitMacroStatement(MetaCodeParser.MacroStatementContext context)
        {
            var identifier = context.MacroName.Text;
            var body = context.BodyStatements.Accept(this) as BlockStatementNode;

            var parameters = context.macroFormalParameter()
                                    .Select(param => param.Accept(this) as MacroFormalParameterNode)
                                    .ToArray();

            //var type = context.Type.Text == "implicit" ? MacroType.Implicit : MacroType.Explicit;

            return StatementFactory.Macro(identifier, parameters, body, MacroType.Implicit);
        }
        public override Node VisitAttribute(MetaCodeParser.AttributeContext context)
        {
            var name = context.Name.Text;
            var expressions = context.expression()
                                     .Select(expression => expression.Accept(this) as ExpressionNode)
                                     .ToArray();

            return ConstantLiteralFactory.Attribute(name, expressions);
        }
        public override Node VisitVariableDeclaration(MetaCodeParser.VariableDeclarationContext context)
        {
            var attributes = GetAttributes(context.attribute());
            var name = context.VariableName.Text;
            var typeName = context.VariableType.With(variable => variable.Accept(this)) as TypeNameNode;
            var defaultValue = context.VariableDefaultValue.With(expression => expression.Accept(this)) as ExpressionNode;

            return StatementFactory.DeclareVariable(name, typeName, defaultValue, attributes);
        }