Chapter 6. Sub-programs: Procedures and Functions

Syntax:


      PROCEDURE identifier [ '(' [VOLATILE] type { IN | OUT | IN OUT } identifier2 [',' ...] ')' IS
        statement_block
      END PROCEDURE

      FUNCTION identifier [ '(' [VOLATILE] type { IN | OUT | IN OUT } identifier2 [',' ...] ')' RETURN type IS
        statement_block
      END FUNCTION
    

The only difference between a PROCEDURE and a FUNCTION, is the former does not return a value, while the later does. The procedure identifier exists in the block in which the procedure is defined. A new block is immediately opened, and all parameters exist in that block. A parameter marked IN will be assigned the value passed when called. A parameter marked OUT will assign the resulting value to parameter passed when called. While in a sub-program, a new keyword is introduced:


      RETURN [ expr ]
    
When executed, the sub program immediately returns. If the sub program is a FUNCTION, expr is required. If it is a PROCEDURE, expr is forbidden.

A sub-program is executed simply by using its name. If parameters are specified in the sub-program definition, all parameters are required, otherwise none are allowed. A FUNCTION can be used anywhere a value is required (in expressions, as parameters to other sub-programs, etc). There is no limit to the number of parameters.

JALv2 is a pass by value language. Conceptually, an IN parameter is read once when the sub-program enters, and an OUT parameter is written once when the sub-program returns. This is not always desired. For example if a sub-program writes a string of characters to the serial port (passed as parameter), only the last character written will be sent. For this case we need VOLATILE parameters. These are either read each time used (IN) or written each time assigned (OUT). This is accomplished using pseudo variables (see below). If the value passed is not a pseudo-variable, a suitable one is created.

There are two ways to pass an array into a sub-program:


      PROCEDURE string_write (BYTE IN str[5]) IS...
      PROCEDURE string_write (BYTE IN str[]) IS...
    

The first follows the pass-by-value symantics noted above. An array variable of size 5, str, is allocated in the namespace of the procedure. Any callers must call with an array of exactly 5 bytes, which is copied into the local variable and used.

Alternately, the second version created a flexible array. This is pass-by-reference which means (1) the amount of data space used for str is only two or three bytes, and (2) any sized array can be passed in. This is generally far more useful, and far less wasteful. The operator COUNT can be used to determine the size of the array passed in.

Procedures and functions can be nested.

Example:


      FUNCTION square_root (WORD IN n) RETURN WORD IS

        WORD result
        WORD ix

        ix = 1
        WHILE ix < n LOOP
          n = n - ix
          result = result + 1
          ix = ix + 2
        END WHILE
        RETURN result

      END FUNCTION

      xx = square_root(xx)
    

Recursion is fully supported but due to the overhead it is discouraged.