123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Windows.Forms;
- using NTERA.Core;
- using NTERA.EmuEra.Game.EraEmu.Config;
- using NTERA.EmuEra.Game.EraEmu.Content;
- using NTERA.EmuEra.Game.EraEmu.GameData;
- using NTERA.EmuEra.Game.EraEmu.GameData.Expression;
- using NTERA.EmuEra.Game.EraEmu.GameData.Function;
- using NTERA.EmuEra.Game.EraEmu.GameData.Variable;
- using NTERA.EmuEra.Game.EraEmu.GameProc.Function;
- using NTERA.EmuEra.Game.EraEmu.Sub;
- namespace NTERA.EmuEra.Game.EraEmu.GameProc
- {
- internal sealed partial class Process
- {
- public Process(IConsole view)
- {
- console = view;
- }
- public LogicalLine getCurrentLine => state.CurrentLine;
- /// <summary>
- /// @~~と$~~を集めたもの。CALL命令などで使う
- /// 実行順序はLogicalLine自身が保持する。
- /// </summary>
- LabelDictionary labelDic;
- public LabelDictionary LabelDictionary => labelDic;
- /// <summary>
- /// 変数全部。スクリプト中で必要になる変数は(ユーザーが直接触れないものも含め)この中にいれる
- /// </summary>
- private VariableEvaluator vEvaluator;
- public VariableEvaluator VEvaluator => vEvaluator;
- private ExpressionMediator exm;
- private GameBase gamebase;
- readonly IConsole console;
- private IdentifierDictionary idDic;
- ProcessState state;
- ProcessState originalState;//リセットする時のために
- bool noError;
- //色々あって復活させてみる
- bool initialiing;
- public bool inInitializeing => initialiing;
- public bool Initialize()
- {
- LexicalAnalyzer.UseMacro = false;
- state = new ProcessState(console);
- originalState = state;
- initialiing = true;
- #if !DEBUG
- try
- {
- #endif
- ParserMediator.Initialize(console);
- if (ParserMediator.HasWarning)
- {
- ParserMediator.FlushWarningList();
- if(MessageBox.Show("There is a problem with the config file.\nWould you like to close Emuera?","Config Error", MessageBoxButtons.YesNo)
- == DialogResult.Yes)
- {
- console.PrintSystemLine("Processing was terminated because there was a problem with the config file and exit was selected");
- return false;
- }
- }
- AppContents.LoadContents();
-
- if (Config.Config.UseKeyMacro && !Program.AnalysisMode)
- {
- if (File.Exists(Program.ExeDir + "macro.txt"))
- {
- if (Config.Config.DisplayReport)
- console.PrintSystemLine("Loading macro.txt...");
- KeyMacro.LoadMacroFile(Program.ExeDir + "macro.txt");
- }
- }
- if (Config.Config.UseReplaceFile && !Program.AnalysisMode)
- {
- if (File.Exists(Program.CsvDir + "_Replace.csv"))
- {
- if (Config.Config.DisplayReport)
- console.PrintSystemLine("Loading _Replace.csv...");
- ConfigData.Instance.LoadReplaceFile(Program.CsvDir + "_Replace.csv");
- if (ParserMediator.HasWarning)
- {
- ParserMediator.FlushWarningList();
- if (MessageBox.Show("Abnormality is found in _Replace.csv.\nWould you like to close Emuera?", "_Replace.csv Error", MessageBoxButtons.YesNo)
- == DialogResult.Yes)
- {
- console.PrintSystemLine("Processing was terminated because _Replace.csv file had an error and exit was selected");
- return false;
- }
- }
- }
- }
- Config.Config.SetReplace(ConfigData.Instance);
- //ここでBARを設定すれば、いいことに気づいた予感
- console.setStBar(Config.Config.DrawLineString);
- if (Config.Config.UseRenameFile)
- {
- if (File.Exists(Program.CsvDir + "_Rename.csv"))
- {
- if (Config.Config.DisplayReport || Program.AnalysisMode)
- console.PrintSystemLine("Loading _Rename.csv...");
- ParserMediator.LoadEraExRenameFile(Program.CsvDir + "_Rename.csv");
- }
- else
- console.PrintError("csv\\_Rename.csv is missing");
- }
- if (!Config.Config.DisplayReport)
- {
- console.PrintSingleLine(Config.Config.LoadLabel);
- console.RefreshStrings(true);
- }
- gamebase = new GameBase();
- if (!gamebase.LoadGameBaseCsv(Program.CsvDir + "GAMEBASE.CSV"))
- {
- console.PrintSystemLine("Processing was terminated because a problem occurred while loading GAMEBASE.CSV");
- return false;
- }
- console.SetWindowTitle(gamebase.ScriptWindowTitle);
- GlobalStatic.GameBaseData = gamebase;
- ConstantData constant = new ConstantData(gamebase);
- constant.LoadData(Program.CsvDir, console, Config.Config.DisplayReport);
- GlobalStatic.ConstantData = constant;
- _trainName = constant.GetCsvNameList(VariableCode.TRAINNAME);
- vEvaluator = new VariableEvaluator(gamebase, constant);
- GlobalStatic.VEvaluator = vEvaluator;
- idDic = new IdentifierDictionary(vEvaluator.VariableData);
- GlobalStatic.IdentifierDictionary = idDic;
- StrForm.Initialize();
- VariableParser.Initialize();
- exm = new ExpressionMediator(this, vEvaluator, console);
- GlobalStatic.EMediator = exm;
- labelDic = new LabelDictionary();
- GlobalStatic.LabelDictionary = labelDic;
- HeaderFileLoader hLoader = new HeaderFileLoader(console, idDic, this);
- LexicalAnalyzer.UseMacro = false;
- if (!hLoader.LoadHeaderFiles(Program.ErbDir, Config.Config.DisplayReport))
- {
- console.PrintSystemLine("Processing was terminated because a problem occurred while loading ERH files");
- return false;
- }
- LexicalAnalyzer.UseMacro = idDic.UseMacro();
- ErbLoader loader = new ErbLoader(console, exm, this);
- if (Program.AnalysisMode)
- noError = loader.LoadErbs(Program.AnalysisFiles, labelDic);
- else
- noError = loader.LoadErbFiles(Program.ErbDir, Config.Config.DisplayReport, labelDic);
- InitSystemProcess();
- initialiing = false;
- #if !DEBUG
- }
- catch (Exception e)
- {
- handleException(e, null, true);
- console.PrintSystemLine("Processing was terminated because a fatal error has occurred during initialization");
- return false;
- }
- #endif
- if (labelDic == null)
- {
- return false;
- }
- state.Begin(BeginType.TITLE);
- GC.Collect();
- return true;
- }
- public void ReloadErb()
- {
- saveCurrentState(false);
- state.SystemState = SystemStateCode.System_Reloaderb;
- ErbLoader loader = new ErbLoader(console, exm, this);
- loader.LoadErbFiles(Program.ErbDir, false, labelDic);
- console.ReadAnyKey();
- }
- public void ReloadPartialErb(List<string> path)
- {
- saveCurrentState(false);
- state.SystemState = SystemStateCode.System_Reloaderb;
- ErbLoader loader = new ErbLoader(console, exm, this);
- loader.LoadErbs(path, labelDic);
- console.ReadAnyKey();
- }
- public void SetCommnds(Int64 count)
- {
- coms = new List<long>((int)count);
- isCTrain = true;
- Int64[] selectcom = vEvaluator.SELECTCOM_ARRAY;
- if (count >= selectcom.Length)
- {
- throw new CodeEE("The value of the arguments of the CALLTRAIN instruction exceeds the number of SELECTCOM elements");
- }
- for (int i = 0; i < (int)count; i++)
- {
- coms.Add(selectcom[i + 1]);
- }
- }
- public bool ClearCommands()
- {
- coms.Clear();
- count = 0;
- isCTrain = false;
- skipPrint = true;
- return (CallFunction("CALLTRAINEND", false, false));
- }
- public void InputInteger(Int64 i)
- {
- vEvaluator.RESULT = i;
- }
- public void InputSystemInteger(Int64 i)
- {
- _systemResult = i;
- }
- public void InputString(string s)
- {
- vEvaluator.RESULTS = s;
- }
-
- public void DoScript()
- {
- state.lineCount = 0;
- bool systemProcRunning = true;
- try
- {
- while (true)
- {
- methodStack = 0;
- systemProcRunning = true;
- while (state.ScriptEnd && console.IsRunning)
- RunSystemProc();
- if (!console.IsRunning)
- break;
- systemProcRunning = false;
- runScriptProc(true);
- }
- }
- catch (Exception ec)
- {
- LogicalLine currentLine = state.ErrorLine;
- if (currentLine != null && currentLine is NullLine)
- currentLine = null;
- if (systemProcRunning)
- handleExceptionInSystemProc(ec, currentLine, true);
- else
- handleException(ec, currentLine, true);
- }
- }
-
- public void BeginTitle()
- {
- vEvaluator.ResetData();
- state = originalState;
- state.Begin(BeginType.TITLE);
- }
- private void checkInfiniteLoop()
- {
- //うまく動かない。BEEP音が鳴るのを止められないのでこの処理なかったことに(1.51)
- ////フリーズ防止。処理中でも履歴を見たりできる
- //System.Windows.Forms.Application.DoEvents();
- ////System.Threading.Thread.Sleep(0);
- //if (!console.Enabled)
- //{
- // //DoEvents()の間にウインドウが閉じられたらおしまい。
- // console.ReadAnyKey();
- // return;
- //}
- //uint time = WinmmTimer.TickCount - startTime;
- //if (time < Config.InfiniteLoopAlertTime)
- // return;
- //LogicalLine currentLine = state.CurrentLine;
- //if ((currentLine == null) || (currentLine is NullLine))
- // return;//現在の行が特殊な状態ならスルー
- //if (!console.Enabled)
- // return;//クローズしてるとMessageBox.Showができないので。
- //string caption = "There is a possibility of an infinite loop";
- //string text = string.Format(
- // "Currently {1} line at {0} is being executed.\nSince the last input {3} milliseconds has passed and the line was executed {2} times.\nWould you like to forcibly terminate processing?",
- // currentLine.Position.Filename, currentLine.Position.LineNo, state.lineCount, time);
- //DialogResult result = MessageBox.Show(text, caption, MessageBoxButtons.YesNo);
- //if (result == DialogResult.Yes)
- //{
- // throw new CodeEE("Forced termination was selected due to suspected infinite loop");
- //}
- //state.lineCount = 0;
- //startTime = WinmmTimer.TickCount;
- }
- int methodStack;
- public SingleTerm GetValue(SuperUserDefinedMethodTerm udmt,bool translate = false)
- {
- methodStack++;
- if (methodStack > 100)
- {
- //StackOverflowExceptionはcatchできない上に再現性がないので発生前に一定数で打ち切る。
- //環境によっては100以前にStackOverflowExceptionがでるかも?
- throw new CodeEE("Call stack of the function has overflowed (is it being recursively called indefinitely?)");
- }
- SingleTerm ret = null;
- int temp_current = state.currentMin;
- state.currentMin = state.functionCount;
- udmt.Call.updateRetAddress(state.CurrentLine);
- try
- {
- state.IntoFunction(udmt.Call, udmt.Argument, exm);
- //do whileの中でthrow されたエラーはここではキャッチされない。
- //#functionを全て抜けてDoScriptでキャッチされる。
- runScriptProc(translate);
- ret = state.MethodReturnValue;
- }
- finally
- {
- if (udmt.Call.TopLabel.hasPrivDynamicVar)
- udmt.Call.TopLabel.Out();
- //1756beta2+v3:こいつらはここにないとデバッグコンソールで式中関数が事故った時に大事故になる
- state.currentMin = temp_current;
- methodStack--;
- }
- return ret;
- }
- public void clearMethodStack()
- {
- methodStack = 0;
- }
- public int MethodStack()
- {
- return methodStack;
- }
- public ScriptPosition GetRunningPosition()
- {
- LogicalLine line = state.ErrorLine;
- if (line == null)
- return null;
- return line.Position;
- }
- private readonly string scaningScope = null;
- private string GetScaningScope()
- {
- if (scaningScope != null)
- return scaningScope;
- return state.Scope;
- }
- public LogicalLine scaningLine = null;
- internal LogicalLine GetScaningLine()
- {
- if (scaningLine != null)
- return scaningLine;
- LogicalLine line = state.ErrorLine;
- if (line == null)
- return null;
- return line;
- }
-
-
- private void handleExceptionInSystemProc(Exception exc, LogicalLine current, bool playSound)
- {
- console.ThrowError(playSound);
- if (exc is CodeEE)
- {
- console.PrintError("An error has occurred at the end of the function: " + Program.ExeName);
- console.PrintError(exc.Message);
- }
- else if (exc is ExeEE)
- {
- console.PrintError("An Emuera error has occurred at the end of the function: " + Program.ExeName);
- console.PrintError(exc.Message);
- }
- else
- {
- console.PrintError("An unexpected error has occurred at the end of the function: " + Program.ExeName);
- console.PrintError(exc.GetType() + ":" + exc.Message);
- string[] stack = exc.StackTrace.Split('\n');
- for (int i = 0; i < stack.Length; i++)
- {
- console.PrintError(stack[i]);
- }
- }
- }
-
- private void handleException(Exception exc, LogicalLine current, bool playSound)
- {
- console.ThrowError(playSound);
- ScriptPosition position = null;
- EmueraException ee = exc as EmueraException;
- if((ee != null) && (ee.Position != null))
- position = ee.Position;
- else if ((current != null) && (current.Position != null))
- position = current.Position;
- string posString = "";
- if (position != null)
- {
- if (position.LineNo >= 0)
- posString = position.Filename + " at line " + position.LineNo + " ";
- else
- posString = position.Filename + "で";
-
- }
- if (exc is CodeEE)
- {
- if (position != null)
- {
- InstructionLine procline = current as InstructionLine;
- if (procline != null && procline.FunctionCode == FunctionCode.THROW)
- {
- console.PrintErrorButton(posString + "THROW has occurred");
- if (position.RowLine != null)
- console.PrintError(position.RowLine);
- console.PrintError("THROW contents: " + exc.Message);
- }
- else
- {
- console.PrintErrorButton(posString + "Error has occurred:" + Program.ExeName);
- if (position.RowLine != null)
- console.PrintError(position.RowLine);
- console.PrintError("Error description: " + exc.Message);
- }
- console.PrintError("Function: @" + current.ParentLabelLine.LabelName + "(file:" + current.ParentLabelLine.Position.Filename + " in line " + current.ParentLabelLine.Position.LineNo + ")");
- console.PrintError("Function call stack: ");
- LogicalLine parent = null;
- int depth = 0;
- while ((parent = state.GetReturnAddressSequensial(depth++)) != null)
- {
- if (parent.Position != null)
- {
- console.PrintErrorButton("↑" + parent.Position.Filename + " at line " + parent.Position.LineNo + "(function@" + parent.ParentLabelLine.LabelName + ")");
- }
- }
- }
- else
- {
- console.PrintError(posString + "Error has occurred: " + Program.ExeName);
- console.PrintError(exc.Message);
- }
- }
- else if (exc is ExeEE)
- {
- console.PrintError(posString + "Emuera has encountered an error: " + Program.ExeName);
- console.PrintError(exc.Message);
- }
- else
- {
- console.PrintError(posString + "Unexpected error has occurred: " + Program.ExeName);
- console.PrintError(exc.GetType() + ":" + exc.Message);
- string[] stack = exc.StackTrace.Split('\n');
- for (int i = 0; i < stack.Length; i++)
- {
- console.PrintError(stack[i]);
- }
- }
- }
- }
- }
|