/// <summary> /// Следующий шаг выполнения проги /// </summary> private void btn_step() { try { this.btn_first_run.Enabled = false; this.btn_refresh_all.Enabled = true; // если исходный текст пуст if (program.sourceCode.entities.Count == 0) { throw new SPException("Исходный текст должен содержать хотя бы одну строку"); } if (program.index == 0) { tb_error.Clear(); } // если это последняя строка if ((program.index + 1) == program.sourceCode.entities.Count) { //this.btn_next_step.Enabled = false; CheckSourceEntity.checkEND(new SourceEntity(), false, ""); } this.program.nextFirstStep(this.tb_result); TMO.printTMO(this.dgv_tmo); Global.printGlobal(this.dgv_global); } catch (SPException ex) { this.tb_error.Text = ex.Message; this.disableButtons(); this.btn_refresh_all.Enabled = true; } catch (Exception) { this.tb_error.Text = "Ошибка!"; this.disableButtons(); this.btn_refresh_all.Enabled = true; } }
/// <summary> /// Шаг первого прохода /// </summary> public void firstRunStep(SourceEntity se, TMOEntity te) { String operation = se.operation; String label = se.label; List <String> operands = se.operands; try { CheckSourceEntity.checkLabel(se); if (operation == "END") { CheckSourceEntity.checkEND(se, this.macroFlag, this.macroName); result.Add(Utils.print(se)); } else if (operation == "GLOBAL" && this.macroFlag == false) { CheckSourceEntity.checkGLOBAL(se); if (operands.Count == 1) { Global.entities.Add(new GlobalEntity(operands[0], null)); } else { Global.entities.Add(new GlobalEntity(operands[0], Int32.Parse(operands[1]))); } } else if (operation == "SET" && this.macroFlag == false) { CheckSourceEntity.checkSET(se, te); Global.searchInGlobal(se.operands[0]).value = Int32.Parse(se.operands[1]); } else if (operation == "INC" && this.macroFlag == false) { CheckSourceEntity.checkINC(se, te); Global.searchInGlobal(operands[0]).value++; } else if (operation == "MACRO") { if (te != TMO.root) { throw new SPException("Макроопределения внутри макросов запрещены"); } CheckSourceEntity.checkMACRO(se, macroFlag); TMO.entities.Add(new TMOEntity() { name = label, parameters = se.operands }); this.macroFlag = true; this.macroName = label; } else if (operation == "MEND") { if (te != TMO.root) { throw new SPException("Макроопределения внутри макросов запрещены"); } CheckSourceEntity.checkMEND(se, macroFlag); foreach (SourceEntity mc in mbMacroCall) { if (mc.operation == this.macroName) { TMOEntity currentTe = TMO.searchInTMO(this.macroName); CheckSourceEntity.checkMacroSubstitution(mc, currentTe); List <SourceEntity> res = CheckBody.checkMacroBody(currentTe, operands); // результат макроподстановки List <SourceEntity> macroSubs = new List <SourceEntity>(); foreach (SourceEntity str in res) { macroSubs.Add(Utils.print(str)); } // Заменяем в результате макровызов на результат макроподстановки for (int i = 0; i < this.result.Count; i++) { if (this.result[i].operation == mc.operation && this.result[i].isRemove == "true") { this.result.Remove(this.result[i]); this.result.InsertRange(i, macroSubs); i += macroSubs.Count - 1; } } } } TMOEntity curTe = TMO.searchInTMO(this.macroName); curTe.IsFinished = true; var prevTe = TMO.GetPrevNotFinishedMacro(); if (prevTe != null) { this.macroFlag = true; this.macroName = prevTe.name; } else { this.macroFlag = false; this.macroName = null; } } else { if (this.macroFlag == true) { TMO.searchInTMO(this.macroName).body.Add(se); } else { if (te == TMO.root && (operation == "WHILE" || operation == "ENDW")) { throw new SPException("Использование директивы " + operation + " возможно только в теле макроса: " + se.sourceString); } // макровызов if (TMO.isInTMO(operation)) { TMOEntity currentTe = TMO.searchInTMO(operation); CheckSourceEntity.checkMacroSubstitution(se, currentTe); CheckBody.checkMacroRun(se, te, currentTe); List <SourceEntity> res = CheckBody.checkMacroBody(currentTe, operands); foreach (SourceEntity str in res) { result.Add(Utils.print(str)); } //if (te == TMO.root) //{ //} //else //{ // throw new SPException("Макровызовы внутри макроса запрещены"); //} } else { // Добавляем строку в список подозрительных на макровызов и в результат se = Utils.print(se); if (te == TMO.root && macroFlag == false) { se.isRemove = "true"; mbMacroCall.Add(se); } result.Add(se); } } } } catch (SPException ex) { throw new SPException(ex.Message); } }