@@ -299,6 +299,34 @@ pub trait Cursor {
299299 self . set_position ( CursorPosition :: After ( block) ) ;
300300 }
301301
302+ /// Get the next position that a forwards traversal will move to, but do not
303+ /// move this cursor.
304+ fn next_position ( & self ) -> CursorPosition {
305+ self . next_inst_position ( )
306+ . unwrap_or_else ( || self . next_block_position ( ) )
307+ }
308+
309+ /// Get the next position that a backwards traversal will move to, but do
310+ /// not move this cursor.
311+ fn prev_position ( & self ) -> CursorPosition {
312+ self . prev_inst_position ( )
313+ . unwrap_or_else ( || self . prev_block_position ( ) )
314+ }
315+
316+ /// Get the position that a `cursor.next_block()` call would move this
317+ /// cursor to, but do not update this cursor's position.
318+ fn next_block_position ( & self ) -> CursorPosition {
319+ let next = if let Some ( block) = self . current_block ( ) {
320+ self . layout ( ) . next_block ( block)
321+ } else {
322+ self . layout ( ) . entry_block ( )
323+ } ;
324+ match next {
325+ Some ( block) => CursorPosition :: Before ( block) ,
326+ None => CursorPosition :: Nowhere ,
327+ }
328+ }
329+
302330 /// Go to the top of the next block in layout order and return it.
303331 ///
304332 /// - If the cursor wasn't pointing at anything, go to the top of the first block in the
@@ -320,16 +348,23 @@ pub trait Cursor {
320348 /// }
321349 /// ```
322350 fn next_block ( & mut self ) -> Option < ir:: Block > {
323- let next = if let Some ( block) = self . current_block ( ) {
324- self . layout ( ) . next_block ( block)
351+ let pos = self . next_block_position ( ) ;
352+ self . set_position ( pos) ;
353+ self . current_block ( )
354+ }
355+
356+ /// Get the position that a `cursor.prev_block()` call would move this
357+ /// cursor to, but do not update this cursor's position.
358+ fn prev_block_position ( & self ) -> CursorPosition {
359+ let prev = if let Some ( block) = self . current_block ( ) {
360+ self . layout ( ) . prev_block ( block)
325361 } else {
326- self . layout ( ) . entry_block ( )
362+ self . layout ( ) . last_block ( )
327363 } ;
328- self . set_position ( match next {
329- Some ( block) => CursorPosition :: Before ( block) ,
364+ match prev {
365+ Some ( block) => CursorPosition :: After ( block) ,
330366 None => CursorPosition :: Nowhere ,
331- } ) ;
332- next
367+ }
333368 }
334369
335370 /// Go to the bottom of the previous block in layout order and return it.
@@ -353,16 +388,36 @@ pub trait Cursor {
353388 /// }
354389 /// ```
355390 fn prev_block ( & mut self ) -> Option < ir:: Block > {
356- let prev = if let Some ( block) = self . current_block ( ) {
357- self . layout ( ) . prev_block ( block)
358- } else {
359- self . layout ( ) . last_block ( )
360- } ;
361- self . set_position ( match prev {
362- Some ( block) => CursorPosition :: After ( block) ,
363- None => CursorPosition :: Nowhere ,
364- } ) ;
365- prev
391+ let pos = self . prev_block_position ( ) ;
392+ self . set_position ( pos) ;
393+ self . current_block ( )
394+ }
395+
396+ /// Get the position that a `cursor.next_inst()` call would move this cursor
397+ /// to, but do not update this cursor's position.
398+ fn next_inst_position ( & self ) -> Option < CursorPosition > {
399+ use self :: CursorPosition :: * ;
400+ match self . position ( ) {
401+ Nowhere | After ( ..) => None ,
402+ At ( inst) => {
403+ if let Some ( next) = self . layout ( ) . next_inst ( inst) {
404+ Some ( At ( next) )
405+ } else {
406+ Some ( After (
407+ self . layout ( )
408+ . inst_block ( inst)
409+ . expect ( "current instruction removed?" ) ,
410+ ) )
411+ }
412+ }
413+ Before ( block) => {
414+ if let Some ( next) = self . layout ( ) . first_inst ( block) {
415+ Some ( At ( next) )
416+ } else {
417+ Some ( After ( block) )
418+ }
419+ }
420+ }
366421 }
367422
368423 /// Move to the next instruction in the same block and return it.
@@ -406,30 +461,33 @@ pub trait Cursor {
406461 /// }
407462 /// ```
408463 fn next_inst ( & mut self ) -> Option < ir:: Inst > {
464+ let pos = self . next_inst_position ( ) ?;
465+ self . set_position ( pos) ;
466+ self . current_inst ( )
467+ }
468+
469+ /// Get the position that a `cursor.prev_inst()` call would move this cursor
470+ /// to, but do not update this cursor's position.
471+ fn prev_inst_position ( & self ) -> Option < CursorPosition > {
409472 use self :: CursorPosition :: * ;
410473 match self . position ( ) {
411- Nowhere | After ( ..) => None ,
474+ Nowhere | Before ( ..) => None ,
412475 At ( inst) => {
413- if let Some ( next) = self . layout ( ) . next_inst ( inst) {
414- self . set_position ( At ( next) ) ;
415- Some ( next)
476+ if let Some ( prev) = self . layout ( ) . prev_inst ( inst) {
477+ Some ( At ( prev) )
416478 } else {
417- let pos = After (
479+ Some ( Before (
418480 self . layout ( )
419481 . inst_block ( inst)
420482 . expect ( "current instruction removed?" ) ,
421- ) ;
422- self . set_position ( pos) ;
423- None
483+ ) )
424484 }
425485 }
426- Before ( block) => {
427- if let Some ( next) = self . layout ( ) . first_inst ( block) {
428- self . set_position ( At ( next) ) ;
429- Some ( next)
486+ After ( block) => {
487+ if let Some ( prev) = self . layout ( ) . last_inst ( block) {
488+ Some ( At ( prev) )
430489 } else {
431- self . set_position ( After ( block) ) ;
432- None
490+ Some ( Before ( block) )
433491 }
434492 }
435493 }
@@ -460,33 +518,9 @@ pub trait Cursor {
460518 /// }
461519 /// ```
462520 fn prev_inst ( & mut self ) -> Option < ir:: Inst > {
463- use self :: CursorPosition :: * ;
464- match self . position ( ) {
465- Nowhere | Before ( ..) => None ,
466- At ( inst) => {
467- if let Some ( prev) = self . layout ( ) . prev_inst ( inst) {
468- self . set_position ( At ( prev) ) ;
469- Some ( prev)
470- } else {
471- let pos = Before (
472- self . layout ( )
473- . inst_block ( inst)
474- . expect ( "current instruction removed?" ) ,
475- ) ;
476- self . set_position ( pos) ;
477- None
478- }
479- }
480- After ( block) => {
481- if let Some ( prev) = self . layout ( ) . last_inst ( block) {
482- self . set_position ( At ( prev) ) ;
483- Some ( prev)
484- } else {
485- self . set_position ( Before ( block) ) ;
486- None
487- }
488- }
489- }
521+ let pos = self . prev_inst_position ( ) ?;
522+ self . set_position ( pos) ;
523+ self . current_inst ( )
490524 }
491525
492526 /// Insert an instruction at the current position.
0 commit comments