diff --git a/VS/CSHARP/asm-dude-vsix/Resources/examples/example_semantic_analysis2.asm b/VS/CSHARP/asm-dude-vsix/Resources/examples/example_semantic_analysis2.asm index fc947a31..85bdff8b 100644 --- a/VS/CSHARP/asm-dude-vsix/Resources/examples/example_semantic_analysis2.asm +++ b/VS/CSHARP/asm-dude-vsix/Resources/examples/example_semantic_analysis2.asm @@ -11,6 +11,11 @@ label1: + mov rcx, 10 +labelx: + dec rcx + jnz labelx + mov rax, rcx aaa diff --git a/VS/CSHARP/asm-dude-vsix/Squiggles/SquigglesTagger.cs b/VS/CSHARP/asm-dude-vsix/Squiggles/SquigglesTagger.cs index d1f5af8a..13e919b9 100644 --- a/VS/CSHARP/asm-dude-vsix/Squiggles/SquigglesTagger.cs +++ b/VS/CSHARP/asm-dude-vsix/Squiggles/SquigglesTagger.cs @@ -222,9 +222,9 @@ public IEnumerable> GetTags(NormalizedSnapshotSpanCollection { if (Decorate_Syntax_Errors || Decorate_Unimplemented) { - if (this._asmSimulator.IsImplemented(lineNumber)) + if (this._asmSimulator.Is_Implemented(lineNumber)) { - if (Decorate_Syntax_Errors && this._asmSimulator.HasSyntaxError(lineNumber)) + if (Decorate_Syntax_Errors && this._asmSimulator.Has_Syntax_Error(lineNumber)) { string message = AsmSourceTools.Linewrap("Syntax Error: " + this._asmSimulator.Get_Syntax_Error(lineNumber).Message, AsmDudePackage.maxNumberOfCharsInToolTips); yield return new TagSpan(tagSpan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError, message)); @@ -376,7 +376,7 @@ private void Update_Error_Task_AsmSim(int lineNumber, AsmMessageEnum error) if (Settings.Default.AsmSim_Show_Syntax_Errors) { var tup = this._asmSimulator.Get_Syntax_Error(lineNumber); - this.AddErrorTask_SyntaxError(lineNumber, tup.Message, tup.Mnemonic); + if (tup.Message.Length > 0) this.AddErrorTask_SyntaxError(lineNumber, tup.Message, tup.Mnemonic); errorListNeedsRefresh = true; } break; @@ -386,7 +386,7 @@ private void Update_Error_Task_AsmSim(int lineNumber, AsmMessageEnum error) if (Settings.Default.AsmSim_Show_Usage_Of_Undefined) { var tup = this._asmSimulator.Get_Usage_Undefined_Warning(lineNumber); - this.AddErrorTask_UsageUndefined(lineNumber, tup); + if (tup.Length > 0) this.AddErrorTask_UsageUndefined(lineNumber, tup); errorListNeedsRefresh = true; } break; @@ -396,7 +396,7 @@ private void Update_Error_Task_AsmSim(int lineNumber, AsmMessageEnum error) if (Settings.Default.AsmSim_Show_Redundant_Instructions) { var tup = this._asmSimulator.Get_Redundant_Instruction_Warning(lineNumber); - this.AddErrorTask_RedundantInstruction(lineNumber, tup); + if (tup.Length > 0) this.AddErrorTask_RedundantInstruction(lineNumber, tup); errorListNeedsRefresh = true; } break; @@ -407,7 +407,7 @@ private void Update_Error_Task_AsmSim(int lineNumber, AsmMessageEnum error) if (errorListNeedsRefresh) { this._errorListProvider.Refresh(); - this._errorListProvider.Show(); // do not use BringToFront since that will select the error window. + //this._errorListProvider.Show(); // do not use BringToFront since that will select the error window. } } @@ -446,7 +446,7 @@ await System.Threading.Tasks.Task.Run(() => if (Settings.Default.AsmSim_Show_Syntax_Errors) { - foreach (var tup in this._asmSimulator.SyntaxErrors) + foreach (var tup in this._asmSimulator.Syntax_Errors) { this.AddErrorTask_SyntaxError(tup.LineNumber, tup.Message, tup.Mnemonic); errorListNeedsRefresh = true; @@ -472,7 +472,7 @@ await System.Threading.Tasks.Task.Run(() => if (errorListNeedsRefresh) { this._errorListProvider.Refresh(); - this._errorListProvider.Show(); // do not use BringToFront since that will select the error window. + //this._errorListProvider.Show(); // do not use BringToFront since that will select the error window. } } #endregion Update Error Tasks @@ -638,7 +638,7 @@ await System.Threading.Tasks.Task.Run(() => if (errorListNeedsRefresh) { this._errorListProvider.Refresh(); - this._errorListProvider.Show(); // do not use BringToFront since that will select the error window. + //this._errorListProvider.Show(); // do not use BringToFront since that will select the error window. } } #endregion Update Error Tasks diff --git a/VS/CSHARP/asm-dude-vsix/Tools/AsmDudeToolsStatic.cs b/VS/CSHARP/asm-dude-vsix/Tools/AsmDudeToolsStatic.cs index f80b5239..c4ea8131 100644 --- a/VS/CSHARP/asm-dude-vsix/Tools/AsmDudeToolsStatic.cs +++ b/VS/CSHARP/asm-dude-vsix/Tools/AsmDudeToolsStatic.cs @@ -495,8 +495,8 @@ public static void Disable_Message(string msg, string filename, ErrorListProvide errorTask.Navigate += AsmDudeToolsStatic.Error_Task_Navigate_Handler; errorListProvider.Tasks.Add(errorTask); - errorListProvider.Show(); // do not use BringToFront since that will select the error window. errorListProvider.Refresh(); + //errorListProvider.Show(); // do not use BringToFront since that will select the error window. } public static MicroArch Get_MicroArch_Switched_On() diff --git a/VS/CSHARP/asm-dude-vsix/Tools/AsmSimulator.cs b/VS/CSHARP/asm-dude-vsix/Tools/AsmSimulator.cs index 2ce8464c..9d010bfd 100644 --- a/VS/CSHARP/asm-dude-vsix/Tools/AsmSimulator.cs +++ b/VS/CSHARP/asm-dude-vsix/Tools/AsmSimulator.cs @@ -170,6 +170,7 @@ private AsmSimulator(ITextBuffer buffer, IBufferTagAggregatorFactoryService aggr public event EventHandler Line_Updated_Event; public event EventHandler Reset_Done_Event; + #region Reset public void Reset(int delay = -1) { this._delay.Reset(delay); @@ -236,101 +237,83 @@ void PreCalculate_LOCAL() bool update_Redundant_Instruction = Settings.Default.AsmSim_On && (Settings.Default.AsmSim_Show_Redundant_Instructions || Settings.Default.AsmSim_Decorate_Redundant_Instructions); bool update_Known_Register = Settings.Default.AsmSim_On && (Settings.Default.AsmSim_Decorate_Registers); - foreach (int lineNumber in LineNumber_Centered_LOCAL(this._sFlow.FirstLineNumber, this._last_Changed_LineNumber, this._sFlow.LastLineNumber)) { this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.USAGE_OF_UNDEFINED)); } - - foreach (int lineNumber in LineNumber_Centered_LOCAL(this._sFlow.FirstLineNumber, this._last_Changed_LineNumber, this._sFlow.LastLineNumber)) { - var syntaxInfo = this.Get_Syntax_Errors(lineNumber); - - if (!syntaxInfo.IsImplemented) // the operation is not implemented + try { - if (decorate_Not_Implemented) + var syntaxInfo = this.Calculate_Syntax_Errors(lineNumber); + if (!syntaxInfo.IsImplemented) // the operation is not implemented { - this._isNotImplemented.Add(lineNumber); - this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.NOT_IMPLEMENTED)); - } - } - else - { - if (syntaxInfo.Message != null) // found a syntax error - { - if (update_Syntax_Error) + if (decorate_Not_Implemented) { - this._syntax_Errors.Add(lineNumber, (syntaxInfo.Mnemonic, syntaxInfo.Message)); - this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.SYNTAX_ERROR)); + this._isNotImplemented.Add(lineNumber); + this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.NOT_IMPLEMENTED)); } } - else // operation is implemented and no syntax error + else { - if (update_Known_Register) + if (syntaxInfo.Message != null) // found a syntax error { - var content = this._sFlow.Get_Line(lineNumber); - foreach (var v in content.Args) + if (update_Syntax_Error) { - Rn regName = RegisterTools.ParseRn(v, true); - if (regName != Rn.NOREG) - { - this.PreCompute_Register_Value(regName, lineNumber, true); - this.PreCompute_Register_Value(regName, lineNumber, false); - this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); - } + this._syntax_Errors.Add(lineNumber, (syntaxInfo.Mnemonic, syntaxInfo.Message)); + this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.SYNTAX_ERROR)); } } - if (update_Usage_Undefined) + else // operation is implemented and no syntax error { - string message = this.Get_Usage_Undefined_Warnings(lineNumber); - if (message.Length > 0) + if (update_Known_Register) { - this._usage_Undefined.Add(lineNumber, message); - this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.USAGE_OF_UNDEFINED)); + var content = this._sFlow.Get_Line(lineNumber); + foreach (var v in content.Args) + { + Rn regName = RegisterTools.ParseRn(v, true); + if (regName != Rn.NOREG) + { + this.PreCompute_Register_Value(regName, lineNumber, true); + this.PreCompute_Register_Value(regName, lineNumber, false); + this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); + } + } } - } - if (update_Redundant_Instruction) - { - string message = this.Get_Redundant_Instruction_Warnings(lineNumber); - if (message.Length > 0) + if (update_Usage_Undefined) { + string message = this.Calculate_Usage_Undefined_Warnings(lineNumber); + if (message.Length > 0) + { + this._usage_Undefined.Add(lineNumber, message); + this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.USAGE_OF_UNDEFINED)); + } + } + if (update_Redundant_Instruction) + { + string message = this.Calculate_Redundant_Instruction_Warnings(lineNumber); + if (message.Length > 0) + { - this._redundant_Instruction.Add(lineNumber, message); - this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.REDUNDANT)); + this._redundant_Instruction.Add(lineNumber, message); + this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.REDUNDANT)); + } } } } } + catch (Exception e) + { + AsmDudeToolsStatic.Output_ERROR(string.Format("{0}:PreCalculate_LOCAL; e={1}", ToString(), e.ToString())); + } } } #endregion } - - public StaticFlow StaticFlow { get { return this._sFlow; } } - - public (bool IsImplemented, Mnemonic Mnemonic, string Message) Get_Syntax_Errors(int lineNumber) - { - var dummyKeys = ("", "", ""); - var content = this._sFlow.Get_Line(lineNumber); - var opcodeBase = Runner.InstantiateOpcode(content.Mnemonic, content.Args, dummyKeys, this.Tools); - if (opcodeBase == null) return (IsImplemented: false, Mnemonic: Mnemonic.NONE, Message: null); - - if (opcodeBase.GetType() == typeof(AsmSim.Mnemonics.NotImplemented)) - { - return (IsImplemented: false, Mnemonic: content.Mnemonic, Message: null); - } - else - { - return (opcodeBase.IsHalted) - ? (IsImplemented: true, Mnemonic: content.Mnemonic, Message: opcodeBase.SyntaxError) - : (IsImplemented: true, Mnemonic: content.Mnemonic, Message: null); - } - } + #endregion #region Syntax Errors - - public IEnumerable<(int LineNumber, Mnemonic Mnemonic, string Message)> SyntaxErrors + public IEnumerable<(int LineNumber, Mnemonic Mnemonic, string Message)> Syntax_Errors { get { @@ -340,12 +323,11 @@ void PreCalculate_LOCAL() } } } - public bool IsImplemented(int lineNumber) + public bool Is_Implemented(int lineNumber) { return !this._isNotImplemented.Contains(lineNumber); } - - public bool HasSyntaxError(int lineNumber) + public bool Has_Syntax_Error(int lineNumber) { return this._syntax_Errors.ContainsKey(lineNumber); } @@ -353,6 +335,24 @@ public bool HasSyntaxError(int lineNumber) { return this._syntax_Errors.TryGetValue(lineNumber, out (Mnemonic Mnemonic, string Message) error) ? error : (Mnemonic.NONE, ""); } + private (bool IsImplemented, Mnemonic Mnemonic, string Message) Calculate_Syntax_Errors(int lineNumber) + { + var dummyKeys = ("", "", ""); + var content = this._sFlow.Get_Line(lineNumber); + var opcodeBase = Runner.InstantiateOpcode(content.Mnemonic, content.Args, dummyKeys, this.Tools); + if (opcodeBase == null) return (IsImplemented: false, Mnemonic: Mnemonic.NONE, Message: null); + + if (opcodeBase.GetType() == typeof(AsmSim.Mnemonics.NotImplemented)) + { + return (IsImplemented: false, Mnemonic: content.Mnemonic, Message: null); + } + else + { + return (opcodeBase.IsHalted) + ? (IsImplemented: true, Mnemonic: content.Mnemonic, Message: opcodeBase.SyntaxError) + : (IsImplemented: true, Mnemonic: content.Mnemonic, Message: null); + } + } #endregion #region Usage Undefined @@ -360,7 +360,6 @@ public bool HasSyntaxError(int lineNumber) { get { foreach (var x in this._usage_Undefined) yield return (x.Key, x.Value); } } - public bool Has_Usage_Undefined_Warning(int lineNumber) { return this._usage_Undefined.ContainsKey(lineNumber); @@ -369,8 +368,7 @@ public string Get_Usage_Undefined_Warning(int lineNumber) { return this._usage_Undefined.TryGetValue(lineNumber, out string message) ? message : ""; } - - public string Get_Usage_Undefined_Warnings(int lineNumber) + private string Calculate_Usage_Undefined_Warnings(int lineNumber) { lock (this._updateLock) { @@ -434,8 +432,7 @@ public string Get_Redundant_Instruction_Warning(int lineNumber) { return this._redundant_Instruction.TryGetValue(lineNumber, out string message) ? message : ""; } - - public string Get_Redundant_Instruction_Warnings(int lineNumber) + private string Calculate_Redundant_Instruction_Warnings(int lineNumber) { var content = this._sFlow.Get_Line(lineNumber); if (content.Mnemonic == Mnemonic.NONE) return ""; @@ -475,96 +472,112 @@ public string Get_Redundant_Instruction_Warnings(int lineNumber) #endregion #region Getters - public void PreCompute_Register_Value(Rn name, int lineNumber, bool before) + private void PreCompute_Register_Value(Rn name, int lineNumber, bool before) { // get the register value and discard the result, the value will be added to the cache - Get_Register_Value(name, lineNumber, before, false, true); + this.Get_Register_Value(name, lineNumber, before, false, true); } public (string Value, bool Bussy) Get_Register_Value(Rn name, int lineNumber, bool before, bool async, bool create) { - if (!this.Enabled) return ("", false); - - var state = (before) ? this.Get_State_Before(lineNumber, async, create) : this.Get_State_After(lineNumber, async, create); - if (state.Bussy) + try { - this._threadPool2.QueueWorkItem(Update_State_And_TvArray_LOCAL); - this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); - return ("[I'm bussy and haven't acquired the state of line " + (lineNumber+1) + " yet.]", true); // plus 1 for the lineNumber because lineNumber 0 is shown as lineNumber 1 - } - if (state.State == null) - { - this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); - return ("[I'm confused, sorry about that.]", true); - } + if (!this.Enabled) return ("", false); - Tv[] reg = state.State.GetTvArray_Cached(name); - if (reg == null) - { - this._threadPool2.QueueWorkItem(Update_TvArray_LOCAL, state.State); - this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); - return ("[I'm bussy determining the bits of " + name + ".]", true); - } - else - { - this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); - return (ToString_LOCAL(reg), false); - } + var state = (before) ? this.Get_State_Before(lineNumber, async, create) : this.Get_State_After(lineNumber, async, create); + if (state.Bussy) + { + this._threadPool2.QueueWorkItem(Update_State_And_TvArray_LOCAL); + this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); + return ("[I'm bussy and haven't acquired the state of line " + (lineNumber + 1) + " yet.]", true); // plus 1 for the lineNumber because lineNumber 0 is shown as lineNumber 1 + } + if (state.State == null) + { + this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); + return ("[I'm confused, sorry about that.]", true); + } - #region Local Methods + Tv[] reg = state.State.GetTvArray_Cached(name); + if (reg == null) + { + this._threadPool2.QueueWorkItem(Update_TvArray_LOCAL, state.State); + this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); + return ("[I'm bussy determining the bits of " + name + ".]", true); + } + else + { + this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); + return (ToString_LOCAL(reg), false); + } - void Update_State_And_TvArray_LOCAL() - { - var state2 = (before) ? this.Get_State_Before(lineNumber, false, true) : this.Get_State_After(lineNumber, false, true); - Update_TvArray_LOCAL(state2.State); - } + #region Local Methods - void Update_TvArray_LOCAL(State state2) - { - state2.Update_TvArray_Cached(name); - this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); - } + void Update_State_And_TvArray_LOCAL() + { + var state2 = (before) ? this.Get_State_Before(lineNumber, false, true) : this.Get_State_After(lineNumber, false, true); + Update_TvArray_LOCAL(state2.State); + } - string ToString_LOCAL(Tv[] array) - { - if (false) + void Update_TvArray_LOCAL(State state2) { - return string.Format("{0} = {1}\n{2}", ToolsZ3.ToStringHex(reg), ToolsZ3.ToStringBin(reg), state.State.ToStringConstraints("") + state.State.ToStringRegs("") + state.State.ToStringFlags("")); + state2.Update_TvArray_Cached(name); + this.Line_Updated_Event?.Invoke(this, new LineUpdatedEventArgs(lineNumber, AsmMessageEnum.DECORATE_REG)); } - else + + string ToString_LOCAL(Tv[] array) { - return string.Format("{0} = {1}", ToolsZ3.ToStringHex(reg), ToolsZ3.ToStringBin(reg)); + if (false) + { + return string.Format("{0} = {1}\n{2}", ToolsZ3.ToStringHex(reg), ToolsZ3.ToStringBin(reg), state.State.ToStringConstraints("") + state.State.ToStringRegs("") + state.State.ToStringFlags("")); + } + else + { + return string.Format("{0} = {1}", ToolsZ3.ToStringHex(reg), ToolsZ3.ToStringBin(reg)); + } } + #endregion + } + catch (Exception e) + { + AsmDudeToolsStatic.Output_ERROR(string.Format("{0}:Get_Register_Value; e={1}", ToString(), e.ToString())); + return ("Exception in AsmSimulator:Get_Register_Value", false); } - #endregion } - + public (bool HasValue, bool Bussy) Has_Register_Value(Rn name, int lineNumber, bool before, bool create = false) { - var state = (before) - ? this.Get_State_Before(lineNumber, false, false) - : this.Get_State_After(lineNumber, false, false); - if (state.Bussy) + try { - return (false, true); - } - else if (state.State == null) - { - if (create) PreCompute_Register_Value(name, lineNumber, before); - return (false, true); - } - else - { - Tv[] content = state.State.GetTvArray_Cached(name); - if (content == null) + var state = (before) + ? this.Get_State_Before(lineNumber, false, false) + : this.Get_State_After(lineNumber, false, false); + if (state.Bussy) + { + return (false, true); + } + else if (state.State == null) { if (create) PreCompute_Register_Value(name, lineNumber, before); return (false, true); } - foreach (Tv tv in content) + else { - if ((tv == Tv.ONE) || (tv == Tv.ZERO) || (tv == Tv.UNDEFINED)) return (true, false); + Tv[] content = state.State.GetTvArray_Cached(name); + if (content == null) + { + if (create) PreCompute_Register_Value(name, lineNumber, before); + return (false, true); + } + foreach (Tv tv in content) + { + if ((tv == Tv.ONE) || (tv == Tv.ZERO) || (tv == Tv.UNDEFINED)) return (true, false); + } + return (false, false); } + } + catch (Exception e) + { + AsmDudeToolsStatic.Output_ERROR(string.Format("{0}:Has_Register_Value; e={1}", ToString(), e.ToString())); return (false, false); } } @@ -574,7 +587,7 @@ string ToString_LOCAL(Tv[] array) /// returns null otherwise and schedules its computation. /// if the state is not computed yet, /// return null and create one in a different thread according to the provided createState boolean. - public (State State, bool Bussy) Get_State_After(int lineNumber, bool async, bool create) + private (State State, bool Bussy) Get_State_After(int lineNumber, bool async, bool create) { if (!this.Enabled) return (State: null, Bussy: false); if (this._cached_States_After.TryGetValue(lineNumber, out State result)) @@ -625,7 +638,7 @@ void Calculate_State_After_LOCAL() #endregion } - public (State State, bool Bussy) Get_State_Before(int lineNumber, bool async, bool create) + private (State State, bool Bussy) Get_State_Before(int lineNumber, bool async, bool create) { if (!this.Enabled) return (State: null, Bussy: false); if (this._cached_States_Before.TryGetValue(lineNumber, out State result)) diff --git a/VS/CSHARP/asm-sim-lib/DynamicFlow.cs b/VS/CSHARP/asm-sim-lib/DynamicFlow.cs index e92d3619..d779eafd 100644 --- a/VS/CSHARP/asm-sim-lib/DynamicFlow.cs +++ b/VS/CSHARP/asm-sim-lib/DynamicFlow.cs @@ -27,7 +27,6 @@ using QuickGraph; using Microsoft.Z3; using AsmTools; -using Amib.Threading; namespace AsmSim { @@ -495,21 +494,21 @@ public string ToStringOverview(StaticFlow flow, bool showRegisterValues = false) private State Construct_State_Private(string key, bool after) { Tools tools = new Tools(this._tools); - var alreadyVisisted = new HashSet(); + var visisted = new List(); lock (this._updateLock) { - return Construct_State_Private_LOCAL(key, after); + return Construct_State_Private_LOCAL(key, after, visisted) ?? new State(tools, key, key); } #region Local Methods - State Construct_State_Private_LOCAL(string key_LOCAL, bool after_LOCAL) + State Construct_State_Private_LOCAL(string key_LOCAL, bool after_LOCAL, ICollection visited_LOCAL) { #region Payload - if (alreadyVisisted.Contains(key_LOCAL)) // found a cycle + if (visited_LOCAL.Contains(key_LOCAL)) // found a cycle { Console.WriteLine("WARNING: DynamicFlow: Construct_State_Private: Found cycle at key "+key_LOCAL+ "; not implemented yet."); - return new State(tools, key_LOCAL, key_LOCAL); + return null; //new State(tools, key_LOCAL, key_LOCAL); } if (!this.Has_Vertex(key_LOCAL)) { @@ -517,8 +516,8 @@ State Construct_State_Private_LOCAL(string key_LOCAL, bool after_LOCAL) return new State(tools, key_LOCAL, key_LOCAL); } - //alreadyVisisted.Add(key_LOCAL); // make better cycle detection method, this does not work State result; + visited_LOCAL.Add(key_LOCAL); switch (this._graph.InDegree(key_LOCAL)) { @@ -527,13 +526,22 @@ State Construct_State_Private_LOCAL(string key_LOCAL, bool after_LOCAL) break; case 1: var edge = this._graph.InEdge(key_LOCAL, 0); - result = Construct_State_Private_LOCAL(edge.Source, false); // recursive call - result.Update_Forward(edge.Tag.StateUpdate); + if (edge.Tag.StateUpdate.Reset) + { + result = new State(tools, key_LOCAL, key_LOCAL); + } + else + { + result = Construct_State_Private_LOCAL(edge.Source, false, visited_LOCAL); // recursive call + if (result == null) return null; + result.Update_Forward(edge.Tag.StateUpdate); + } break; case 2: var edge1 = this._graph.InEdge(key_LOCAL, 0); var edge2 = this._graph.InEdge(key_LOCAL, 1); - result = Merge_State_Update_LOCAL(key_LOCAL, edge1.Source, edge1.Tag.StateUpdate, edge2.Source, edge2.Tag.StateUpdate); + result = Merge_State_Update_LOCAL(key_LOCAL, edge1.Source, edge1.Tag.StateUpdate, edge2.Source, edge2.Tag.StateUpdate, visited_LOCAL); + if (result == null) return null; break; default: Console.WriteLine("WARNING: DynamicFlow:Construct_State_Private: inDegree = " + this._graph.InDegree(key_LOCAL) + " is not implemented yet"); @@ -552,11 +560,11 @@ State Construct_State_Private_LOCAL(string key_LOCAL, bool after_LOCAL) break; case 2: State state1 = new State(result); - State state2 = new State(result); { var edge1 = this._graph.OutEdge(key_LOCAL, 0); state1.Update_Forward(edge1.Tag.StateUpdate); } + State state2 = new State(result); { var edge2 = this._graph.OutEdge(key_LOCAL, 1); state2.Update_Forward(edge2.Tag.StateUpdate); @@ -579,11 +587,13 @@ State Construct_State_Private_LOCAL(string key_LOCAL, bool after_LOCAL) return result; } - State Merge_State_Update_LOCAL(string target, string source1, StateUpdate update1, string source2, StateUpdate update2) + State Merge_State_Update_LOCAL(string target, string source1, StateUpdate update1, string source2, StateUpdate update2, ICollection visited2) { - State state1 = Construct_State_Private_LOCAL(source1, false); // recursive call - State state2 = Construct_State_Private_LOCAL(source2, false); // recursive call - + State state1 = Construct_State_Private_LOCAL(source1, false, new List(visited2)); // recursive call + if (state1 == null) return null; + State state2 = Construct_State_Private_LOCAL(source2, false, new List(visited2)); // recursive call + if (state2 == null) return null; + StateUpdate mergeStateUpdate; { string nextKey1 = target + "A"; diff --git a/VS/CSHARP/asm-sim-lib/StaticFlow.cs b/VS/CSHARP/asm-sim-lib/StaticFlow.cs index 241f3521..cb22b631 100644 --- a/VS/CSHARP/asm-sim-lib/StaticFlow.cs +++ b/VS/CSHARP/asm-sim-lib/StaticFlow.cs @@ -61,7 +61,7 @@ public string Get_Key(int lineNumber) } else { - return "!" + lineNumber.ToString(); + return "!" + (lineNumber + 1).ToString(); } } public (string Key1, string Key2) Get_Key((int lineNumber1, int lineNumber2) lineNumber)