/// <summary> /// Заменяет команды #START, #STOP /// </summary> protected void ReplaceStartStopProcessCommands(StringBuilder Code) { for (int j = 0; j < 2; j++) { string pattern = (j == 0) ? @"/\*(\d+)\*/.*(#STARTp(\d+))" : @"/\*(\d+)\*/.*(#STOPp(\d+))"; do { MatchCollection mc = Regex.Matches(Code.ToString(), pattern); int k = 0; for (int i = 0; i < mc.Count; i++) { int LineNumber = int.Parse(mc[i].Groups[1].Value); RelkonCodeProcess p = this.codeModel.GetProcessByIndex(int.Parse(mc[i].Groups[3].Value)); string s = ""; if (p != null) { s = (j == 0) ? this.GetStartProcessCode(p) : this.GetStopProcessCode(p); } else { this.errors.Add(new CompilationError("Указаного процесса не существует", this.codeModel.FileName, LineNumber, false)); } string RelkonCode = mc[i].Groups[2].Value; Code.Replace(RelkonCode, s, mc[i].Groups[2].Index + k, RelkonCode.Length); k += s.Length - RelkonCode.Length; } }while (Regex.IsMatch(Code.ToString(), pattern)); } }
/// <summary> /// Заменяет команды перехода (#\s2, #\0.1\s2 и т.д.) /// </summary> /// <param name="Process">Процесс, ситуации которого рассматриваются</param> protected void ReplaceJumpSituationCommand(StringBuilder Code, RelkonCodeProcess Process) { string pattern = @"/\*(\d+)\*/.*(#(?:/(\d+\.\d+))?/s(\d+))"; do { int k = 0; MatchCollection mc = Regex.Matches(Code.ToString(), pattern); for (int i = 0; i < mc.Count; i++) { int LineNumber = int.Parse(mc[i].Groups[1].Value); string RelkonCode = mc[i].Groups[2].Value; uint delay = (mc[i].Groups[3].Value != "") ? (uint)(double.Parse(mc[i].Groups[3].Value, NumberFormatInfo.InvariantInfo) * 1000) : 0; string s = ""; if (this.ValidateDelayInterval(delay, LineNumber)) { RelkonCodeSituation Situation = Process.GetSituationByIndex(int.Parse(mc[i].Groups[4].Value)); if (Situation != null) { s = this.GetJumpToSituationCode(Process, Situation, delay); } else { this.errors.Add(new CompilationError("Указанной ситуации не существует", this.codeModel.FileName, LineNumber, false)); } } Code.Replace(RelkonCode, s, mc[i].Groups[2].Index + k, RelkonCode.Length); k += s.Length - RelkonCode.Length; } }while (Regex.IsMatch(Code.ToString(), @"#(?:/(\d+\.\d+))?/s(\d+)")); }
/// <summary> /// Генерирует код ситуации на основе исходного кода Relkon (заменяет команды Relkon /// на команды C /// </summary> /// <param name="Situation">Ситуация, чей код генерируется</param> /// <param name="Process">Процесс, к которому относится ситуация</param> private void GenerateSituationCode(RelkonCodeProcess Process, RelkonCodeSituation Situation, IndentedTextWriter CodeWriter) { StringBuilder code = new StringBuilder(Situation.Code); this.ReplaceIO(code); this.ReplaceStartStopProcessCommands(code); this.ReplaceJumpSituationCommand(code, Process); this.ReplaceRestartSituationCommands(code, Process); this.PerfomCustomReplacing(code); CodeWriter.Write(code.ToString()); }
/// <summary> /// Заменяет команды перехода (#\s2, #\0.1\s2 и т.д.); /// </summary> /// <param name="Process">Процесс, ситуации которого рассматриваются</param> protected virtual void ReplaceRestartSituationCommands(StringBuilder Code, RelkonCodeProcess Process) { string pattern = @"/\*(\d+)\*/.*(#(?:/(\d+\.\d+))?/R)"; do { int k = 0; MatchCollection mc = Regex.Matches(Code.ToString(), pattern); for (int i = 0; i < mc.Count; i++) { int LineNumber = int.Parse(mc[i].Groups[1].Value); string RelkonCode = mc[i].Groups[2].Value; uint delay = (mc[i].Groups[3].Value != "") ? (uint)(double.Parse(mc[i].Groups[3].Value, NumberFormatInfo.InvariantInfo) * 1000) : 0; string s = ""; if (this.ValidateDelayInterval(delay, LineNumber)) { s = this.GetRestartSituationCode(Process, delay); } Code.Replace(RelkonCode, s, mc[i].Groups[2].Index + k, RelkonCode.Length); k += s.Length - RelkonCode.Length; } }while (Regex.IsMatch(Code.ToString(), pattern)); }
/// <summary> /// Создает код запуска нового цикла ситуации /// </summary> /// <param name="Process">Процесс, в котором осуществляется работа</param> /// <param name="Delay">Задержка в мс перед запуском нового цикла</param> protected abstract string GetRestartSituationCode(RelkonCodeProcess Process, uint Delay);
/// <summary> /// Создает код операции перехода на другую ситуацию /// </summary> /// <param name="Process">Процесс, в котором осуществляется работа</param> /// <param name="Situation">Ситуация, на которую осуществляется переход</param> /// <param name="Delay">Задержка в мс перед переходом</param> protected abstract string GetJumpToSituationCode(RelkonCodeProcess Process, RelkonCodeSituation Situation, uint Delay);
/// <summary> /// Возвращает код остановки процесса /// </summary> protected virtual string GetStopProcessCode(RelkonCodeProcess Process) { return(this.GetProcessName(Process) + ".W = empty"); }
/// <summary> /// Возвращает код запуска процесса /// </summary> protected abstract string GetStartProcessCode(RelkonCodeProcess Process);
/// <summary> /// Возвращает имя функции ситуации /// </summary> protected abstract string GetSituationName(RelkonCodeProcess Process, RelkonCodeSituation Situation);
/// <summary> /// Возвращает имя переменной процесса /// </summary> protected abstract string GetProcessName(RelkonCodeProcess Process);
protected override string GetProcessName(RelkonCodeProcess Process) { return("_Sys4x_p" + Process.Index); }
protected override string GetSituationName(RelkonCodeProcess Process, RelkonCodeSituation Situation) { throw new NotImplementedException(); }