/// <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); }
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)); }