Пример #1
0
        public LocalVariableToken GetNewLocalVariableToken(string subKey, FunctionLabelLine func)
        {
            LocalVariableToken ret = null;
            int newSize            = 0;

            if (varCode == VariableCode.LOCAL)
            {
                newSize = func.LocalLength;
            }
            else if (varCode == VariableCode.LOCALS)
            {
                newSize = func.LocalsLength;
            }
            else if (varCode == VariableCode.ARG)
            {
                newSize = func.ArgLength;
            }
            else if (varCode == VariableCode.ARGS)
            {
                newSize = func.ArgsLength;
            }
            if (newSize > 0)
            {
                if ((newSize < size) && ((varCode == VariableCode.ARG) || (varCode == VariableCode.ARGS)))
                {
                    newSize = size;
                }
                ret = creater(varCode, subKey, newSize);
            }
            else if (newSize == 0)
            {
                ret = creater(varCode, subKey, size);
            }
            else
            {
                ret = creater(varCode, subKey, size);
                LogicalLine line = GlobalStatic.Process.GetScaningLine();
                if (line != null)
                {
                    if (!func.IsSystem)
                    {
                        ParserMediator.Warn("関数宣言に引数変数\"" + varCode + "\"が使われていない関数中で\"" + varCode + "\"が使われています(関数の引数以外の用途に使うことは推奨されません。代わりに#DIMの使用を検討してください)", line, 1, false, false);
                    }
                    else
                    {
                        ParserMediator.Warn("システム関数" + func.LabelName + "中で\"" + varCode + "\"が使われています(関数の引数以外の用途に使うことは推奨されません。代わりに#DIMの使用を検討してください)", line, 1, false, false);
                    }
                }
                //throw new CodeEE("この関数に引数変数\"" + varCode + "\"は定義されていません");
            }
            localVarTokens.Add(subKey, ret);
            return(ret);
        }
Пример #2
0
 public static void Warn(string str, LogicalLine line, int level, bool isError, bool isBackComp, string stack)
 {
     if (isError)
     {
         line.IsError = true;
         line.ErrMes  = str;
     }
     if (level < Config.DisplayWarningLevel && !Program.AnalysisMode)
     {
         return;
     }
     if (isBackComp && !Config.WarnBackCompatibility)
     {
         return;
     }
     if (console != null && !console.RunERBFromMemory)
     {
         warningList.Add(new ParserWarning(str, line.Position, level, stack));
     }
     //				console.PrintWarning(str, line.Position, level);
 }
Пример #3
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]);
         }
     }
 }
Пример #4
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が発生しました", "openFileWithDebug", position);
                        if (position.RowLine != null)
                            console.PrintError(position.RowLine);
                        console.PrintError("THROW内容:" + exc.Message);
                    }
                    else
                    {
                        console.PrintErrorButton(posString + "エラーが発生しました:" + Program.ExeName, "openFileWithDebug", 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 + "内)", "openFileWithDebug", 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]);
                }
            }
        }
Пример #5
0
 public static void Warn(string str, LogicalLine line, int level, bool isError, bool isBackComp, string stack)
 {
     if (isError)
     {
         line.IsError = true;
         line.ErrMes = str;
     }
     if (level < Config.DisplayWarningLevel && !Program.AnalysisMode)
         return;
     if (isBackComp && !Config.WarnBackCompatibility)
         return;
     if (console != null && !console.RunERBFromMemory)
         warningList.Add(new ParserWarning(str, line.Position, level, stack));
     //				console.PrintWarning(str, line.Position, level);
 }
Пример #6
0
 /// <summary>
 /// Parser中での警告出力
 /// </summary>
 /// <param name="str"></param>
 /// <param name="line"></param>
 /// <param name="level">警告レベル.0:軽微なミス.1:無視できる行.2:行が実行されなければ無害.3:致命的</param>
 public static void Warn(string str, LogicalLine line, int level, bool isError, bool isBackComp)
 {
     Warn(str, line, level, isError, isBackComp, null);
 }
Пример #7
0
 public void ShiftNextLine()
 {
     currentLine = currentLine.NextLine;
     //nextLine = nextLine.NextLine;
     //RunningLine = null;
     //sequential = true;
     //GlobalStatic.Process.lineCount++;
     lineCount++;
 }
Пример #8
0
 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();
 }
Пример #9
0
 /// <summary>
 /// 関数内の移動。JUMPではなくGOTOやIF文など
 /// </summary>
 /// <param name="line"></param>
 public void JumpTo(LogicalLine line)
 {
     currentLine = line;
     lineCount++;
     //sequential = false;
     //ShfitNextLine();
 }
 public void updateRetAddress(LogicalLine line)
 {
     returnAddress = line;
 }
 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 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;
 }
Пример #13
0
 private LogicalLine addLine(LogicalLine nextLine, LogicalLine lastLine)
 {
     if (nextLine == null)
         return null;
     enabledLineCount++;
     lastLine.NextLine = nextLine;
     return nextLine;
 }
Пример #14
0
        private void printFunctionNotFoundWarning(string str, LogicalLine line, int level, bool isError)
        {
            if (Program.AnalysisMode)
            {
                if (warningDic.ContainsKey(str))
                    warningDic[str]++;
                else
                    warningDic.Add(str, 1);
                return;
            }
            if (isError)
            {
                line.IsError = true;
                line.ErrMes = str;
            }
            if (level < Config.DisplayWarningLevel)
                return;
            bool ignore = false;
            DisplayWarningFlag warnFlag = Config.FunctionNotFoundWarning;
            if (warnFlag == DisplayWarningFlag.IGNORE)
                ignore = true;
            else if (warnFlag == DisplayWarningFlag.DISPLAY)
                ignore = false;
            else if (warnFlag == DisplayWarningFlag.ONCE)
            {

                string filename = line.Position.Filename.ToUpper();
                if (!string.IsNullOrEmpty(filename))
                {
                    if (ignoredFNFWarningFileList.Contains(filename))
                    {
                        ignore = true;
                    }
                    else
                    {
                        ignore = false;
                        ignoredFNFWarningFileList.Add(filename);
                    }
                }
            }
            if (ignore && !Program.AnalysisMode)
            {
                ignoredFNFWarningCount++;
                return;
            }
            ParserMediator.Warn(str, line, level, isError, false);
        }
Пример #15
0
 private void newGeneration()
 {
     //値の入力を求められない時は更新は必要ないはず
     if (state != ConsoleState.WaitInteger && state != ConsoleState.WaitIntegerWithTimer && state != ConsoleState.WaitString && state != ConsoleState.WaitStringWithTimer && state != ConsoleState.WaitSystemInteger
         && state != ConsoleState.WaitOneInteger && state != ConsoleState.WaitOneString && state != ConsoleState.WaitOneIntegerWithTimer && state != ConsoleState.WaitOneStringWithTimer)
         return;
     if (!updatedGeneration && emuera.getCurrentLine != lastInputLine)
     {
         //ボタン無しで次の入力に来たなら強制で世代更新
         lastButtonGeneration = newButtonGeneration;
     }
     else
         updatedGeneration = false;
     lastInputLine = emuera.getCurrentLine;
     //古い選択肢を選択できないように。INPUTで使った選択肢をINPUTSには流用できないように。
     if ((state == ConsoleState.WaitInteger) || (state == ConsoleState.WaitSystemInteger) || (state == ConsoleState.WaitIntegerWithTimer) || (state == ConsoleState.WaitOneInteger) || (state == ConsoleState.WaitOneIntegerWithTimer))
     {
         if (lastButtonGeneration == newButtonGeneration)
             unchecked { newButtonGeneration++; }
         else if (!lastButoonIsInput)
             lastButtonGeneration = newButtonGeneration;
         lastButoonIsInput = true;
     }
     if (state == ConsoleState.WaitString || state == ConsoleState.WaitStringWithTimer || state == ConsoleState.WaitOneString || state == ConsoleState.WaitOneStringWithTimer)
     {
         if (lastButtonGeneration == newButtonGeneration)
             unchecked { newButtonGeneration++; }
         else if (lastButoonIsInput)
             lastButtonGeneration = newButtonGeneration;
         lastButoonIsInput = false;
     }
 }
Пример #16
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;
 }
Пример #17
0
 /// <summary>
 /// Parser中での警告出力
 /// </summary>
 /// <param name="str"></param>
 /// <param name="line"></param>
 /// <param name="level">警告レベル.0:軽微なミス.1:無視できる行.2:行が実行されなければ無害.3:致命的</param>
 public static void Warn(string str, LogicalLine line, int level, bool isError, bool isBackComp)
 {
     Warn(str, line, level, isError, isBackComp, null);
 }
Пример #18
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;
 }
Пример #19
0
        public VariableToken GetVariableToken(string key, string subKey, bool allowPrivate)
        {
            VariableToken ret = null;

            if (Config.ICVariable)
            {
                key = key.ToUpper();
            }
            if (allowPrivate)
            {
                LogicalLine line = GlobalStatic.Process.GetScaningLine();
                if ((line != null) && (line.ParentLabelLine != null))
                {
                    ret = line.ParentLabelLine.GetPrivateVariable(key);
                    if (ret != null)
                    {
                        if (subKey != null)
                        {
                            throw new CodeEE("プライベート変数" + key + "に対して@が使われました");
                        }
                        return(ret);
                    }
                }
            }
            if (localvarTokenDic.ContainsKey(key))
            {
                if (localvarTokenDic[key].IsForbid)
                {
                    throw new CodeEE("呼び出された変数\"" + key + "\"は設定により使用が禁止されています");
                }
                LogicalLine line = GlobalStatic.Process.GetScaningLine();
                if (string.IsNullOrEmpty(subKey))
                {
                    //システムの入力待ち中にデバッグコマンドからLOCALを呼んだとき。
                    if ((line == null) || (line.ParentLabelLine == null))
                    {
                        throw new CodeEE("実行中の関数が存在しないため" + key + "を取得又は変更できませんでした");
                    }
                    subKey = line.ParentLabelLine.LabelName;
                }
                else
                {
                    ParserMediator.Warn("コード中でローカル変数を@付きで呼ぶことは推奨されません(代わりに*.ERHファイルの利用を検討してください)", line, 1, false, false);
                    if (Config.ICFunction)
                    {
                        subKey = subKey.ToUpper();
                    }
                }
                LocalVariableToken retLocal = localvarTokenDic[key].GetExistLocalVariableToken(subKey);
                if (retLocal == null)
                {
                    retLocal = localvarTokenDic[key].GetNewLocalVariableToken(subKey, line.ParentLabelLine);
                }
                return(retLocal);
            }
            if (varTokenDic.TryGetValue(key, out ret))
            {
                //一文字変数の禁止オプションを考えた名残
                //if (Config.ForbidOneCodeVariable && ret.CanForbid)
                //    throw new CodeEE("設定によりシステム一文字数値変数の使用が禁止されています(呼び出された変数:" + ret.Name +")");
                if (ret.IsForbid)
                {
                    if (!ret.CanForbid)
                    {
                        throw new ExeEE("CanForbidでない変数\"" + ret.Name + "\"にIsForbidがついている");
                    }
                    throw new CodeEE("呼び出された変数\"" + ret.Name + "\"は設定により使用が禁止されています");
                }
                if (subKey != null)
                {
                    throw new CodeEE("ローカル変数でない変数" + key + "に対して@が使われました");
                }
                return(ret);
            }
            if (subKey != null)
            {
                throw new CodeEE("@の使い方が不正です");
            }
            return(null);
        }
Пример #20
0
        //外から見えるのはここだけ
        /// <summary>
        /// 一行分のTokenCollectionからLogicalLineを作成する
        /// </summary>
        /// <param defaultName="parser"></param>
        /// <returns></returns>
        internal static LogicalLine GetCodeToken(TokenCollection stream)
        {
            if (stream == null)
            {
                return(null);
            }
            if (stream.Count == 0)
            {
                return(null);
            }
            if (stream.NextIsEndOfStream)
            {
                return(null);
            }
            LogicalLine line = null;

            try
            {
                if (stream.NextToken is IfStatementPrimitive)                 //if, else行
                {
                    return((LogicalLine)readIf(stream));
                }
                if (stream.NextToken is McallFunctionPrimitive)                 //on行
                {
                    return((LogicalLine)readMcall(stream));
                }
                if (stream.NextToken is OnEventFunctionPrimitive)
                {                                           //on###行
                    if (stream.NextNextTokenIsGotoFunction) //goto/gosubがないなら
                    {
                        return((LogicalLine)readOnEvent(stream));
                    }
                    else
                    {
                        return((LogicalLine)readCommand(stream));
                    }
                }
                if (stream.NextToken is OnFunctionPrimitive)                 //on行
                {
                    return((LogicalLine)readOn(stream));
                }
                if (stream.NextToken is FunctionPrimitive)                //その他の関数
                {
                    return((LogicalLine)readCommand(stream));
                }
                if (stream.NextToken is VariablePrimitive)                //代入行
                {
                    return((LogicalLine)readAssignment(stream));
                }
            }
            //ここでHspLogicalLineExceptionをcatchする。他のところでは行ってはならない
            catch (HspLogicalLineException e)
            {
                line = new UnknownLine(stream.Primitives);
                line.AddError(e.Message);
                return(line);
            }
            line = new UnknownLine(stream.Primitives);
            line.AddError("?行:先頭の単語が解釈できない");
            return(line);
        }