Commodore‎ > ‎BASIC‎ > ‎Keywords‎ > ‎

RENUMBER

Keyword Abbreviation Token (hex) Version(s) Classification
RENUMBER REN{Shift+U} F8 3.5, 7.0 Command

  Syntax  
RENUMBER [ [ newLineNumber ] [ , [ increment ] [ , startingLine ] ] ]
 
Parameters Type Legal Value(s) Default Value Note(s)
newLineNumber Literal integer
0 to 63999
10 
Must be a literal value
increment Unsigned integer 1 to 63999  10   
startingLine Unsigned integer
0 to 63999
0
 
 
  Purpose  
Program editing; Renumber BASIC program line(s) in memory.

 
  Remarks  
RENUMBER updates a range of program lines in memory by changing their line numbers, and more importantly, finds and updates all references to those lines anywhere and everywhere in the program.  Unfortunately, the Syntax is radically different from DELETE and LIST which also operate on a range of program lines.
 
There are two reasons you might want to do this.  First, the renumbered lines will be consistantly numbered.  This makes the program listing a bit easier to read and hopefully understand.  On the downside, if you are intimately familiar with the line numbers used before RENUMBER you will probably be confused afterwords.
 
The second reason is to "open up space".  Some textbooks on BASIC and many examples you can find in reality will be written with line numbers in increments of 10.  Even if you practice this, once you start editing/debugging a program, you may use up "all available line numbers".  For example, if your program started with line numbers 10 and 20 (and none in between) but over time you added 9 more lines between them (11 to 19) then you would be in trouble if you needed to add yet another line between 10 and 20.  RENUMBER to the rescue!
 
Manually editing line numbers is extremely error prone, so RENUMBER is a very handy feature.  However it is slow.  Hopefully you won't need it very often.
 
The first thing RENUMBER does is parse the arguments you supply (if any).  The newLineNumber must be a literal value, it can not be a variable or expression; otherwise SYNTAX ERROR occurs.  If the increment or startingLine are invalid expressions, SYNTAX ERROR occurs; if either is string type then TYPE MISMATCH ERROR occurs; if either is floating-point, they will be converted with INT.  Finaly, if any parameter is not a Legal Value (see table above), then ILLEGAL QUANTITY ERROR occurs.
 
Unfortunately you can only specifying the startingLine where RENUMBER will work its magic, not the endingLine, which makes this much less useful than it could be.  In other words, it always updates line numbers until the end of the program.  Trivia: Commodore's own 6502 Assembler for the C64 (which used the BASIC editor for entering ML programs) included a [RE]NUMBER function that used a LIST-style line number range.  Why they didn't use that version in real BASIC is beyond me!
 
Besides the unfortunate Syntax, RENUMBER also has several bugs!  These are described below... at least the ones I know about!
 
If the startingLine does not exist, then the next greatest line number will be set as the startingLine.  If there is no next greatest line number then RENUMBER quits and reports no error.
 
The newLineNumber is tested to be sure it does not come before (or is the same as) any lines that exist before the startingLine.  If this occurs, ILLEGAL QUANTITY ERROR is generated.  In case that doesn't make sense, here is an example:
NEW

READY.
10 REM LINE 10
20 REM LINE 20
30 REM LINE 30
RENUMBER 15,,30 : REM change line# 30 to line# 15 

?ILLEGAL QUANTITY ERROR  because line# 15 would be less/equal to existing line# 20
READY.
RENUMBER 15,,25 : REM change line# 30 to line# 25

READY.
LIST

10 REM LINE 10
20 REM LINE 20
25 REM LINE 30
 
READY.
 
Next BASIC will (try to) calculate what the new ending line number would be.  This is "simply" calculated as the number of program lines (from the startLine until the last line of the program) multiplied by the increment and added to the newLineNumber.  If this calculation gives a value greater than 63743 then LINE NUMBER TOO LARGE ERROR is generated.  Well there are two bugs here.  First, line numbers may be as large as 63999.  (For you ML programers, the problem is it tests the high byte for $F9 instead of the correct test for $FA).  Second, the ending line number would actually be newLineNumber + ( increment * ( number of lines - 1 ) ).  Notice the calculation BASIC uses is missing the minus one.  In practice, these bugs rarely appear.
 
If an error hasn't occurred, RENUMBER now performs pass 1, the test phase.  It looks through the entire program for the following keywords: COLLISION, ELSE, GO, GOSUB, GOTO, RESTORE, RESUME, RUN, THEN, TRAP.  Note that it ignores some statements that use line numbers, such as DELETE, LIST, and RENUMBER.  Well DELETE and RENUMBER don't work in a program, but LIST does (at least in versions of BASIC that have RENUMBER).  So yet another bug. Anyway, for each of those statments the line number(s) it "calculates" what it should be after RENUMBER finishes.  This is really only needed when a statement references a line number in the range being renumbered.  Because it does this check for all line number references, it runs slower than neccessary and if the reference is not valid in the original version then an UNRESOLVED REFERENCE ERROR occurs.
 
In other words, you get UNRESOLVED REFERENCE ERROR if the original version would have generate an UNDEF'D STATMENT ERROR should that line be executed.  Often when developing a program, GOSUB and GOTO statements (for example) will be written that reference a program line that hasn't been written yet. You never get an error when testing the program (hopefully) because the conditions which invoke them never occur.  However RENUMBER always tests them.  Now this error is appropriate when the line number being referenced is in the range of renumbered lines, but unneeded otherwise.  It often makes RENUMBER unusable... it might okay if a printed a list of these, but stops on the first one.  So then you change that line to use some dummy value just to get RENUMBER to work and try again, but then it prints another UNRESOLVED REFERENCE, and so you change that and try again.  It can take a ridiculous amount of time!
 
Now once it knows what that "new" (maybe the same) line number in the statement should be, it calculates the different in size from the existing line number reference.  For example, if the original program has a line that read 10 GOTO 85, but the re-numbered version should read 10 GOTO 100 then one extra byte would be needed (because "85" is only 2 digits, but "100" is 3 digits).  The line numbers can get smaller too, in which case the size difference would be negative.
 
So phase 1 goes through the whole program and calculates the number of extra (rarely fewer) bytes that will be needed to perform RENUMBER.  If the extra bytes would make the program exceed the secret variable "Limit of Text" (machines over 64K RAM) or "End of BASIC" (64K or less machines) then an OUT OF MEMORY ERROR occurs and the program is left unchanged.  The original ROMs of the C128 have a bug in this phase where, I believe, the extra bytes needed in a list of line numbers (for example ON...GOTO) are not properly calculated.
 
In both the original and updated ROMs of the C128 (not sure about C16 and Plus/4) there are bugs in this phase and the next relating to COLLISION and GO TO (i.e., the GOTO with a space).  These seem to be "harmless" bugs because they only strike when there is no line number (for COLLISION) the statement is mal-formed (for GO TO).
 
If phase 1 completes without error, RENUMBER begins phase 2.  This runs through entire program again, and looks for the same keywords listed above for phase 1.  This time, however, it changes the text of every program statement that includes a line number reference (well for the listed keywords), even when the referenced line number is unchanged.  As each line number reference is updated, the program size is adjusted up or down when needed.  This can never generate an error but if BASIC under-calculated the new program size in phase 1 and the program is already using most of available RAM then strange things will happen.  I don't know what would happen, however.  On the C128 it would probably be fatal because the "Limit of Text" is (by default) where the MMU registers begin, and over-writing them would mess up the CPU environemnt.
 
After phase 2, the final phase 3 begins.  This first searches for the startLine, and sets it as the "current line"It will be found because RENUMBER would have quit already if it didn't exist.  Finally, RENUMBER changes the line number of the "current line" to the value of newLineNumber, updates the newLineNumber by adding increment to it (for the next line), advances to the next line, and repeats until there is no next line (i.e., until the all remaining program lines have been renumbered).
 
In summary, RENUMBER performs 3 passes.  First it varies line references exist and calculates size.  Second it updates references.  Third it renumbers a range of program lines.  Phases 1 and 2 go over the whole program.  Phase 3 will, by default, go over the whole program but this can be a smaller range by giving an appropriate startingLine.  So maybe now you see why RENUMBER is slow?  Anyway, it is bound to be much faster and more accurate than doing it manually.
 
RENUMBER may only be used as a command in direct mode.  Attempting to use it as a statement in a program will generate DIRECT MODE ONLY ERROR.
 
Examples:
RENUMBER      : REM renumber entire program, first line# of 10, increment by 10
RENUMBER 100  : REM renumber entire program, first line# of 100, increment by 10
RENUMBER ,25  : REM renumber entire program, first line# of 10, increment by 25
RENUMBER 500,,220 : REM renumber lines 220- as lines 500- with increment 10
 
 
  Compare With  
 
  Contrast With  
 
  See Also  

© H2Obsession, 2014
Comments