コード例 #1
0
        private void ProcessAssignments(CLanguageParser.FunctionDefinitionContext context, int index)
        {
            List <RelationalExpression> conditionRelations       = _relationService.GetConditionRelations(context);
            List <RelationalExpression> assignmentRelations      = _relationService.GetAssignmentRelations(context);
            List <RelationalExpression> initDeclarationRelations = _relationService.GetInitializationRelations(context);
            List <string> nullCheckOperands = conditionRelations
                                              .Select(x => x.RightOperand == NULL_TOKEN ? x.LeftOperand : (x.LeftOperand == NULL_TOKEN ? x.RightOperand : null))
                                              .Where(x => x != null)
                                              .ToList();
            //todo: this is not right: tail = head->next; if a check is made for head
            //todo: further reconsider this: in the case of a "check null and return", further assignments can be replaced with old* correspondents
            //assignmentRelations
            //    .RemoveAll(x => nullCheckOperands.Any(op => x.LeftOperand.ContainsInvariant($"{op}{POINTER_ACCESS_MARKER}") ||
            //                                                x.RightOperand.ContainsInvariant($"{op}{POINTER_ACCESS_MARKER}")));
            var relations = new List <RelationalExpression>();

            relations.AddRange(conditionRelations);
            relations.AddRange(assignmentRelations);

            string variablesSnapshot = GetVariablesSnapshot(relations);
            string snapshotFlagCheck = GetSnapshotsFlagCheckExpression(relations);

            //todo: fix indenting
            //var indent = index - CodeInput.Substring(0, index).InvariantLastIndexOf(Environment.NewLine);
            InsertionDeclaration snapshotAndCheckInsertion = new InsertionDeclaration(index + 1, $"{variablesSnapshot}{Environment.NewLine}{snapshotFlagCheck}".Indent(51));
            List <IDeclaration>  conditionReplacements     = GetConditionReplacements(conditionRelations);
            List <IDeclaration>  assignmentReplacements    = GetCasAssignmentsReplacements(assignmentRelations);
            List <IDeclaration>  initReplacements          = GetInitDeclarationsReplacements(initDeclarationRelations);

            _updateTable.Add(snapshotAndCheckInsertion);
            conditionReplacements.ForEach(_updateTable.Add);
            assignmentReplacements.ForEach(_updateTable.Add);
            initReplacements.ForEach(_updateTable.Add);
        }
コード例 #2
0
        public override object VisitFunctionDefinition(CLanguageParser.FunctionDefinitionContext context)
        {
            var index = AddWhileLoop(context);

            ProcessAssignments(context, index);

            return(base.VisitFunctionDefinition(context));
        }
コード例 #3
0
        public List <RelationalExpression> GetInitializationRelations(CLanguageParser.FunctionDefinitionContext context)
        {
            var relations = context
                            .GetDescendants <CLanguageParser.InitDeclaratorContext>()
                            .Where(x => x.ChildCount > 1)
                            .Select(GetRelationalExpression)
                            .ToList();

            return(relations);
        }
コード例 #4
0
        /// <summary>
        /// Adds the "while loop for this method and returns the "while" loop insertion index.
        /// </summary>
        private int AddWhileLoop(CLanguageParser.FunctionDefinitionContext context)
        {
            int    insertionIndex = int.MaxValue;
            string operationName  = context.GetFirstDescendant <CLanguageParser.DirectDeclaratorContext>().GetName();

            var localVariables = _dataStructure[operationName]
                                 .LocalVariables
                                 .OrderBy(x => x.Index)
                                 .ToList();
            var variable = localVariables
                           .Skip(1) //todo:why??
                           .Select((var, ix) => new { Variable = var, Index = ix })
                           .FirstOrDefault(x => x.Variable.LinksToGlobalState);

            if (variable != null)
            {
                insertionIndex = localVariables[variable.Index].Index;
            }

            var    bodyContext           = context.compoundStatement();
            string body                  = bodyContext.GetContextText();
            var    globalVariableIndexes = _dataStructure
                                           .GlobalVariables
                                           .Select(x => new Regex($"[^a-zA-Z\\d:]{x.Name}[^a-zA-Z\\d:]"))
                                           .Select(x => x.IsMatch(body) ? x.Match(body).Index : -1)
                                           .Where(x => x > 0)
                                           .Select(x => x + bodyContext.GetStartIndex());

            // If there is a global variable, we take the minimum between that index and the local variable that links to global state
            insertionIndex = Math.Min(insertionIndex, globalVariableIndexes.Any() ? globalVariableIndexes.Min() : insertionIndex);
            Method method = _dataStructure[operationName];

            // If the local or global variable is embedded in an "if" statement, we will embed the "if" statement in the "while" loop as well
            if (method.IfStatements.Any())
            {
                var index = insertionIndex;
                var surroundingIfStatements = method.IfStatements.Where(x => x.Context.ContainsIndex(index));

                if (surroundingIfStatements.Any())
                {
                    insertionIndex = Math.Min(insertionIndex, surroundingIfStatements.Min(x => x.StartIndex));
                }
            }

            string trimmedBody = body.Substring(0, insertionIndex - bodyContext.GetStartIndex());

            insertionIndex = trimmedBody.InvariantLastIndexOf(Environment.NewLine) + bodyContext.GetStartIndex() + 2;
            int offset = trimmedBody.Length - trimmedBody.InvariantLastIndexOf(Environment.NewLine) - 2;

            _updateTable.Add(new InsertionDeclaration(insertionIndex, new string(' ', offset) + "while (true) {"));
            _updateTable.Add(new InsertionDeclaration(context.GetStopIndex() - 1, "}"));

            return(insertionIndex);
        }
コード例 #5
0
        public List <RelationalExpression> GetConditionRelations(CLanguageParser.FunctionDefinitionContext context)
        {
            var relations = context
                            .GetDescendants <CLanguageParser.SelectionStatementContext>()
                            .SelectMany(x => x.expression().GetLeafDescendants <CLanguageParser.EqualityExpressionContext>())
                            .Select(x => (object)x.Parent)
                            .Select(GetRelationalExpression)
                            .ToList();

            return(relations);
        }
コード例 #6
0
        public override object VisitFunctionDefinition(CLanguageParser.FunctionDefinitionContext context)
        {
            string functionName = context.GetFirstDescendant <CLanguageParser.DirectDeclaratorContext>().GetName();
            var    bodyContext  = context.compoundStatement();
            var    operation    = new Method(functionName)
            {
                StartIndex = bodyContext.Start.StartIndex,
                EndIndex   = bodyContext.Stop.StopIndex,
                Context    = bodyContext
            };

            DataStructure.AddOperation(operation);

            return(base.VisitFunctionDefinition(context));
        }
コード例 #7
0
        public List <RelationalExpression> GetAssignmentRelations(CLanguageParser.FunctionDefinitionContext context)
        {
            var relations = context
                            .GetDescendants <CLanguageParser.AssignmentExpressionContext>()
                            .Where(x => x.ChildCount > 1)
                            .Select(GetRelationalExpression)
                            .ToList();

            foreach (var relation in relations)
            {
                //todo: this is incorrect since we need to track only those relations from the root to this relation;
                //todo "if (condition) {1} else {2;3}" => for relation "3" we don't track relation "1"
                relation.PreviousRelations = relations
                                             .Where(x => x.LeftOperandSnapshot != null || x.RightOperandSnapshot != null)
                                             .Where(x => x.RightOperandInterval.End <= relation.LeftOperandInterval.Start)
                                             .ToList();
            }

            return(relations);
        }