public static CalledFunction CallEventFunction(Process parent, string label, LogicalLine retAddress) { var called = new CalledFunction(label); var newLabelList = new List <FunctionLabelLine>(); called.Finished = false; called.eventLabelList = parent.LabelDictionary.GetEventLabels(label); if (called.eventLabelList == null) { var line = parent.LabelDictionary.GetNonEventLabel(label); if (parent.LabelDictionary.GetNonEventLabel(label) != null) { throw new CodeEE("イベント関数でない関数@" + label + "(" + line.Position.Filename + ":" + line.Position.LineNo + "行目)に対しEVENT呼び出しが行われました"); } return(null); } called.counter = -1; called.group = 0; called.ShiftNext(); called.TopLabel = called.CurrentLabel; called.ReturnAddress = retAddress; called.IsEvent = true; return(called); }
private bool callFunction(string functionName, bool force, bool isEvent) { CalledFunction call = null; if (isEvent) { call = CalledFunction.CallEventFunction(this, functionName, null); } else { call = CalledFunction.CallFunction(this, functionName, null); } if (call == null) { if (!force) { return(false); } else { throw new CodeEE("関数\"@" + functionName + "\"が見つかりません"); } } //そもそも非イベント関数では関数1個分しか与えないので条件を満たすわけがない //if ((!isEvent) && (call.Count > 1)) // throw new ExeEE("イベント関数でない関数\"@" + functionName + "\"の候補が複数ある"); state.IntoFunction(call, null, null); return(true); }
public static CalledFunction CallFunction(Process parent, string label, LogicalLine retAddress) { var called = new CalledFunction(label); called.Finished = false; var labelline = parent.LabelDictionary.GetNonEventLabel(label); if (labelline == null) { if (parent.LabelDictionary.GetEventLabels(label) != null) { throw new CodeEE("イベント関数@" + label + "に対し通常のCALLが行われました(このエラーは互換性オプション「" + Config.GetConfigName(ConfigCode.CompatiCallEvent) + "」により無視できます)"); } return(null); } if (labelline.IsMethod) { throw new CodeEE("#FUCNTION(S)が定義された関数@" + labelline.LabelName + "(" + labelline.Position.Filename + ":" + labelline.Position.LineNo + "行目)に対し通常のCALLが行われました"); } called.TopLabel = labelline; called.CurrentLabel = labelline; called.ReturnAddress = retAddress; called.IsEvent = false; return(called); }
public void SetBegin(BeginType type) { string errmes = ""; switch (type) { case BeginType.SHOP: case BeginType.TRAIN: case BeginType.AFTERTRAIN: case BeginType.ABLUP: case BeginType.TURNEND: case BeginType.FIRST: if ((sysStateCode & SystemStateCode.__CAN_BEGIN__) != SystemStateCode.__CAN_BEGIN__) { errmes = "BEGIN"; goto err; } break; //1.729 BEGIN TITLEはどこでも使えるように case BeginType.TITLE: break; //BEGINの処理中でチェック済み //default: // throw new ExeEE("不適当なBEGIN呼び出し"); } begintype = type; return; err: CalledFunction func = functionList[0]; string funcName = func.FunctionName; throw new CodeEE("@" + funcName + "中で" + errmes + "命令を実行することはできません"); }
/// <summary> /// エラーならnullを返す。 /// </summary> public static UserDefinedMethodTerm Create(IOperandTerm[] srcArgs, CalledFunction call, out string errMes) { UserDefinedFunctionArgument arg = call.ConvertArg(srcArgs, out errMes); if (arg == null) return null; return new UserDefinedMethodTerm(arg, call.TopLabel.MethodType, call); }
public static CalledFunction CreateCalledFunctionMethod(FunctionLabelLine labelline, string label) { var called = new CalledFunction(label); called.TopLabel = labelline; called.CurrentLabel = labelline; called.ReturnAddress = null; called.IsEvent = false; return(called); }
public CalledFunction Clone() { var called = new CalledFunction(FunctionName); called.eventLabelList = eventLabelList; called.CurrentLabel = CurrentLabel; called.TopLabel = TopLabel; called.group = group; called.IsEvent = IsEvent; called.counter = counter; called.ReturnAddress = ReturnAddress; return(called); }
public CalledFunction Clone() { CalledFunction called = new CalledFunction(this.FunctionName); called.eventLabelList = this.eventLabelList; called.CurrentLabel = this.CurrentLabel; called.TopLabel = this.TopLabel; called.group = this.group; called.IsEvent = this.IsEvent; called.counter = this.counter; called.returnAddress = this.returnAddress; return(called); }
public void ClearFunctionList() { if (Program.DebugMode && !isClone && GlobalStatic.Process.MethodStack() == 0) { console.DebugClearTraceLog(); } CalledFunction called = null; var count = functionList.Count; for (var i = 0; i < count; ++i) { called = functionList[i]; if (called.CurrentLabel.hasPrivDynamicVar) { called.CurrentLabel.Out(); } } functionList.Clear(); begintype = BeginType.NULL; }
bool doFlowControlFunction(InstructionLine func) { switch (func.FunctionCode) { case FunctionCode.LOADDATA: { ExpressionArgument intExpArg = (ExpressionArgument)func.Argument; Int64 target = intExpArg.Term.GetIntValue(exm); if (target < 0) { throw new CodeEE("LOADDATAの引数に負の値(" + target.ToString() + ")が指定されました"); } else if (target > int.MaxValue) { throw new CodeEE("LOADDATAの引数(" + target.ToString() + ")が大きすぎます"); } //EraDataResult result = vEvaluator.checkData((int)target); EraDataResult result = vEvaluator.CheckData((int)target, EraSaveFileType.Normal); if (result.State != EraDataState.OK) { throw new CodeEE("不正なデータをロードしようとしました"); } if (!vEvaluator.LoadFrom((int)target)) { throw new ExeEE("ファイルのロード中に予期しないエラーが発生しました"); } state.ClearFunctionList(); state.SystemState = SystemStateCode.LoadData_DataLoaded; return(false); } case FunctionCode.TRYCALLLIST: case FunctionCode.TRYJUMPLIST: { //if (!sequential)//RETURNで帰ってきた //{ // state.JumpTo(func.JumpTo); // break; //} string funcName = ""; CalledFunction callto = null; SpCallArgment cfa = null; foreach (InstructionLine iLine in func.callList) { cfa = (SpCallArgment)iLine.Argument; funcName = cfa.FuncnameTerm.GetStrValue(exm); if (Config.ICFunction) { funcName = funcName.ToUpper(); } callto = CalledFunction.CallFunction(this, funcName, func.JumpTo); if (callto == null) { continue; } callto.IsJump = func.Function.IsJump(); string errMes; UserDefinedFunctionArgument args = callto.ConvertArg(cfa.RowArgs, out errMes); if (args == null) { throw new CodeEE(errMes); } state.IntoFunction(callto, args, exm); return(true); } state.JumpTo(func.JumpTo); } break; case FunctionCode.TRYGOTOLIST: { string funcName = ""; LogicalLine jumpto = null; foreach (InstructionLine iLine in func.callList) { if (iLine.Argument == null) { ArgumentParser.SetArgumentTo(iLine); } funcName = ((SpCallArgment)iLine.Argument).FuncnameTerm.GetStrValue(exm); if (Config.ICVariable) { funcName = funcName.ToUpper(); } jumpto = state.CurrentCalled.CallLabel(this, funcName); if (jumpto != null) { break; } } if (jumpto == null) { state.JumpTo(func.JumpTo); } else { state.JumpTo(jumpto); } } break; case FunctionCode.CALLTRAIN: { ExpressionArgument intExpArg = (ExpressionArgument)func.Argument; Int64 count = intExpArg.Term.GetIntValue(exm); SetCommnds(count); return(false); } case FunctionCode.STOPCALLTRAIN: { if (isCTrain) { ClearCommands(); skipPrint = false; } return(false); } case FunctionCode.DOTRAIN: { switch (state.SystemState) { //case SystemStateCode.Train_Begin://BEGIN TRAINから。 case SystemStateCode.Train_CallEventTrain: //@EVENTTRAINの呼び出し中。スキップ可能 case SystemStateCode.Train_CallShowStatus: //@SHOW_STATUSの呼び出し中 //case SystemStateCode.Train_CallComAbleXX://@COM_ABLExxの呼び出し中。 case SystemStateCode.Train_CallShowUserCom: //@SHOW_USERCOMの呼び出し中 //case SystemStateCode.Train_WaitInput://入力待ち状態。選択が実行可能ならEVENTCOMからCOMxx、そうでなければ@USERCOMにRESULTを渡す //case SystemStateCode.Train_CallEventCom://@EVENTCOMの呼び出し中 //case SystemStateCode.Train_CallComXX://@COMxxの呼び出し中 //case SystemStateCode.Train_CallSourceCheck://@SOURCE_CHECKの呼び出し中 case SystemStateCode.Train_CallEventComEnd: //@EVENTCOMENDの呼び出し中。スキップ可能。Train_CallEventTrainへ帰る。@USERCOMの呼び出し中もここ break; default: exm.Console.PrintSystemLine(state.SystemState.ToString()); throw new CodeEE("DOTRAIN命令をこの位置で実行することはできません"); } coms.Clear(); isCTrain = false; this.count = 0; Int64 train = ((ExpressionArgument)func.Argument).Term.GetIntValue(exm); if (train < 0) { throw new CodeEE("DOTRAIN命令に0未満の値が渡されました"); } if (train >= TrainName.Length) { throw new CodeEE("DOTRAIN命令にTRAINNAMEの配列数以上の値が渡されました"); } doTrainSelectCom = train; state.SystemState = SystemStateCode.Train_DoTrain; return(false); } #if DEBUG default: throw new ExeEE("未定義の関数です"); #endif } return(true); }
public static CalledFunction CreateCalledFunctionMethod(FunctionLabelLine labelline, string label) { CalledFunction called = new CalledFunction(label); called.TopLabel = labelline; called.CurrentLabel = labelline; called.returnAddress = null; return called; }
public static CalledFunction CallFunction(Process parent, string label, LogicalLine retAddress) { CalledFunction called = new CalledFunction(label); called.Finished = false; FunctionLabelLine labelline = parent.LabelDictionary.GetNonEventLabel(label); if (labelline == null) { if (parent.LabelDictionary.GetEventLabels(label) != null) { throw new CodeEE("イベント関数@" + label + "に対し通常のCALLが行われました"); } return null; } else if (labelline.IsMethod) { throw new CodeEE("#FUCNTION(S)が定義された関数@" + labelline.LabelName + "(" + labelline.Position.Filename + ":" + labelline.Position.LineNo.ToString() + "行目)に対し通常のCALLが行われました"); } called.TopLabel = labelline; called.CurrentLabel = labelline; called.returnAddress = retAddress; return called; }
public static CalledFunction CallEventFunction(Process parent, string label, LogicalLine retAddress) { CalledFunction called = new CalledFunction(label); List<FunctionLabelLine> newLabelList = new List<FunctionLabelLine>(); called.Finished = false; called.eventLabelList = parent.LabelDictionary.GetEventLabels(label); if (called.eventLabelList == null) { FunctionLabelLine line = parent.LabelDictionary.GetNonEventLabel(label); if (parent.LabelDictionary.GetNonEventLabel(label) != null) { throw new CodeEE("イベント関数でない関数@" + label + "(" + line.Position.Filename + ":" + line.Position.LineNo + "行目)に対しEVENT呼び出しが行われました"); } return null; } called.counter = -1; called.group = 0; called.ShiftNext(); called.TopLabel = called.CurrentLabel; called.returnAddress = retAddress; return called; }
public CalledFunction Clone() { CalledFunction called = new CalledFunction(this.FunctionName); called.eventLabelList = this.eventLabelList; called.CurrentLabel = this.CurrentLabel; called.TopLabel = this.TopLabel; called.group = this.group; called.counter = this.counter; called.returnAddress = this.returnAddress; return called; }
public void IntoFunction(CalledFunction call, UserDefinedFunctionArgument srcArgs, ExpressionMediator exm) { if (Program.DebugMode) { FunctionLabelLine label = call.CurrentLabel; if (call.IsJump) console.DebugAddTraceLog("JUMP :@" + label.LabelName + ":" + label.Position.ToString() + "行目"); else console.DebugAddTraceLog("CALL :@" + label.LabelName + ":" + label.Position.ToString() + "行目"); } if (srcArgs != null) { //引数の値を確定させる srcArgs.SetTransporter(exm); //プライベート変数更新 if (call.TopLabel.hasPrivDynamicVar) call.TopLabel.In(); //更新した変数へ引数を代入 for (int i = 0; i < call.TopLabel.Arg.Length; i++) { if (srcArgs.Arguments[i] != null) { if (call.TopLabel.Arg[i].Identifier.IsReference) ((ReferenceToken)(call.TopLabel.Arg[i].Identifier)).SetRef(srcArgs.TransporterRef[i]); else if (srcArgs.Arguments[i].GetOperandType() == typeof(Int64)) call.TopLabel.Arg[i].SetValue(srcArgs.TransporterInt[i], exm); else call.TopLabel.Arg[i].SetValue(srcArgs.TransporterStr[i], exm); } } } else//こっちに来るのはシステムからの呼び出し=引数は存在しない関数のみ ifネストの外に出していい気もしないでもないがはてさて { //プライベート変数更新 if (call.TopLabel.hasPrivDynamicVar) call.TopLabel.In(); } functionList.Add(call); //sequential = false; currentLine = call.CurrentLabel; lineCount++; //ShfitNextLine(); }
public void IntoFunction(CalledFunction call, UserDefinedFunctionArgument srcArgs, ExpressionMediator exm) { if (call.IsEvent) { foreach (CalledFunction called in functionList) { if (called.IsEvent) { throw new CodeEE("EVENT関数の解決前にCALLEVENT命令が行われました"); } } } if (Program.DebugMode) { FunctionLabelLine label = call.CurrentLabel; if (call.IsJump) { console.DebugAddTraceLog("JUMP :@" + label.LabelName + ":" + label.Position.ToString() + "行目"); } else { console.DebugAddTraceLog("CALL :@" + label.LabelName + ":" + label.Position.ToString() + "行目"); } } if (srcArgs != null) { //引数の値を確定させる srcArgs.SetTransporter(exm); //プライベート変数更新 if (call.TopLabel.hasPrivDynamicVar) { call.TopLabel.In(); } //更新した変数へ引数を代入 for (int i = 0; i < call.TopLabel.Arg.Length; i++) { if (srcArgs.Arguments[i] != null) { if (call.TopLabel.Arg[i].Identifier.IsReference) { ((ReferenceToken)(call.TopLabel.Arg[i].Identifier)).SetRef(srcArgs.TransporterRef[i]); } else if (srcArgs.Arguments[i].GetOperandType() == typeof(Int64)) { call.TopLabel.Arg[i].SetValue(srcArgs.TransporterInt[i], exm); } else { call.TopLabel.Arg[i].SetValue(srcArgs.TransporterStr[i], exm); } } } } else//こっちに来るのはシステムからの呼び出し=引数は存在しない関数のみ ifネストの外に出していい気もしないでもないがはてさて { //プライベート変数更新 if (call.TopLabel.hasPrivDynamicVar) { call.TopLabel.In(); } } functionList.Add(call); //sequential = false; currentLine = call.CurrentLabel; lineCount++; //ShfitNextLine(); }
public void Return(Int64 ret) { if (IsFunctionMethod) { ReturnF(null); return; } //sequential = false;//いずれにしろ順列ではない。 //呼び出し元は全部スクリプト処理 //if (functionList.Count == 0) //{ // throw new ExeEE("実行中の関数が存在しません"); //} CalledFunction called = functionList[functionList.Count - 1]; if (called.IsJump) { //JUMPした場合。即座にRETURN RESULTする。 if (called.TopLabel.hasPrivDynamicVar) { called.TopLabel.Out(); } functionList.Remove(called); if (Program.DebugMode) { console.DebugRemoveTraceLog(); } Return(ret); return; } if (!called.IsEvent) { if (called.TopLabel.hasPrivDynamicVar) { called.TopLabel.Out(); } currentLine = null; } else { if (called.CurrentLabel.hasPrivDynamicVar) { called.CurrentLabel.Out(); } //#Singleフラグ付き関数で1が返された。 //1752 非0ではなく1と等価であることを見るように修正 //1756 全てを終了ではなく#PRIや#LATERのグループごとに修正 if (called.IsOnly) { called.FinishEvent(); } else if ((called.HasSingleFlag) && (ret == 1)) { called.ShiftNextGroup(); } else { called.ShiftNext(); //次の同名関数に進む。 } currentLine = called.CurrentLabel; //関数の始点(@~~)へ移動。呼ぶべき関数が無ければnull if (called.CurrentLabel != null) { lineCount++; if (called.CurrentLabel.hasPrivDynamicVar) { called.CurrentLabel.In(); } } } if (Program.DebugMode) { console.DebugRemoveTraceLog(); } //関数終了 if (currentLine == null) { currentLine = called.ReturnAddress; functionList.RemoveAt(functionList.Count - 1); if (currentLine == null) { //この時点でfunctionListは空のはず //functionList.Clear();//全て終了。stateEndProcessに処理を返す if (begintype != BeginType.NULL) //BEGIN XXが行なわれていれば { Begin(); } return; } lineCount++; //ShfitNextLine(); return; } else if (Program.DebugMode) { FunctionLabelLine label = called.CurrentLabel; console.DebugAddTraceLog("CALL :@" + label.LabelName + ":" + label.Position.ToString() + "行目"); } lineCount++; //ShfitNextLine(); return; }
private UserDefinedMethodTerm(UserDefinedFunctionArgument arg, Type returnType, CalledFunction call) : base(returnType) { Argument = arg; Call = call; }
/// <summary> /// BEGIN命令によるプログラム状態の変化 /// </summary> /// <param name="key"></param> /// <returns></returns> public void Begin() { //@EVENTSHOPからの呼び出しは一旦破棄 if (sysStateCode == SystemStateCode.Shop_CallEventShop) { return; } switch (begintype) { case BeginType.SHOP: if (sysStateCode == SystemStateCode.Normal) { calledWhenNormal = true; } else { calledWhenNormal = false; } sysStateCode = SystemStateCode.Shop_Begin; break; case BeginType.TRAIN: sysStateCode = SystemStateCode.Train_Begin; break; case BeginType.AFTERTRAIN: sysStateCode = SystemStateCode.AfterTrain_Begin; break; case BeginType.ABLUP: sysStateCode = SystemStateCode.Ablup_Begin; break; case BeginType.TURNEND: sysStateCode = SystemStateCode.Turnend_Begin; break; case BeginType.FIRST: sysStateCode = SystemStateCode.First_Begin; break; case BeginType.TITLE: sysStateCode = SystemStateCode.Title_Begin; break; //セット時に判定してるので、ここには来ないはず //default: // throw new ExeEE("不適当なBEGIN呼び出し"); } if (Program.DebugMode) { console.DebugClearTraceLog(); console.DebugAddTraceLog("BEGIN:" + begintype.ToString()); } CalledFunction called = null; var count = functionList.Count; for (var i = 0; i < count; ++i) { called = functionList[i]; if (called.CurrentLabel.hasPrivDynamicVar) { called.CurrentLabel.Out(); } } functionList.Clear(); begintype = BeginType.NULL; return; }