/// <summary> /// Extracts the constant from a condition /// </summary> /// <returns>The extracted variable</returns> public int?GetConstFromCondition() { Validate(); System.Collections.Specialized.StringCollection refvarIDs = new System.Collections.Specialized.StringCollection(); Match matchResult = Regex.Match(TACtext, "ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}", RegexOptions.None); while (matchResult.Success) { refvarIDs.Add(matchResult.Value); matchResult = matchResult.NextMatch(); } if (refvarIDs.Count == 3) { return(null); } else { return(Convert.ToInt32(TACtext.Split(' ')[3])); } }
/// <summary> /// Modifies the TAC text of instruction: replaces numerical constant to variable name /// </summary> /// <param name="variable">Variable containing constant</param> /// <param name="value">Constant number to be replaced</param> public void ModifyConstInstruction(Variable variable, int?value) { if (variable == null || value == null) { throw new ObjectException("Wrong parameter passing."); } RefVariables.Add(variable); string TACtext_new = string.Empty; for (int i = 0; i < TACtext.Split(' ').Length; i++) { if (TACtext.Split(' ')[i] != value.ToString()) { TACtext_new = string.Join(" ", TACtext_new, TACtext.Split(' ')[i]); } else { TACtext_new = string.Join(" ", TACtext_new, variable.name); } } TACtext = TACtext_new.Trim(); }
/// <summary> /// Determines the new state of a dead variable (a pointer) as a result of the instruction /// </summary> /// <param name="variable">A variable or a pointer</param> /// <returns>A list of states. For variable: 1 - variable, 2 - empty. For pointer: 1-pointer, 2 - variable. Empty list if nothing has changed.</returns> public List <Variable.State> GetChangedStates(Variable variable) { if (string.IsNullOrWhiteSpace(TACtext)) { throw new ObjectException("TAC text is empty. Instruction: " + ID); } if (RefVariables.Count == 0 || !RefVariables.Contains(variable)) { throw new ObjectException("No referenced variables found in instruction " + ID); } List <Variable.State> var_states = new List <Variable.State>(); string right = string.Empty, left = string.Empty; if (TACtext.Split('=').Length == 2) { right = TACtext.Split('=')[1]; left = TACtext.Split('=')[0]; } switch (statementType) { case Common.StatementType.FullAssignment: case Common.StatementType.UnaryAssignment: case Common.StatementType.Copy: if (Regex.IsMatch(right, variable.ID, RegexOptions.None) && !Regex.IsMatch(left, variable.ID, RegexOptions.None)) { var_states.Add(Variable.State.Free); } else if (Regex.IsMatch(left, variable.ID, RegexOptions.None)) { var_states.Add(Variable.State.Filled); } break; case Common.StatementType.ConditionalJump: var_states.Add(Variable.State.Free); break; case Common.StatementType.PointerAssignment: if (left.Contains("&")) { throw new ObjectException("Instruction type '&a=p' is not supported. Please use 'p=&a' instead."); } else if (right.Contains("&")) { // Nothing changed if (Regex.IsMatch(right, variable.ID, RegexOptions.None) && !variable.pointer) { break; } // Pointer is filled else if (Regex.IsMatch(left, variable.ID, RegexOptions.None) && variable.pointer) { var_states.Add(Variable.State.Filled); } else { throw new ObjectException("GetChangedStates could not parse 'p=&a' instruction type. Possible errors: 'a' is a poiner; 'p' is not a pointer; incorrect TAC text."); } } else if (left.Contains("*")) { // Variable state is free if (Regex.IsMatch(right, variable.ID, RegexOptions.None) && !variable.pointer) { var_states.Add(Variable.State.Free); } // Pointer is free, variable is filled else if (Regex.IsMatch(left, variable.ID, RegexOptions.None) && variable.pointer) { var_states.Add(Variable.State.Free); var_states.Add(Variable.State.Filled); } else { throw new ObjectException("GetChangedStates could not parse '*p=a' instruction type. Possible error: 'a' is a poiner or 'p' is not a pointer; incorrect TAC text."); } } else if (right.Contains("*")) { // Pointer is free, variable is free if (Regex.IsMatch(right, variable.ID, RegexOptions.None) && variable.pointer) { var_states.Add(Variable.State.Free); var_states.Add(Variable.State.Free); } // Variable is filled else if (Regex.IsMatch(left, variable.ID, RegexOptions.None) && !variable.pointer) { var_states.Add(Variable.State.Filled); } else { throw new ObjectException("GetChangedStates could not parse 'a=*p' instruction type. Possible error: 'a' is a poiner or 'p' is not a pointer; incorrect TAC text."); } } else { throw new ObjectException("GetChangedStates: problem in parsing TAC text of PointerAssignment instruction type. Instruction: " + ID); } break; case Common.StatementType.IndexedAssignment: throw new ObjectException("This statement type is not supported."); case Common.StatementType.Procedural: if (variable.pointer) { throw new ObjectException("GetChangedStates: pointers are not supported in Procedural instruction type."); } else if ((Regex.IsMatch(TACtext, "param", RegexOptions.None) || Regex.IsMatch(TACtext, "return", RegexOptions.None)) && Regex.IsMatch(TACtext, RefVariables[0].ID, RegexOptions.None)) { var_states.Add(Variable.State.Free); } else if (Regex.IsMatch(TACtext, "retrieve", RegexOptions.None) && Regex.IsMatch(TACtext, RefVariables[0].ID, RegexOptions.None)) { var_states.Add(Variable.State.Filled); } break; case Common.StatementType.UnconditionalJump: case Common.StatementType.NoOperation: default: throw new ObjectException("This statement type cannot change states of 'dead' variables."); } return(var_states); }