"Returns the successor to str. The successor is calculated by incrementing characters starting from the rightmost alphanumeric (or the rightmost character if there are no alphanumerics) in the string. Incrementing a digit always results in another digit, and incrementing a letter results in another letter of the same case.

If the increment generates a carry, the character to the left of it is incremented. This process repeats until there is no carry, adding an additional character if necessary."

To start, we should handle the "carry" logic. There are two kinds of carries: digits and letters. Both involve checking if a character has exceeded a range (resetting it to the beginning of the range if it has). We can build a word that does this, returning the new character value as well as a boolean flag indicating if a carry occurred:

:carry(eltlastfirst--?elt')'[_> dup _] keep ?;

Using this to carry digits is pretty easy (using the 0 to 9 range):

:next-digit(ch--?ch')1 + CHAR: 9 CHAR: 0 carry;

To carry letters, we need to make sure that the carry preserves the original case (uppercase or lowercase) of the letter:

This leaves the core of the algorithm, which starts at the end of the string, incrementing each character (continuing if the carry flag is true), and then handling the case where we need to carry the first character: