/// <summary> /// Sets the pointer to a certain position /// </summary> /// <param name="pos">New position</param> /// <param name="assert_op">If given, then will assert that instruction at location 'pos' matches provided WantOp</param> /// <returns><c>this</c> to allow Fluent chaining.</returns> /// <remarks>Some code (especially within switch..case structure) can get shuffled around by the compiler during optimization. /// <para>This method allows returning to a certain point in the instruction chain, /// e.g., to the start of a switch structure.</para></remarks> public InstructionsWalker GoTo(int pos, WantOp assert_op = null) { if (!(assert_op is null)) { CodeInstruction op = Instructions[pos]; if (assert_op.NotMatches(Instructions[pos])) { throw new AssertionFailure($"Op at {pos} is <{op}> does not match assertion {assert_op}"); } } CurrentLocation = pos; return(this); }
/// <summary> /// Fetch the current location, but do NOT advance /// </summary> /// <param name="fetchedCurLoc">Variable to hold the fetched CurrentLocation</param> /// <param name="offset">Add this to the fetched location</param> /// <param name="assert_op">If given, asserts that instruction at location+offset matches a <c>WantOp</c> criteria</param> /// <returns><c>this</c> for Fluent chaining.</returns> public InstructionsWalker FetchLocation(out int fetchedCurLoc, int offset = 0, WantOp assert_op = null) { fetchedCurLoc = CurrentLocation + offset; if (!(assert_op is null)) { CodeInstruction op = Instructions[fetchedCurLoc]; if (assert_op.NotMatches(Instructions[fetchedCurLoc])) { throw new AssertionFailure($"Op at {fetchedCurLoc} is <{op}> does not match assertion {assert_op}"); } } return(this); }
public CodeInstruction CurrentOp(WantOp assert_op = null) { CodeInstruction op = Instructions[CurrentLocation]; if (!(assert_op is null)) { if (assert_op.NotMatches(op)) { throw new AssertionFailure($"CurrentOp <{op}> does not match assertion {assert_op}"); } } return(op); }
/// <summary> /// Advance pointer forward by N. If N is negative, move backwards instead. /// </summary> /// <param name="N">How many instructions to advance. Can be negative.</param> /// <param name="assert_op">If given, then will assert that instruction at destination matches provided WantOp</param> /// <returns><c>this</c> to allow Fluent chaining.</returns> public InstructionsWalker GoForward(int N, WantOp assert_op = null) { int newpos = CurrentLocation + N; if (!(assert_op is null)) { CodeInstruction op = Instructions[newpos]; if (assert_op.NotMatches(Instructions[newpos])) { throw new AssertionFailure($"Op at {newpos} is <{op}> does not match assertion {assert_op}"); } } CurrentLocation = newpos; return(this); }