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);
        }
        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);
        }
Example #3
0
 /// <summary>
 /// 関数内の移動。JUMPではなくGOTOやIF文など
 /// </summary>
 /// <param name="line"></param>
 public void JumpTo(LogicalLine line)
 {
     currentLine = line;
     lineCount++;
     //sequential = false;
     //ShfitNextLine();
 }
Example #4
0
 public void ShiftNextLine()
 {
     currentLine = currentLine.NextLine;
     //nextLine = nextLine.NextLine;
     //RunningLine = null;
     //sequential = true;
     //GlobalStatic.Process.lineCount++;
     lineCount++;
 }
Example #5
0
        public ScriptPosition GetRunningPosition()
        {
            LogicalLine line = state.ErrorLine;

            if (line == null)
            {
                return(null);
            }
            return(line.Position);
        }
Example #6
0
        public void DoScript()
        {
            startTime       = _Library.WinmmTimer.TickCount;
            state.lineCount = 0;
            bool systemProcRunning = true;

            //uint sp = 0;
            //List<uint> spl = new List<uint>();

            try
            {
                //int i = 0;
                while (true)
                {
                    methodStack       = 0;
                    systemProcRunning = true;
                    while (state.ScriptEnd && console.IsRunning)
                    {
                        runSystemProc();
                    }

                    if (!console.IsRunning)
                    {
                        //Console.Write("test");
                        break;
                    }
                    systemProcRunning = false;

                    //sp = _Library.WinmmTimer.TickCount;
                    runScriptProc();
                    //spl.Add(_Library.WinmmTimer.TickCount - sp);

                    //++i;
                }
            }
            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);
                }
            }
        }
Example #7
0
        internal LogicalLine GetScaningLine()
        {
            if (scaningLine != null)
            {
                return(scaningLine);
            }
            LogicalLine line = state.ErrorLine;

            if (line == null)
            {
                return(null);
            }
            return(line);
        }
Example #8
0
        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 = _Library.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 = string.Format("無限ループの可能性があります");
            string text    = string.Format(
                "現在、{0}の{1}行目を実行中です。\n最後の入力から{3}ミリ秒経過し{2}行が実行されました。\n処理を中断し強制終了しますか?",
                currentLine.Position.Filename, currentLine.Position.LineNo, state.lineCount, time);
            DialogResult result = MessageBox.Show(text, caption, MessageBoxButtons.YesNo);

            if (result == DialogResult.Yes)
            {
                throw new CodeEE("無限ループの疑いにより強制終了が選択されました");
            }
            else
            {
                state.lineCount = 0;
                startTime       = _Library.WinmmTimer.TickCount;
            }
        }
Example #9
0
        public void DoScript()
        {
            startTime       = _Library.WinmmTimer.TickCount;
            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();
                }
            }
            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);
                }
            }
        }
Example #10
0
 private void handleExceptionInSystemProc(Exception exc, LogicalLine current, bool playSound)
 {
     console.ThrowError(playSound);
     if (exc is CodeEE)
     {
         console.PrintError("関数の終端でエラーが発生しました:" + Program.ExeName);
         console.PrintError(exc.Message);
     }
     else if (exc is ExeEE)
     {
         console.PrintError("関数の終端でEmueraのエラーが発生しました:" + Program.ExeName);
         console.PrintError(exc.Message);
     }
     else
     {
         console.PrintError("関数の終端で予期しないエラーが発生しました:" + Program.ExeName);
         console.PrintError(exc.GetType().ToString() + ":" + exc.Message);
         string[] stack = exc.StackTrace.Split('\n');
         for (int i = 0; i < stack.Length; i++)
         {
             console.PrintError(stack[i]);
         }
     }
 }
Example #11
0
 public void ReturnF(SingleTerm ret)
 {
     //読み込み時のチェック済みのはず
     //if (!IsFunctionMethod)
     //    throw new ExeEE("ReturnFと#FUNCTIONのチェックがおかしい");
     //sequential = false;//いずれにしろ順列ではない。
     //呼び出し元はRETURNFコマンドか関数終了時のみ
     //if (functionList.Count == 0)
     //    throw new ExeEE("実行中の関数が存在しません");
     //非イベント呼び出しなので、これは起こりえない
     //else if (functionList.Count != 1)
     //    throw new ExeEE("関数が複数ある");
     if (Program.DebugMode)
     {
         console.DebugRemoveTraceLog();
     }
     //OutはGetValue側で行う
     //functionList[0].TopLabel.Out();
     currentLine = functionList[functionList.Count - 1].ReturnAddress;
     functionList.RemoveAt(functionList.Count - 1);
     //nextLine = null;
     MethodReturnValue = ret;
     return;
 }
Example #12
0
 private void runScriptProc()
 {
     while (true)
     {
         //bool sequential = state.Sequential;
         state.ShiftNextLine();
         //WinmmTimerから時間を取得するのはそれ自体結構なコストがかかるので10000行に一回くらいで。
         if (Config.InfiniteLoopAlertTime > 0 && (state.lineCount % 10000 == 0))
         {
             checkInfiniteLoop();
         }
         LogicalLine     line = state.CurrentLine;
         InstructionLine func = line as InstructionLine;
         //これがNULLになる様な処理は現状ないはず
         //if (line == null)
         //	throw new ExeEE("Emuera.exeは次に実行する行を見失いました");
         if (line.IsError)
         {
             throw new CodeEE(line.ErrMes);
         }
         else if (func != null)
         {                //1753 InstructionLineを先に持ってきてみる。わずかに速くなった気がしないでもない
             if (!Program.DebugMode && func.Function.IsDebug())
             {            //非DebugモードでのDebug系命令。何もしない。(SIF文のためにコメント行扱いにはできない)
                 continue;
             }
             if (func.Argument == null)
             {
                 ArgumentParser.SetArgumentTo(func);
                 if (func.IsError)
                 {
                     throw new CodeEE(func.ErrMes);
                 }
             }
             if ((skipPrint) && (func.Function.IsPrint()))
             {
                 if ((userDefinedSkip) && (func.Function.IsInput()))
                 {
                     console.PrintError("表示スキップ中にデフォルト値を持たないINPUTに遭遇しました");
                     console.PrintError("INPUTに必要な処理をNOSKIP~ENDNOSKIPで囲むか、SKIPDISP 0~SKIPDISP 1で囲ってください");
                     throw new CodeEE("無限ループに入る可能性が高いため実行を終了します");
                 }
                 continue;
             }
             if (func.Function.Instruction != null)
             {
                 func.Function.Instruction.DoInstruction(exm, func, state);
             }
             else if (func.Function.IsFlowContorol())
             {
                 doFlowControlFunction(func);
             }
             else
             {
                 doNormalFunction(func);
             }
         }
         else if ((line is NullLine) || (line is FunctionLabelLine))
         {                //(関数終端) or ファイル終端
             //if (sequential)
             //{//流れ落ちてきた
             if (!state.IsFunctionMethod)
             {
                 vEvaluator.RESULT = 0;
             }
             state.Return(0);
             //}
             //1750 飛んできた直後にShiftNextが入るのでここが実行されることは無いはず
             //else//CALLやJUMPで飛んできた
             //return;
         }
         else if (line is GotoLabelLine)
         {
             continue;                    //$ラベル。何もすることはない。
         }
         else if (line is InvalidLine)
         {
             if (string.IsNullOrEmpty(line.ErrMes))
             {
                 throw new CodeEE("読込に失敗した行が実行されました。エラーの詳細は読込時の警告を参照してください。");
             }
             else
             {
                 throw new CodeEE(line.ErrMes);
             }
         }
         //現在そんなものはない
         //else
         //	throw new ExeEE("定義されていない種類の行です");
         if (!console.IsRunning || state.ScriptEnd)
         {
             return;
         }
     }
 }
Example #13
0
        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);
        }
Example #14
0
        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 + "の" + position.LineNo.ToString() + "行目で";
                }
                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が発生しました", position);
                        if (position.RowLine != null)
                        {
                            console.PrintError(position.RowLine);
                        }
                        console.PrintError("THROW内容:" + exc.Message);
                    }
                    else
                    {
                        console.PrintErrorButton(posString + "エラーが発生しました:" + Program.ExeName, position);
                        if (position.RowLine != null)
                        {
                            console.PrintError(position.RowLine);
                        }
                        console.PrintError("エラー内容:" + exc.Message);
                    }
                    console.PrintError("現在の関数:@" + current.ParentLabelLine.LabelName + "(" + current.ParentLabelLine.Position.Filename + "の" + current.ParentLabelLine.Position.LineNo.ToString() + "行目)");
                    console.PrintError("関数呼び出しスタック:");
                    LogicalLine parent = null;
                    int         depth  = 0;
                    while ((parent = state.GetReturnAddressSequensial(depth++)) != null)
                    {
                        if (parent.Position != null)
                        {
                            console.PrintErrorButton("↑" + parent.Position.Filename + "の" + parent.Position.LineNo.ToString() + "行目(関数@" + parent.ParentLabelLine.LabelName + "内)", parent.Position);
                        }
                    }
                }
                else
                {
                    console.PrintError(posString + "エラーが発生しました:" + Program.ExeName);
                    console.PrintError(exc.Message);
                }
            }
            else if (exc is ExeEE)
            {
                console.PrintError(posString + "Emueraのエラーが発生しました:" + Program.ExeName);
                console.PrintError(exc.Message);
            }
            else
            {
                console.PrintError(posString + "予期しないエラーが発生しました:" + Program.ExeName);
                console.PrintError(exc.GetType().ToString() + ":" + exc.Message);
                string[] stack = exc.StackTrace.Split('\n');
                for (int i = 0; i < stack.Length; i++)
                {
                    console.PrintError(stack[i]);
                }
            }
        }
Example #15
0
        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;
        }
Example #16
0
 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 updateRetAddress(LogicalLine line)
 {
     ReturnAddress = line;
 }