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); }
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); }
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]); } } }
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]); } } }
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); }
/// <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); }
public void ShiftNextLine() { currentLine = currentLine.NextLine; //nextLine = nextLine.NextLine; //RunningLine = null; //sequential = true; //GlobalStatic.Process.lineCount++; lineCount++; }
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(); }
/// <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; }
private LogicalLine addLine(LogicalLine nextLine, LogicalLine lastLine) { if (nextLine == null) return null; enabledLineCount++; lastLine.NextLine = nextLine; return nextLine; }
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); }
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; } }
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; }
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; }
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); }
//外から見えるのはここだけ /// <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); }