Page 1 of 1

Passing arrays to (recursive?) procedures

Posted: Mon Jun 24, 2024 7:30 pm
by clovepower
Hi

I am new to ugBASIC, so please bear with me. I have two questions about procedures:

1) Is it possible to pass an array to a procedure and, if so, how?
2) Does ugBASIC support recursive calls to procedures?

Thanks & Regards

Re: Passing arrays to (recursive?) procedures

Posted: Mon Jun 24, 2024 8:08 pm
by spotlessmind1975
Hi clovepower, and welcome to the forum! :D
clovepower wrote: ↑Mon Jun 24, 2024 7:30 pm 1) Is it possible to pass an array to a procedure and, if so, how?
On ugBASIC the parameters in the procedures are always passed by copy, never by reference, and the copy occurs only for simple, i.e. non-aggregate, types. So you can pass single variables but not arrays or "resources" (i.e. graphical images).

However, there are more efficient ways to pass arrays.

The first is to use global variables, or shared variables. The former can be defined (in the main program) with the GLOBAL keyword, while the latter (within the procedures) with the SHARED keyword. SHARED and GLOBAL basically do the same thing, only from a different point of view.

i.e.:

Code: Select all

DIM v(42) AS BYTE
DIM z(84) AS INTEGER

GLOBAL v

PROCEDURE test

    SHARED z

    v(1) = z(1)
    
END PROC
The second, more "BASIC like", is to exploit the way in which variables are stored in memory. For numeric types, arrays are areas of contiguous memory, and the location occupied by a certain element (n) is accessible with the PEEK, PEEKW, PEEKD instructions, appropriately inflected.

i.e.:

Code: Select all

DIM v1(42) AS INTEGER, v2(42) AS INTEGER

PROCEDURE update[ vaddr AS ADDRESS, pos AS INTEGER, value AS BYTE ]

    POKEW vaddr+(pos*2), value

END PROC

update[VARPTR(v1), 1, 42] : REM like v1(1) = 42
update[VARPTR(v2), 1, 42] : REM like v2(1) = 42
clovepower wrote: ↑Mon Jun 24, 2024 7:30 pm 2) Does ugBASIC support recursive calls to procedures?
Not currently. The ugBASIC language is a stackless language, therefore it is not possible to define recursive procedures as the local variables are, so to speak, shared between the various levels.

This, which is a specific project choice, is not a real limit.

First of all, recursive programming is not recommended by many good programming practices on resource-limited systems (see this NASA guide). Moreover, any stacked implementation can be converted into an iterative implementation (see here), with the use of a vector as a stack. Finally, the stack of 8-bit processors is slow and small, and therefore it is inherently difficult to write anything useful with such availability. Most mid-level languages ​​on 8-bit processors, such as C, use a simulated stack that is even slower. And ugBASIC try to be as much efficient as it can.

On the other hand, the advantage is that a classic procedure can be quickly translated into a parallel (multitasked) procedure, simply by inserting the PARALLEL keyword as a prefix. In fact, given that the local variables of the procedure are in any case statically defined, it is possible to rely on external data structures to differentiate the behavior of the very same code.This approach allows you to separate code and data, and create very complex game logic through simple process interactions. Here you can see an example of this approach.

In the future it is possible that PROCEDURE may be equipped with a stack. However, this is not an immediate development.

Re: Passing arrays to (recursive?) procedures

Posted: Thu Jun 27, 2024 10:20 am
by clovepower
Thanks a lot for the exhaustive answer!

Re: Passing arrays to (recursive?) procedures

Posted: Thu Jun 27, 2024 10:24 am
by clovepower
BTW, very happy to have come to know ugBASIC: it is at intersection of two things I love: computer languages and retro-computing.
I do like the idea of something easily portable across systems.
I am now trying to get more familiar with it.