sub traverse_tree { my ( $tree_root, $visitor_callback ) = @_; my ( $curr_node, $prev_node ) = $tree_root; while( $curr_node ) { my $next_node; { goto FROM_PARENT if $prev_node == $curr_node->parent; goto FROM_LEFT if $prev_node == $curr_node->left; goto FROM_RIGHT if $prev_node == $curr_node->right; FROM_PARENT: last if $next_node = $curr_node->left; FROM_LEFT: $visitor_callback->( $curr_node ); last if $next_node = $curr_node->right; FROM_RIGHT: $next_node = $curr_node->parent; } ( $prev_node, $curr_node ) = ( $curr_node, $next_node ); } }