GOSUB

Top  Previous  Next

 

The GOSUB statement calls an internal subroutine.

 

 

Format

 

GOSUB label{:}

GOSUB label{:}(args)

 

where

 

labelis the label attached to the statement at the start of the internal subroutine.

 

argsis a comma separated list of arguments to a subroutine defined with the LOCAL SUBROUTINE statement.

 

 

The optional colon after the label has no effect on the action of the statement.

 

The program continues execution at the given label, saving the location of the GOSUB for a later RETURN which will resume execution at the statement following the GOSUB. See also the  RETURN TO statement for details of alternate returns.

 

QMBasic defines two styles of internal subroutine. A conventional internal subroutine, as found in other multivalue database products, has no formal start or end. The label may be any label defined within the program or subroutine. It is the programmer's responsibility to ensure that internal subroutines return correctly. Variables referenced in the internal subroutine are accessible across the entire program module, requiring great care from the programmer to ensure that data in one part of the module is not accidentally altered elsewhere by use of the same name. Loop counters in FOR/NEXT loops are a good example of where this frequently happens. Calling this style of internal subroutine recursively is possible but of limited use because the variables in one invocation will be overwritten by the next.

 

The second style, referred to in QMBasic terminology as a local subroutine, is introduced by the LOCAL statement and is terminated by END. Local subroutines may have arguments and may have private local variables that are not visible outside the subroutine which are stacked if the subroutine is called recursively.

 

 

Examples

 

IF STOCK.LEVEL <= REORDER.LEVEL THEN GOSUB REORDER

 

This program fragment checks if the value of STOCK.LEVEL has fallen to the REORDER.LEVEL and, if so, calls internal subroutine REORDER.

 

 

LOCAL SUBROUTINE UPDATE.STOCK(PROD.NO, CHANGE)

  PRIVATE STOCK.REC

  READU STOCK.REC FROM STOCK.F, PROD.NO THEN

     STOCK.REC<STK.QOH> += CHANGE

     WRITE STOCK.REC TO STOCK.F, PROD.NO

  END

  RETURN

END

 

The above local subroutine takes a record id and the amount by which a field is to be updated, reads the corresponding record and applies the update. A real program would include statements to handle the case where the record is not found.