Process.ScriptProc.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using NTERA.Core.Interop;
  5. using NTERA.EmuEra.Game.EraEmu.GameData.Expression;
  6. using NTERA.EmuEra.Game.EraEmu.GameData.Variable;
  7. using NTERA.EmuEra.Game.EraEmu.GameProc.Function;
  8. using NTERA.EmuEra.Game.EraEmu.Sub;
  9. namespace NTERA.EmuEra.Game.EraEmu.GameProc
  10. {
  11. internal sealed partial class Process
  12. {
  13. private void runScriptProc(bool translate = false)
  14. {
  15. while (true)
  16. {
  17. //bool sequential = state.Sequential;
  18. state.ShiftNextLine();
  19. //WinmmTimerから時間を取得するのはそれ自体結構なコストがかかるので10000行に一回くらいで。
  20. if (Config.Config.InfiniteLoopAlertTime > 0 && (state.lineCount % 10000 == 0))
  21. checkInfiniteLoop();
  22. LogicalLine line = state.CurrentLine;
  23. InstructionLine func = line as InstructionLine;
  24. //これがNULLになる様な処理は現状ないはず
  25. //if (line == null)
  26. // throw new ExeEE("Emuera.exeは次に実行する行を見失いました");
  27. if (line.IsError)
  28. throw new CodeEE(line.ErrMes);
  29. if (func != null)
  30. {//1753 InstructionLineを先に持ってきてみる。わずかに速くなった気がしないでもない
  31. if (!Program.DebugMode && func.Function.IsDebug())
  32. {//非DebugモードでのDebug系命令。何もしない。(SIF文のためにコメント行扱いにはできない)
  33. continue;
  34. }
  35. if (func.Argument == null)
  36. {
  37. ArgumentParser.SetArgumentTo(func);
  38. if (func.IsError)
  39. throw new CodeEE(func.ErrMes);
  40. }
  41. if ((skipPrint) && (func.Function.IsPrint()))
  42. {
  43. if ((userDefinedSkip) && (func.Function.IsInput()))
  44. {
  45. console.PrintError("表示スキップ中にデフォルト値を持たないINPUTに遭遇しました");
  46. console.PrintError("INPUTに必要な処理をNOSKIP~ENDNOSKIPで囲むか、SKIPDISP 0~SKIPDISP 1で囲ってください");
  47. throw new CodeEE("無限ループに入る可能性が高いため実行を終了します");
  48. }
  49. continue;
  50. }
  51. if (func.Function.Instruction != null)
  52. func.Function.Instruction.DoInstruction(exm, func, state, translate);
  53. else if (func.Function.IsFlowContorol())
  54. doFlowControlFunction(func);
  55. else
  56. doNormalFunction(func);
  57. }
  58. else if ((line is NullLine) || (line is FunctionLabelLine))
  59. {//(関数終端) or ファイル終端
  60. //if (sequential)
  61. //{//流れ落ちてきた
  62. if (!state.IsFunctionMethod)
  63. vEvaluator.RESULT = 0;
  64. state.Return(0);
  65. //}
  66. //1750 飛んできた直後にShiftNextが入るのでここが実行されることは無いはず
  67. //else//CALLやJUMPで飛んできた
  68. //return;
  69. }
  70. else if (line is GotoLabelLine)
  71. continue;//$ラベル。何もすることはない。
  72. else if (line is InvalidLine)
  73. {
  74. if (string.IsNullOrEmpty(line.ErrMes))
  75. throw new CodeEE("読込に失敗した行が実行されました。エラーの詳細は読込時の警告を参照してください。");
  76. throw new CodeEE(line.ErrMes);
  77. }
  78. //現在そんなものはない
  79. //else
  80. // throw new ExeEE("定義されていない種類の行です");
  81. if (!console.IsRunning || state.ScriptEnd)
  82. return;
  83. }
  84. }
  85. public void DoDebugNormalFunction(InstructionLine func, bool munchkin)
  86. {
  87. if (func.Function.Instruction != null)
  88. func.Function.Instruction.DoInstruction(exm, func, state);
  89. else
  90. doNormalFunction(func);
  91. if (munchkin)
  92. vEvaluator.IamaMunchkin();
  93. }
  94. #region normal
  95. void doNormalFunction(InstructionLine func)
  96. {
  97. Int64 iValue = 0;
  98. string str = null;
  99. IOperandTerm term = null;
  100. switch (func.FunctionCode)
  101. {
  102. case FunctionCode.PRINTBUTTON://変数の内容
  103. {
  104. if (skipPrint)
  105. break;
  106. SpButtonArgument bArg = (SpButtonArgument)func.Argument;
  107. str = bArg.PrintStrTerm.GetStrValue(exm);
  108. //ボタン処理に絡んで表示がおかしくなるため、PRINTBUTTONでの改行コードはオミット
  109. str = str.Replace("\n", "");
  110. if (bArg.ButtonWord.GetOperandType() == typeof(long))
  111. exm.Console.PrintButton(str, bArg.ButtonWord.GetIntValue(exm));
  112. else
  113. exm.Console.PrintButton(str, bArg.ButtonWord.GetStrValue(exm));
  114. }
  115. break;
  116. case FunctionCode.PRINTBUTTONC://変数の内容
  117. case FunctionCode.PRINTBUTTONLC:
  118. {
  119. if (skipPrint)
  120. break;
  121. SpButtonArgument bArg = (SpButtonArgument)func.Argument;
  122. str = bArg.PrintStrTerm.GetStrValue(exm);
  123. //ボタン処理に絡んで表示がおかしくなるため、PRINTBUTTONでの改行コードはオミット
  124. str = str.Replace("\n", "");
  125. bool isRight = (func.FunctionCode == FunctionCode.PRINTBUTTONC) ? true : false;
  126. if (bArg.ButtonWord.GetOperandType() == typeof(long))
  127. exm.Console.PrintButtonC(str, bArg.ButtonWord.GetIntValue(exm), isRight);
  128. else
  129. exm.Console.PrintButtonC(str, bArg.ButtonWord.GetStrValue(exm), isRight);
  130. }
  131. break;
  132. case FunctionCode.PRINTPLAIN:
  133. case FunctionCode.PRINTPLAINFORM:
  134. {
  135. if (skipPrint)
  136. break;
  137. //Bartoum : This is where printplain print from so we always translate
  138. term = ((ExpressionArgument)func.Argument).Term;
  139. exm.Console.PrintPlain(term.GetStrValue(exm, true));
  140. }
  141. break;
  142. case FunctionCode.DRAWLINE://画面の左端から右端まで----と線を引く。
  143. if (skipPrint)
  144. break;
  145. exm.Console.PrintBar();
  146. exm.Console.NewLine();
  147. break;
  148. case FunctionCode.CUSTOMDRAWLINE:
  149. case FunctionCode.DRAWLINEFORM:
  150. {
  151. if (skipPrint)
  152. break;
  153. term = ((ExpressionArgument)func.Argument).Term;
  154. str = term.GetStrValue(exm);
  155. exm.Console.printCustomBar(str);
  156. //exm.Console.setStBar(str);
  157. //exm.Console.PrintBar();
  158. exm.Console.NewLine();
  159. //exm.Console.setStBar(Config.DrawLineString);
  160. }
  161. break;
  162. case FunctionCode.PRINT_ABL://能力。引数は登録番号
  163. case FunctionCode.PRINT_TALENT://素質
  164. case FunctionCode.PRINT_MARK://刻印
  165. case FunctionCode.PRINT_EXP://経験
  166. {
  167. if (skipPrint)
  168. break;
  169. ExpressionArgument intExpArg = (ExpressionArgument)func.Argument;
  170. Int64 target = intExpArg.Term.GetIntValue(exm);
  171. exm.Console.Write(vEvaluator.GetCharacterDataString(target, func.FunctionCode));
  172. exm.Console.NewLine();
  173. }
  174. break;
  175. case FunctionCode.PRINT_PALAM://パラメータ
  176. {
  177. if (skipPrint)
  178. break;
  179. ExpressionArgument intExpArg = (ExpressionArgument)func.Argument;
  180. Int64 target = intExpArg.Term.GetIntValue(exm);
  181. int count = 0;
  182. ///100以降は否定の珠とかなので表示しない
  183. for (int i = 0; i < 100; i++)
  184. {
  185. string printStr = vEvaluator.GetCharacterParamString(target, i);
  186. if (printStr != null)
  187. {
  188. //Need a function for each PRINT_
  189. //Bartoum
  190. exm.Console.PrintC(printStr, true);
  191. count++;
  192. if ((Config.Config.PrintCPerLine > 0) && (count % Config.Config.PrintCPerLine == 0))
  193. exm.Console.PrintFlush(false);
  194. }
  195. }
  196. exm.Console.PrintFlush(false);
  197. exm.Console.RefreshStrings(false);
  198. }
  199. break;
  200. case FunctionCode.PRINT_ITEM://所持アイテム
  201. if (skipPrint)
  202. break;
  203. exm.Console.Write(vEvaluator.GetHavingItemsString());
  204. exm.Console.NewLine();
  205. break;
  206. case FunctionCode.PRINT_SHOPITEM://ショップで売っているアイテム
  207. {
  208. if (skipPrint)
  209. break;
  210. int length = Math.Min(vEvaluator.ITEMSALES.Length, vEvaluator.ITEMNAME.Length);
  211. if (length > vEvaluator.ITEMPRICE.Length)
  212. length = vEvaluator.ITEMPRICE.Length;
  213. int count = 0;
  214. for (int i = 0; i < length; i++)
  215. {
  216. if (vEvaluator.ItemSales(i))
  217. {
  218. string printStr = vEvaluator.ITEMNAME[i];
  219. if (printStr == null)
  220. printStr = "";
  221. Int64 price = vEvaluator.ITEMPRICE[i];
  222. // 1.52a改変部分 (単位の差し替えおよび前置、後置に対応)
  223. printStr = Translation.translate(printStr, "Item", true);
  224. if (Config.Config.MoneyFirst)
  225. exm.Console.PrintC(string.Format("[{2}] {0}({3}{1})", printStr, price, i, Config.Config.MoneyLabel), false);
  226. else
  227. exm.Console.PrintC(string.Format("[{2}] {0}({1}{3})", printStr, price, i, Config.Config.MoneyLabel), false);
  228. count++;
  229. if ((Config.Config.PrintCPerLine > 0) && (count % Config.Config.PrintCPerLine == 0))
  230. exm.Console.PrintFlush(false);
  231. }
  232. }
  233. exm.Console.PrintFlush(false);
  234. exm.Console.RefreshStrings(false);
  235. }
  236. break;
  237. case FunctionCode.UPCHECK://パラメータの変動
  238. vEvaluator.UpdateInUpcheck(exm.Console, skipPrint);
  239. break;
  240. case FunctionCode.CUPCHECK://パラメータの変動(任意キャラ版)
  241. {
  242. ExpressionArgument intExpArg = (ExpressionArgument)func.Argument;
  243. Int64 target = intExpArg.Term.GetIntValue(exm);
  244. vEvaluator.CUpdateInUpcheck(exm.Console, target, skipPrint);
  245. }
  246. break;
  247. case FunctionCode.DELALLCHARA:
  248. {
  249. vEvaluator.DelAllCharacter();
  250. break;
  251. }
  252. case FunctionCode.PICKUPCHARA:
  253. {
  254. ExpressionArrayArgument intExpArg = (ExpressionArrayArgument)func.Argument;
  255. Int64[] NoList = new Int64[intExpArg.TermList.Length];
  256. Int64 charaNum = vEvaluator.CHARANUM;
  257. for (int i = 0; i < intExpArg.TermList.Length; i++)
  258. {
  259. IOperandTerm term_i = intExpArg.TermList[i];
  260. NoList[i] = term_i.GetIntValue(exm);
  261. if (!(term_i is VariableTerm) || ((((VariableTerm)term_i).Identifier.Code != VariableCode.MASTER) && (((VariableTerm)term_i).Identifier.Code != VariableCode.ASSI) && (((VariableTerm)term_i).Identifier.Code != VariableCode.TARGET)))
  262. if (NoList[i] < 0 || NoList[i] >= charaNum)
  263. throw new CodeEE("命令PICKUPCHARAの第" + (i + 1) + "引数にキャラリストの範囲外の値(" + NoList[i] + ")が与えられました");
  264. }
  265. vEvaluator.PickUpChara(NoList);
  266. }
  267. break;
  268. case FunctionCode.ADDDEFCHARA:
  269. {
  270. //デバッグコマンドなら通す
  271. if ((func.ParentLabelLine != null) && (func.ParentLabelLine.LabelName != "SYSTEM_TITLE"))
  272. throw new CodeEE("@SYSTEM_TITLE以外でこの命令を使うことはできません");
  273. vEvaluator.AddCharacterFromCsvNo(0);
  274. if (GlobalStatic.GameBaseData.DefaultCharacter > 0)
  275. vEvaluator.AddCharacterFromCsvNo(GlobalStatic.GameBaseData.DefaultCharacter);
  276. break;
  277. }
  278. case FunctionCode.PUTFORM://@SAVEINFO関数でのみ使用可能。PRINTFORMと同様の書式でセーブデータに概要をつける。
  279. {
  280. term = ((ExpressionArgument)func.Argument).Term;
  281. str = term.GetStrValue(exm);
  282. if (vEvaluator.SAVEDATA_TEXT != null)
  283. vEvaluator.SAVEDATA_TEXT += str;
  284. else
  285. vEvaluator.SAVEDATA_TEXT = str;
  286. break;
  287. }
  288. case FunctionCode.QUIT://ゲームを終了
  289. exm.Console.Quit();
  290. break;
  291. case FunctionCode.VARSIZE:
  292. {
  293. SpVarsizeArgument versizeArg = (SpVarsizeArgument)func.Argument;
  294. VariableToken varID = versizeArg.VariableID;
  295. vEvaluator.VarSize(varID);
  296. }
  297. break;
  298. case FunctionCode.SAVEDATA:
  299. {
  300. SpSaveDataArgument spSavedataArg = (SpSaveDataArgument)func.Argument;
  301. Int64 target = spSavedataArg.Target.GetIntValue(exm);
  302. if (target < 0)
  303. throw new CodeEE("SAVEDATAの引数に負の値(" + target + ")が指定されました");
  304. if (target > int.MaxValue)
  305. throw new CodeEE("SAVEDATAの引数(" + target + ")が大きすぎます");
  306. string savemes = spSavedataArg.StrExpression.GetStrValue(exm);
  307. if (savemes.Contains("\n"))
  308. throw new CodeEE("SAVEDATAのセーブテキストに改行文字が与えられました(セーブデータが破損するため改行文字は使えません)");
  309. if (!vEvaluator.SaveTo((int)target, savemes))
  310. {
  311. console.PrintError("SAVEDATA命令によるセーブ中に予期しないエラーが発生しました");
  312. }
  313. }
  314. break;
  315. case FunctionCode.POWER:
  316. {
  317. SpPowerArgument powerArg = (SpPowerArgument)func.Argument;
  318. double x = powerArg.X.GetIntValue(exm);
  319. double y = powerArg.Y.GetIntValue(exm);
  320. double pow = Math.Pow(x, y);
  321. if (double.IsNaN(pow))
  322. throw new CodeEE("累乗結果が非数値です");
  323. if (double.IsInfinity(pow))
  324. throw new CodeEE("累乗結果が無限大です");
  325. if ((pow >= Int64.MaxValue) || (pow <= Int64.MinValue))
  326. throw new CodeEE("累乗結果(" + pow + ")が64ビット符号付き整数の範囲外です");
  327. powerArg.VariableDest.SetValue((long)pow, exm);
  328. break;
  329. }
  330. case FunctionCode.SWAP:
  331. {
  332. SpSwapVarArgument arg = (SpSwapVarArgument)func.Argument;
  333. //1756beta2+v11
  334. //値を読み出す前に添え字を確定させておかないと、RANDが添え字にある場合正しく処理できない
  335. FixedVariableTerm vTerm1 = arg.var1.GetFixedVariableTerm(exm);
  336. FixedVariableTerm vTerm2 = arg.var2.GetFixedVariableTerm(exm);
  337. if (vTerm1.GetOperandType() != vTerm2.GetOperandType())
  338. throw new CodeEE("入れ替える変数の型が異なります");
  339. if (vTerm1.GetOperandType() == typeof(Int64))
  340. {
  341. Int64 temp = vTerm1.GetIntValue(exm);
  342. vTerm1.SetValue(vTerm2.GetIntValue(exm), exm);
  343. vTerm2.SetValue(temp, exm);
  344. }
  345. else if (arg.var1.GetOperandType() == typeof(string))
  346. {
  347. string temps = vTerm1.GetStrValue(exm);
  348. vTerm1.SetValue(vTerm2.GetStrValue(exm), exm);
  349. vTerm2.SetValue(temps, exm);
  350. }
  351. else
  352. {
  353. throw new CodeEE("不明な変数型です");
  354. }
  355. break;
  356. }
  357. case FunctionCode.GETTIME:
  358. {
  359. long date = DateTime.Now.Year;
  360. date = date * 100 + DateTime.Now.Month;
  361. date = date * 100 + DateTime.Now.Day;
  362. date = date * 100 + DateTime.Now.Hour;
  363. date = date * 100 + DateTime.Now.Minute;
  364. date = date * 100 + DateTime.Now.Second;
  365. date = date * 1000 + DateTime.Now.Millisecond;
  366. vEvaluator.RESULT = date;//17桁。2京くらい。
  367. vEvaluator.RESULTS = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
  368. }
  369. break;
  370. case FunctionCode.SETCOLOR:
  371. {
  372. SpColorArgument colorArg = (SpColorArgument)func.Argument;
  373. Int64 colorR;
  374. Int64 colorG;
  375. Int64 colorB;
  376. if (colorArg.RGB != null)
  377. {
  378. Int64 colorRGB = colorArg.RGB.GetIntValue(exm);
  379. colorR = (colorRGB & 0xFF0000) >> 16;
  380. colorG = (colorRGB & 0x00FF00) >> 8;
  381. colorB = (colorRGB & 0x0000FF);
  382. }
  383. else
  384. {
  385. colorR = colorArg.R.GetIntValue(exm);
  386. colorG = colorArg.G.GetIntValue(exm);
  387. colorB = colorArg.B.GetIntValue(exm);
  388. if ((colorR < 0) || (colorG < 0) || (colorB < 0))
  389. throw new CodeEE("SETCOLORの引数に0未満の値が指定されました");
  390. if ((colorR > 255) || (colorG > 255) || (colorB > 255))
  391. throw new CodeEE("SETCOLORの引数に255を超える値が指定されました");
  392. }
  393. Color c = Color.FromArgb((Int32)colorR, (Int32)colorG, (Int32)colorB);
  394. exm.Console.SetStringStyle(c);
  395. }
  396. break;
  397. case FunctionCode.SETCOLORBYNAME:
  398. {
  399. string colorName = func.Argument.ConstStr;
  400. Color c = Color.FromName(colorName);
  401. if (c.A == 0)
  402. {
  403. if (str.Equals("transparent", StringComparison.OrdinalIgnoreCase))
  404. throw new CodeEE("無色透明(Transparent)は色として指定できません");
  405. throw new CodeEE("指定された色名\"" + colorName + "\"は無効な色名です");
  406. }
  407. exm.Console.SetStringStyle(c);
  408. }
  409. break;
  410. case FunctionCode.SETBGCOLOR:
  411. {
  412. SpColorArgument colorArg = (SpColorArgument)func.Argument;
  413. Int64 colorR;
  414. Int64 colorG;
  415. Int64 colorB;
  416. if (colorArg.IsConst)
  417. {
  418. Int64 colorRGB = colorArg.ConstInt;
  419. colorR = (colorRGB & 0xFF0000) >> 16;
  420. colorG = (colorRGB & 0x00FF00) >> 8;
  421. colorB = (colorRGB & 0x0000FF);
  422. }
  423. else if (colorArg.RGB != null)
  424. {
  425. Int64 colorRGB = colorArg.RGB.GetIntValue(exm);
  426. colorR = (colorRGB & 0xFF0000) >> 16;
  427. colorG = (colorRGB & 0x00FF00) >> 8;
  428. colorB = (colorRGB & 0x0000FF);
  429. }
  430. else
  431. {
  432. colorR = colorArg.R.GetIntValue(exm);
  433. colorG = colorArg.G.GetIntValue(exm);
  434. colorB = colorArg.B.GetIntValue(exm);
  435. if ((colorR < 0) || (colorG < 0) || (colorB < 0))
  436. throw new CodeEE("SETCOLORの引数に0未満の値が指定されました");
  437. if ((colorR > 255) || (colorG > 255) || (colorB > 255))
  438. throw new CodeEE("SETCOLORの引数に255を超える値が指定されました");
  439. }
  440. Color c = Color.FromArgb((Int32)colorR, (Int32)colorG, (Int32)colorB);
  441. exm.Console.SetBgColor(c);
  442. }
  443. break;
  444. case FunctionCode.SETBGCOLORBYNAME:
  445. {
  446. string colorName = func.Argument.ConstStr;
  447. Color c = Color.FromName(colorName);
  448. if (c.A == 0)
  449. {
  450. if (str.Equals("transparent", StringComparison.OrdinalIgnoreCase))
  451. throw new CodeEE("無色透明(Transparent)は色として指定できません");
  452. throw new CodeEE("指定された色名\"" + colorName + "\"は無効な色名です");
  453. }
  454. exm.Console.SetBgColor(c);
  455. }
  456. break;
  457. case FunctionCode.FONTSTYLE:
  458. {
  459. FontStyle fs = FontStyle.Regular;
  460. if (func.Argument.IsConst)
  461. iValue = func.Argument.ConstInt;
  462. else
  463. iValue = ((ExpressionArgument)func.Argument).Term.GetIntValue(exm);
  464. if ((iValue & 1) != 0)
  465. fs |= FontStyle.Bold;
  466. if ((iValue & 2) != 0)
  467. fs |= FontStyle.Italic;
  468. if ((iValue & 4) != 0)
  469. fs |= FontStyle.Strikeout;
  470. if ((iValue & 8) != 0)
  471. fs |= FontStyle.Underline;
  472. exm.Console.SetStringStyle(fs);
  473. }
  474. break;
  475. case FunctionCode.SETFONT:
  476. if (func.Argument.IsConst)
  477. str = func.Argument.ConstStr;
  478. else
  479. str = ((ExpressionArgument)func.Argument).Term.GetStrValue(exm);
  480. exm.Console.SetFont(str);
  481. break;
  482. case FunctionCode.ALIGNMENT:
  483. str = func.Argument.ConstStr;
  484. if (str.Equals("LEFT", Config.Config.SCVariable))
  485. exm.Console.Alignment = DisplayLineAlignment.LEFT;
  486. else if (str.Equals("CENTER", Config.Config.SCVariable))
  487. exm.Console.Alignment = DisplayLineAlignment.CENTER;
  488. else if (str.Equals("RIGHT", Config.Config.SCVariable))
  489. exm.Console.Alignment = DisplayLineAlignment.RIGHT;
  490. else
  491. throw new CodeEE("ALIGNMENTのキーワード\"" + str + "\"は未定義です");
  492. break;
  493. case FunctionCode.REDRAW:
  494. if (func.Argument.IsConst)
  495. iValue = func.Argument.ConstInt;
  496. else
  497. iValue = ((ExpressionArgument)func.Argument).Term.GetIntValue(exm);
  498. exm.Console.SetRedraw(iValue);
  499. break;
  500. case FunctionCode.RESET_STAIN:
  501. {
  502. if (func.Argument.IsConst)
  503. iValue = func.Argument.ConstInt;
  504. else
  505. iValue = ((ExpressionArgument)func.Argument).Term.GetIntValue(exm);
  506. vEvaluator.SetDefaultStain(iValue);
  507. }
  508. break;
  509. case FunctionCode.SPLIT:
  510. {
  511. SpSplitArgument spSplitArg = (SpSplitArgument)func.Argument;
  512. string target = spSplitArg.TargetStr.GetStrValue(exm);
  513. string[] split = { spSplitArg.Split.GetStrValue(exm) };
  514. string[] retStr = target.Split(split, StringSplitOptions.None);
  515. spSplitArg.Num.SetValue(retStr.Length, exm);
  516. if (retStr.Length > spSplitArg.Var.GetLength(0))
  517. {
  518. string[] temp = retStr;
  519. retStr = new string[spSplitArg.Var.GetLength(0)];
  520. Array.Copy(temp, retStr, retStr.Length);
  521. //throw new CodeEE("SPLITによる分割後の文字列の数が配列変数の要素数を超えています");
  522. }
  523. spSplitArg.Var.SetValue(retStr, new long[] { 0, 0, 0 });
  524. }
  525. break;
  526. case FunctionCode.PRINTCPERLINE:
  527. {
  528. SpGetIntArgument spGetintArg = (SpGetIntArgument)func.Argument;
  529. spGetintArg.VarToken.SetValue(Config.Config.PrintCPerLine, exm);
  530. }
  531. break;
  532. case FunctionCode.SAVENOS:
  533. {
  534. SpGetIntArgument spGetintArg = (SpGetIntArgument)func.Argument;
  535. spGetintArg.VarToken.SetValue(Config.Config.SaveDataNos, exm);
  536. }
  537. break;
  538. case FunctionCode.FORCEKANA:
  539. if (func.Argument.IsConst)
  540. iValue = func.Argument.ConstInt;
  541. else
  542. iValue = ((ExpressionArgument)func.Argument).Term.GetIntValue(exm);
  543. exm.ForceKana(iValue);
  544. break;
  545. case FunctionCode.SKIPDISP:
  546. {
  547. iValue = (func.Argument.IsConst) ? func.Argument.ConstInt : ((ExpressionArgument)func.Argument).Term.GetIntValue(exm);
  548. skipPrint = (iValue != 0);
  549. userDefinedSkip = (iValue != 0);
  550. vEvaluator.RESULT = (skipPrint) ? 1L : 0L;
  551. }
  552. break;
  553. case FunctionCode.NOSKIP:
  554. {
  555. if (func.JumpTo == null)
  556. throw new CodeEE("対応するENDNOSKIPのないNOSKIPです");
  557. saveSkip = skipPrint;
  558. if (skipPrint)
  559. skipPrint = false;
  560. }
  561. break;
  562. case FunctionCode.ENDNOSKIP:
  563. {
  564. if (func.JumpTo == null)
  565. throw new CodeEE("対応するNOSKIPのないENDNOSKIPです");
  566. if (saveSkip)
  567. skipPrint = true;
  568. }
  569. break;
  570. case FunctionCode.OUTPUTLOG:
  571. exm.Console.OutputLog(null);
  572. break;
  573. case FunctionCode.ARRAYSHIFT: //配列要素をずらす
  574. {
  575. SpArrayShiftArgument arrayArg = (SpArrayShiftArgument)func.Argument;
  576. if (!arrayArg.VarToken.Identifier.IsArray1D)
  577. throw new CodeEE("ARRAYSHIFTは1次元配列および配列型キャラクタ変数のみに対応しています");
  578. FixedVariableTerm dest = arrayArg.VarToken.GetFixedVariableTerm(exm);
  579. int shift = (int)arrayArg.Num1.GetIntValue(exm);
  580. if (shift == 0)
  581. break;
  582. int start = (int)arrayArg.Num3.GetIntValue(exm);
  583. if (start < 0)
  584. throw new CodeEE("ARRAYSHIFTの第4引数が負の値(" + start + ")です");
  585. int num;
  586. if (arrayArg.Num4 != null)
  587. {
  588. num = (int)arrayArg.Num4.GetIntValue(exm);
  589. if (num < 0)
  590. throw new CodeEE("ARRAYSHIFTの第5引数が負の値(" + start + ")です");
  591. if (num == 0)
  592. break;
  593. }
  594. else
  595. num = -1;
  596. if (dest.Identifier.IsInteger)
  597. {
  598. Int64 def = arrayArg.Num2.GetIntValue(exm);
  599. vEvaluator.ShiftArray(dest, shift, def, start, num);
  600. }
  601. else
  602. {
  603. string defs = arrayArg.Num2.GetStrValue(exm);
  604. vEvaluator.ShiftArray(dest, shift, defs, start, num);
  605. }
  606. break;
  607. }
  608. case FunctionCode.ARRAYREMOVE:
  609. {
  610. SpArrayControlArgument arrayArg = (SpArrayControlArgument)func.Argument;
  611. if (!arrayArg.VarToken.Identifier.IsArray1D)
  612. throw new CodeEE("ARRAYREMOVEは1次元配列および配列型キャラクタ変数のみに対応しています");
  613. FixedVariableTerm p = arrayArg.VarToken.GetFixedVariableTerm(exm);
  614. int start = (int)arrayArg.Num1.GetIntValue(exm);
  615. int num = (int)arrayArg.Num2.GetIntValue(exm);
  616. if (start < 0)
  617. throw new CodeEE("ARRAYREMOVEの第2引数が負の値(" + start + ")です");
  618. if (num < 0)
  619. throw new CodeEE("ARRAYREMOVEの第3引数が負の値(" + start + ")です");
  620. if (num == 0)
  621. break;
  622. vEvaluator.RemoveArray(p, start, num);
  623. break;
  624. }
  625. case FunctionCode.ARRAYSORT:
  626. {
  627. SpArraySortArgument arrayArg = (SpArraySortArgument)func.Argument;
  628. if (!arrayArg.VarToken.Identifier.IsArray1D)
  629. throw new CodeEE("ARRAYRESORTは1次元配列および配列型キャラクタ変数のみに対応しています");
  630. FixedVariableTerm p = arrayArg.VarToken.GetFixedVariableTerm(exm);
  631. int start = (int)arrayArg.Num1.GetIntValue(exm);
  632. if (start < 0)
  633. throw new CodeEE("ARRAYSORTの第3引数が負の値(" + start + ")です");
  634. int num = 0;
  635. if (arrayArg.Num2 != null)
  636. {
  637. num = (int)arrayArg.Num2.GetIntValue(exm);
  638. if (num < 0)
  639. throw new CodeEE("ARRAYSORTの第4引数が負の値(" + start + ")です");
  640. if (num == 0)
  641. break;
  642. }
  643. else
  644. num = -1;
  645. vEvaluator.SortArray(p, arrayArg.Order, start, num);
  646. break;
  647. }
  648. case FunctionCode.ARRAYCOPY:
  649. {
  650. SpCopyArrayArgument arrayArg = (SpCopyArrayArgument)func.Argument;
  651. IOperandTerm varName1 = arrayArg.VarName1;
  652. IOperandTerm varName2 = arrayArg.VarName2;
  653. VariableToken[] vars = new VariableToken[2] { null, null };
  654. if (!(varName1 is SingleTerm) || !(varName2 is SingleTerm))
  655. {
  656. string[] names = new string[2] { null, null };
  657. names[0] = varName1.GetStrValue(exm);
  658. names[1] = varName2.GetStrValue(exm);
  659. if ((vars[0] = GlobalStatic.IdentifierDictionary.GetVariableToken(names[0], null, true)) == null)
  660. throw new CodeEE("ARRAYCOPY命令の第1引数(" + names[0] + ")が有効な変数名ではありません");
  661. if (!vars[0].IsArray1D && !vars[0].IsArray2D && !vars[0].IsArray3D)
  662. throw new CodeEE("ARRAYCOPY命令の第1引数\"" + names[0] + "\"は配列変数ではありません");
  663. if (vars[0].IsCharacterData)
  664. throw new CodeEE("ARRAYCOPY命令の第1引数\"" + names[0] + "\"はキャラクタ変数です(対応していません)");
  665. if ((vars[1] = GlobalStatic.IdentifierDictionary.GetVariableToken(names[1], null, true)) == null)
  666. throw new CodeEE("ARRAYCOPY命令の第2引数(" + names[0] + ")が有効な変数名ではありません");
  667. if (!vars[1].IsArray1D && !vars[1].IsArray2D && !vars[1].IsArray3D)
  668. throw new CodeEE("ARRAYCOPY命令の第2引数\"" + names[1] + "\"は配列変数ではありません");
  669. if (vars[1].IsCharacterData)
  670. throw new CodeEE("ARRAYCOPY命令の第2引数\"" + names[1] + "\"はキャラクタ変数です(対応していません)");
  671. if (vars[1].IsConst)
  672. throw new CodeEE("ARRAYCOPY命令の第2引数\"" + names[1] + "\"は値を変更できない変数です");
  673. if ((vars[0].IsArray1D && !vars[1].IsArray1D) || (vars[0].IsArray2D && !vars[1].IsArray2D) || (vars[0].IsArray3D && !vars[1].IsArray3D))
  674. throw new CodeEE("ARRAYCOPY命令の2つの配列変数の次元数が一致していません");
  675. if ((vars[0].IsInteger && vars[1].IsString) || (vars[0].IsString && vars[1].IsInteger))
  676. throw new CodeEE("ARRAYCOPY命令の2つの配列変数の型が一致していません");
  677. }
  678. else
  679. {
  680. vars[0] = GlobalStatic.IdentifierDictionary.GetVariableToken(((SingleTerm)varName1).Str, null, true);
  681. vars[1] = GlobalStatic.IdentifierDictionary.GetVariableToken(((SingleTerm)varName2).Str, null, true);
  682. if ((vars[0].IsInteger && vars[1].IsString) || (vars[0].IsString && vars[1].IsInteger))
  683. throw new CodeEE("ARRAYCOPY命令の2つの配列変数の型が一致していません");
  684. }
  685. vEvaluator.CopyArray(vars[0], vars[1]);
  686. }
  687. break;
  688. case FunctionCode.ENCODETOUNI:
  689. {
  690. //int length = Encoding.UTF32.GetEncoder().GetByteCount(target.ToCharArray(), 0, target.Length, false);
  691. //byte[] bytes = new byte[length];
  692. //Encoding.UTF32.GetEncoder().GetBytes(target.ToCharArray(), 0, target.Length, bytes, 0, false);
  693. //vEvaluator.setEncodingResult(bytes);
  694. term = ((ExpressionArgument)func.Argument).Term;
  695. string target = term.GetStrValue(exm);
  696. int length = vEvaluator.RESULT_ARRAY.Length;
  697. // result:0には長さが入るのでその分-1
  698. if (target.Length > length - 1)
  699. throw new CodeEE(String.Format("ENCODETOUNIの引数が長すぎます(現在{0}文字。最大{1}文字まで)", target.Length, length - 1));
  700. int[] ary = new int[target.Length];
  701. for (int i = 0; i < target.Length; i++)
  702. ary[i] = char.ConvertToUtf32(target, i);
  703. vEvaluator.SetEncodingResult(ary);
  704. }
  705. break;
  706. case FunctionCode.ASSERT:
  707. if (((ExpressionArgument)func.Argument).Term.GetIntValue(exm) == 0)
  708. throw new CodeEE("ASSERT文の引数が0です");
  709. break;
  710. case FunctionCode.THROW:
  711. throw new CodeEE(((ExpressionArgument)func.Argument).Term.GetStrValue(exm));
  712. case FunctionCode.CLEARTEXTBOX:
  713. GlobalStatic.MainWindow.Clear_RichText();
  714. break;
  715. case FunctionCode.STRDATA:
  716. {
  717. //表示データが空なら何もしないで飛ぶ
  718. if (func.dataList.Count == 0)
  719. {
  720. state.JumpTo(func.JumpTo);
  721. return;
  722. }
  723. int count = func.dataList.Count;
  724. int choice = (int)exm.VEvaluator.GetNextRand(count);
  725. List<InstructionLine> iList = func.dataList[choice];
  726. int i = 0;
  727. foreach (InstructionLine selectedLine in iList)
  728. {
  729. state.CurrentLine = selectedLine;
  730. if (selectedLine.Argument == null)
  731. ArgumentParser.SetArgumentTo(selectedLine);
  732. term = ((ExpressionArgument)selectedLine.Argument).Term;
  733. str += term.GetStrValue(exm);
  734. if (++i < iList.Count)
  735. str += "\n";
  736. }
  737. ((StrDataArgument)func.Argument).Var.SetValue(str, exm);
  738. //ジャンプするが、流れが連続であることを保証。
  739. state.JumpTo(func.JumpTo);
  740. break;
  741. }
  742. #if DEBUG
  743. default:
  744. throw new ExeEE("未定義の関数");
  745. #endif
  746. }
  747. }
  748. bool saveSkip;
  749. bool userDefinedSkip;
  750. #endregion
  751. #region flow control
  752. bool doFlowControlFunction(InstructionLine func)
  753. {
  754. switch (func.FunctionCode)
  755. {
  756. case FunctionCode.LOADDATA:
  757. {
  758. ExpressionArgument intExpArg = (ExpressionArgument)func.Argument;
  759. Int64 target = intExpArg.Term.GetIntValue(exm);
  760. if (target < 0)
  761. throw new CodeEE("LOADDATAの引数に負の値(" + target + ")が指定されました");
  762. if (target > int.MaxValue)
  763. throw new CodeEE("LOADDATAの引数(" + target + ")が大きすぎます");
  764. //EraDataResult result = vEvaluator.checkData((int)target);
  765. EraDataResult result = vEvaluator.CheckData((int)target, EraSaveFileType.Normal);
  766. if (result.State != EraDataState.OK)
  767. throw new CodeEE("不正なデータをロードしようとしました");
  768. if (!vEvaluator.LoadFrom((int)target))
  769. throw new ExeEE("ファイルのロード中に予期しないエラーが発生しました");
  770. state.ClearFunctionList();
  771. state.SystemState = SystemStateCode.LoadData_DataLoaded;
  772. return false;
  773. }
  774. case FunctionCode.TRYCALLLIST:
  775. case FunctionCode.TRYJUMPLIST:
  776. {
  777. //if (!sequential)//RETURNで帰ってきた
  778. //{
  779. // state.JumpTo(func.JumpTo);
  780. // break;
  781. //}
  782. string funcName = "";
  783. CalledFunction callto = null;
  784. SpCallArgment cfa = null;
  785. foreach (InstructionLine iLine in func.callList)
  786. {
  787. cfa = (SpCallArgment)iLine.Argument;
  788. funcName = cfa.FuncnameTerm.GetStrValue(exm);
  789. if (Config.Config.ICFunction)
  790. funcName = funcName.ToUpper();
  791. callto = CalledFunction.CallFunction(this, funcName, func.JumpTo);
  792. if (callto == null)
  793. continue;
  794. callto.IsJump = func.Function.IsJump();
  795. string errMes;
  796. UserDefinedFunctionArgument args = callto.ConvertArg(cfa.RowArgs, out errMes);
  797. if (args == null)
  798. throw new CodeEE(errMes);
  799. state.IntoFunction(callto, args, exm);
  800. return true;
  801. }
  802. state.JumpTo(func.JumpTo);
  803. }
  804. break;
  805. case FunctionCode.TRYGOTOLIST:
  806. {
  807. string funcName = "";
  808. LogicalLine jumpto = null;
  809. foreach (InstructionLine iLine in func.callList)
  810. {
  811. if (iLine.Argument == null)
  812. ArgumentParser.SetArgumentTo(iLine);
  813. funcName = ((SpCallArgment)iLine.Argument).FuncnameTerm.GetStrValue(exm);
  814. if (Config.Config.ICVariable)
  815. funcName = funcName.ToUpper();
  816. jumpto = state.CurrentCalled.CallLabel(this, funcName);
  817. if (jumpto != null)
  818. break;
  819. }
  820. if (jumpto == null)
  821. state.JumpTo(func.JumpTo);
  822. else
  823. state.JumpTo(jumpto);
  824. }
  825. break;
  826. case FunctionCode.CALLTRAIN:
  827. {
  828. ExpressionArgument intExpArg = (ExpressionArgument)func.Argument;
  829. Int64 count = intExpArg.Term.GetIntValue(exm);
  830. SetCommnds(count);
  831. return false;
  832. }
  833. case FunctionCode.STOPCALLTRAIN:
  834. {
  835. if (isCTrain)
  836. {
  837. ClearCommands();
  838. skipPrint = false;
  839. }
  840. return false;
  841. }
  842. case FunctionCode.DOTRAIN:
  843. {
  844. switch (state.SystemState)
  845. {
  846. //case SystemStateCode.Train_Begin://BEGIN TRAINから。
  847. case SystemStateCode.Train_CallEventTrain://@EVENTTRAINの呼び出し中。スキップ可能
  848. case SystemStateCode.Train_CallShowStatus://@SHOW_STATUSの呼び出し中
  849. //case SystemStateCode.Train_CallComAbleXX://@COM_ABLExxの呼び出し中。
  850. case SystemStateCode.Train_CallShowUserCom://@SHOW_USERCOMの呼び出し中
  851. //case SystemStateCode.Train_WaitInput://入力待ち状態。選択が実行可能ならEVENTCOMからCOMxx、そうでなければ@USERCOMにRESULTを渡す
  852. //case SystemStateCode.Train_CallEventCom://@EVENTCOMの呼び出し中
  853. //case SystemStateCode.Train_CallComXX://@COMxxの呼び出し中
  854. //case SystemStateCode.Train_CallSourceCheck://@SOURCE_CHECKの呼び出し中
  855. case SystemStateCode.Train_CallEventComEnd://@EVENTCOMENDの呼び出し中。スキップ可能。Train_CallEventTrainへ帰る。@USERCOMの呼び出し中もここ
  856. break;
  857. default:
  858. exm.Console.PrintSystemLine(state.SystemState.ToString());
  859. throw new CodeEE("DOTRAIN命令をこの位置で実行することはできません");
  860. }
  861. coms.Clear();
  862. isCTrain = false;
  863. count = 0;
  864. Int64 train = ((ExpressionArgument)func.Argument).Term.GetIntValue(exm);
  865. if (train < 0)
  866. throw new CodeEE("DOTRAIN命令に0未満の値が渡されました");
  867. if (train >= _trainName.Length)
  868. throw new CodeEE("DOTRAIN命令にTRAINNAMEの配列数以上の値が渡されました");
  869. doTrainSelectCom = train;
  870. state.SystemState = SystemStateCode.Train_DoTrain;
  871. return false;
  872. }
  873. #if DEBUG
  874. default:
  875. throw new ExeEE("未定義の関数です");
  876. #endif
  877. }
  878. return true;
  879. }
  880. List<ProcessState> prevStateList = new List<ProcessState>();
  881. public void saveCurrentState(bool single)
  882. {
  883. //怖いところだが、現状起こらない現象なので一旦消してみる
  884. //if (single && (prevStateList.Count > 0))
  885. // throw new ExeEE("記憶している状態があるのに再度記憶しようとした");
  886. if (state != null)
  887. {
  888. prevStateList.Add(state);
  889. state = state.Clone();
  890. }
  891. }
  892. public void loadPrevState()
  893. {
  894. //怖いところだが、現状起こらない現象なので一旦消してみる
  895. //if (prevStateList.Count == 0)
  896. // throw new ExeEE("記憶している状態がないのに呼び戻しされた");
  897. if (state != null)
  898. {
  899. state.ClearFunctionList();
  900. state = prevStateList[prevStateList.Count - 1];
  901. deletePrevState();
  902. }
  903. }
  904. private void deletePrevState()
  905. {
  906. if (prevStateList.Count == 0)
  907. return;
  908. prevStateList.RemoveAt(prevStateList.Count - 1);
  909. }
  910. private void deleteAllPrevState()
  911. {
  912. foreach (ProcessState state in prevStateList)
  913. state.ClearFunctionList();
  914. prevStateList.Clear();
  915. }
  916. public ProcessState getCurrentState => state;
  917. #endregion
  918. }
  919. }