// возвращает ExpressionStatement
        public override object VisitExpressionStatement([NotNull] DoshikParser.ExpressionStatementContext context)
        {
            _compilationContext.SetParsingAntlrContext(context);

            var statement = new ExpressionStatement(_currentNode);

            statement.Expression = ExpressionCreationVisitor.Apply(_compilationContext, statement, context.expression());

            return(statement);
        }
        private static ExpressionTree ApplyToParseTree(CompilationContext compilationContext, ICodeHierarchyNode expressionParent, Antlr4.Runtime.Tree.IParseTree antlrContext)
        {
            compilationContext.PushParsingContext();

            var visitor = new ExpressionCreationVisitor(compilationContext);

            visitor.Visit(antlrContext);

            compilationContext.SetParsingAntlrContext(null);

            var result = new ExpressionBuilder().Build(compilationContext, expressionParent, visitor.Sequence, visitor.WholeExpressonAntlrContext);

            compilationContext.PopParsingContext();

            return(result);
        }
        // Возвращает ExpressionTree
        public override object VisitVariableInitializer([NotNull] DoshikParser.VariableInitializerContext context)
        {
            _compilationContext.SetParsingAntlrContext(context);

            var expressionCtx = context.expression();

            if (expressionCtx != null)
            {
                var expressionTree = ExpressionCreationVisitor.Apply(_compilationContext, _currentExpressionParent, expressionCtx);

                if (_declaringVariable.Type != expressionTree.RootExpression.ReturnOutputSlot.Type)
                {
                    throw _compilationContext.ThrowCompilationError("declaring variable type differs from initialization expression return type");
                }

                return(expressionTree);
            }
            else
            {
                throw _compilationContext.ThrowCompilationError("variables can only be initialized using expressions (no special initializer support yet)");
            }
        }
        public override object VisitWhileLoopStatement([NotNull] DoshikParser.WhileLoopStatementContext context)
        {
            _compilationContext.SetParsingAntlrContext(context);

            var statement = new WhileStatement(_currentNode);

            _currentExpressionParent = statement;

            statement.Condition = ExpressionCreationVisitor.Apply(_compilationContext, _currentExpressionParent, context.condition);

            if (statement.Condition.RootExpression.ReturnOutputSlot.Type != _compilationContext.TypeLibrary.FindByKnownType(KnownType.Boolean))
            {
                throw _compilationContext.ThrowCompilationError("condition must evaluate to bool value");
            }

            _isInLoopCounter++;

            statement.BodyStatement = (Statement)Visit(context.body);

            _isInLoopCounter--;

            return(statement);
        }
        // возвращает Statement (IfStatement)
        public override object VisitIfStatement([NotNull] DoshikParser.IfStatementContext context)
        {
            _compilationContext.SetParsingAntlrContext(context);

            var statement = new IfStatement(_currentNode);

            _currentExpressionParent = statement;

            statement.Condition = ExpressionCreationVisitor.Apply(_compilationContext, _currentExpressionParent, context.condition);

            if (statement.Condition.RootExpression.ReturnOutputSlot.Type != _compilationContext.TypeLibrary.FindByKnownType(KnownType.Boolean))
            {
                throw _compilationContext.ThrowCompilationError("condition must evaluate to bool value");
            }

            statement.TrueStatement = (Statement)Visit(context.trueBody);

            if (context.falseBody != null)
            {
                statement.FalseStatement = (Statement)Visit(context.falseBody);
            }

            return(statement);
        }