Here I explore using and passing pointers in Action! To do so I wrote a program to inverse a string. Inverse as in reverse video, not reverse character order. I created a procedure called StrInv that takes one parameter which is the string. It inverses it without creating a new string and returns. The main routine simply assigns the initial string value, prints it, calls the StrInv procedure, then prints the string again.
I’ll break down the code first, then present the complete listing last.
Start of the code section. It could be omitted as Action! will add it if it’s not found:
This is the PROCedure that does the inverting. It does not return a value. It does not need to. It alters the string contents in it’s original memory location. I declare the procedure and declare one parameter which is of type CHAR POINTER. This is similar to C casting since the variable being passed is a CHAR ARRAY (BYTE ARRAY):
; Inverse a string PROC StrInv(CHAR POINTER pStr)
I declare two bytes for use by the procedure. bLen which will be used to hold the passed strings length. And iLp which is used for the loop counter. bLen could be ommitted along with the assignment of the string length to it by writing the for loop to reference the string length directly:
As stated above, this assigns the strings length, contained in element 0 (zero) to variable bLen which will be used as the extent of the for loop:
; Get length of string bLen=pStr(0)
This is what does the work. It loops through each element of the string, increasing each elements value by 128. By adding 128 to each characters value, the character will become inverse. Each element is directly modified in its original memory location, referenced by the pointers sub index:
; Process each element for iLp=1 to bLen DO ; Add 128 to the value for inverse pStr(iLp)=pStr(iLp)+128 OD RETURN
This is the main routine declaration:
; Main routine PROC Main()
Here I declare a CHAR ARRAY name sStr which is 17 characters/bytes/elements long. It also assigns the initial value:
CHAR ARRAY sStr(17)=" Inverse ATASCII "
These commands setup the screen. Set the left margin to 0, init graphics 0 (text), then display the program title:
; Setup screen Poke(82,0) Graphics(0) ; Title PutE() PrintE("-[Inverse]------------------------------") PutE()
This displays the string before the call to inverse it:
; Show string before PrintF("Before: %S%E",sStr)
This is the call to the procedure to inverse the string. Notice there is no return value assignment. A pointer to the string is passed to the StrInv procedure:
; Inverse it StrInv(sStr)
This displays the string after the call to inverse it, then exits the program:
; Show string after PrintF("After : %S%E",sStr) RETURN
Uninterrupted source code:
MODULE ; Inverse a string PROC StrInv(CHAR POINTER pStr) BYTE bLen,iLp ; Get length of string bLen=pStr(0) ; Process each element for iLp=1 to bLen DO ; Add 128 to the value for inverse pStr(iLp)=pStr(iLp)+128 OD RETURN ; Main routine PROC Main() CHAR ARRAY sStr(17)=" Inverse ATASCII " ; Setup screen Poke(82,0) Graphics(0) ; Title PutE() PrintE("-[Inverse]------------------------------") PutE() ; Show string before PrintF("Before: %S%E",sStr) ; Inverse it StrInv(sStr) ; Show string after PrintF("After : %S%E",sStr) RETURN
Next I’ll cover various loop constructs since I’ve just hit on the for loop.