Functions and Arrays

A Guide (for advanced RoboCom programmers) by Florian Fischer

About this document

This document explains how to write functions, and use the robot's memory as an array, using the new language constructs @@label and ##var of RoboCom 3.

Functions

When you're programming some more complex robots, you'll often end up inserting code twice which is used under different conditions. In a higher programming language, you would use functions in this situation. How does such a function call work? Basically, the computer stores the current program address, jumps to the start of the function, computes the function, and returns to the stored program address (with another jump).

However, unlike most real computers, classical RoboCom uses relative jumps only, that means a "Jump 2" instruction does not jump to the 2nd instruction of the current bank, but instead two instructions forward from the current position. (BJump instructions are always absolute, but are slower and cannot be used when the running bank is unknown, like in many viruses.)
This makes it extremely difficult to return from a function, as the return jump value has to be calculated by hand, counting the bank's instructions, and becomes invalid as soon as another instruction is inserted into the bank.
No wonder that functions were not really common until now in RoboCom.

In RoboCom 3, however, these problems are easy to avoid using the new AJump and @@label instructions.
The procedure is as follows: Before jumping to the function, just store the continue point using a Set #JumpVar, @@ContinuePoint instruction. (@@ContinuePoint is the absolute address of the label @ContinuePoint.) Then jump to the function entry point "normally" using Jump @FunctionBegin. At the end of the function, just return to the saved position using AJump #JumpVar (AJump is an absolute jump, i.e. AJump 5 simply jumps to the 5th instruction of the current bank.)

For an (half-useful) example, let's assume a five-banked robot which runs on bank 5 and has specialized viruses on banks 2, 3, and 4. These are transferred to newly created own bots and to enemy bots as well, for which we'll use a function.

; This is the variable we're going to use to store the return position
Define &JumpVar { #20 }

Bank FunctionMain
@Begin
 Scan   #7                      ; Scan for enemies
 Comp   #7,1
  Jump  @Create
 ; Now we've detected an enemy, so let's call the virus transfer function
 Set    &JumpVar,@@EnemyCont    ; make the function return at @EnemyCont
 Jump        @VirusTrans        ; Call the virus transfer function
@EnemyCont                      ; Return point for the function
 Turn   0                       ; Just continue with next direction
 Jump   @Begin

@Create                         ; No enemy found, so create a new bot
 Create 2,5,0
 Set    &JumpVar,@@CreateCont   ; make the function return at @CreateCont
 Jump        @VirusTrans        ; Call the virus transfer function
@CreateCont                     ; Another return point for the function
 Trans  5,5                     ; copy the rest of the program
 Trans  1,1
 Set    %Active,1               ; activate the new bot
 Turn   0                       ; continue with next direction
 Jump   @Begin

; The virus transfer function
@VirusTrans                     ; Entry point for the function
 Trans  2,2
 Trans  3,3
 Trans  4,4
 AJump       &JumpVar           ; Absolute jump to the position saved in &JumpVar

Arrays

Another new concept in RoboCom 3 is that the robot's main memory (its 20 standard variables) can be used as an array. To do so, the new syntax ##var has been introduced. It means "the variable at index #var".
So, let's assume that you have set #1 to 5. Then, ##1 means the variable number 5, i.e. #5, and "Set ##1, 1" would in fact set #5 to one.
Here's a small test program to illustrate this behaviour. It sets all the variables (from #1 up to #20 to their indices.

Bank Test
Set     #20,0           ; Initialize counter variable
@setloop
 Add    #20,1           ; Count upwards
 Set    ##20, #20       ; Set the current variable to its index
 Comp   #20,20          ; Are there anymore variables to set up?
  Jump  @setloop

Using Arrays, you can easily store assorted data amounts (like the number of your enemies in all rows of the board, statistics about the usage of the #PUB variable, the food growth rates around your homebase in BioCom, etc.).
These examples seem to be a bit far-fetched? Maybe. Arrays are probably not needed to create a charts bot in RC3, but they're still a useful extension to RoboCom and expand its versatility.