Page 1 of 1

How READ...DATA work

Posted: Mon Oct 30, 2023 6:32 pm
by spotlessmind1975
[italian and french follow]

Starting from the next version, the READ...DATA functionality will be made available. This is a very interesting element of the language, because it allows you to store data in the program space, and access it sequentially or randomly, without consuming precious memory, such as that of strings. The syntax is the same as available on many BASIC languages:

Code: Select all

DATA c1, c2, c3, ..., cn
where c1, c2, ... are the constants you want to insert. The constants can be integer numbers, floating point numbers or strings: ugBASIC will take care of storing them in the most efficient way possible. It will then be possible to read the values with the READ command:

Code: Select all

READ x, y, z, ...
The language will try, where possible, to convert the constant into the type of the variable. This mode is obviously "slow" although safe. However, it will also be possible to use a second, faster mode: it is called READ FAST and can only be used if the data is stored in the same format. This can be achieved with the command DATA AS type c1, c2, c3, ..., i.e.:

Code: Select all

DATA AS POSITION 100, 100, 200, 200
In order to make the best use of this mode, it is essential to use the RESTORE command and the READ END function: the first allows you to indicate where to start reading the data, while the second indicates if the data has ended.

:arrow: ITALIAN

A partire dalla prossima versione, sarà resa disponibile la funzionalità di READ...DATA. Questo è un elemento del linguaggio molto interessante, perché permette di memorizzare dati nello spazio del programma, e accedervi in modo sequenziale o casuale, senza per questo consumare preziosa memoria, come quella delle stringhe. La sintassi è la stessa disponibile su molti linguaggi BASIC:

Code: Select all

DATA c1, c2, c3, ..., cn
dove c1, c2, ... sono le costanti che si vogliono inserire. Le costanti possono essere numeri interi, a virgola mobile o stringa: ci penserà ugBASIC a stoccarle nel modo più efficiente possibile. Sarà quindi possibile leggere i valori con il comando READ:

Code: Select all

READ x, y, z, ...
Il linguaggio cercherà, dove possibile, di convertire la costante nel tipo della variabile. Questa modalità è ovviamente "lenta" seppur sicura.

Sarà però possibile utilizzare anche una seconda modalità, più veloce: si chiama READ FAST e la si può utilizzare solo se il dato viene memorizzato nel medesimo formato. Questo lo si può ottenere con la sintassi: DATA AS type c1, c2, c3, ..., esempio:

Code: Select all

DATA AS POSITION 100, 100, 200, 200
Per poter utilizzare al meglio questa modalità, è essenziale usare il comando RESTORE e la funzione READ END: il primo permette di indicare da dove iniziare a leggere i dati, mentre il secondo se i dati sono terminati.

:arrow: FRENCH

À partir de la prochaine version, la fonctionnalité READ...DATA sera rendue disponible. C'est un élément très intéressant du langage, car il permet de stocker des données dans l'espace programme, et d'y accéder de manière séquentielle ou aléatoire, sans consommer une mémoire précieuse, comme celle des chaînes. La syntaxe est la même que celle disponible dans de nombreux langages BASIC :

Code: Select all

DATA c1, c2, c3, ..., cn
c1, c2, ... sont les constantes que vous souhaitez insérer. Les constantes peuvent être des nombres entiers, des nombres à virgule flottante ou des chaînes : ugBASIC se chargera de les stocker de la manière la plus efficace possible. Il sera alors possible de lire les valeurs avec la commande READ :

Code: Select all

READ x, y, z, ...
Le langage tentera, lorsque cela est possible, de convertir la constante en type de variable. Ce mode est évidemment « lent » bien que sécurisé. Cependant, il sera également possible d'utiliser un deuxième mode, plus rapide : il s'appelle READ FAST et ne peut être utilisé que si les données sont stockées dans le même format. Ceci peut être réalisé avec la commande DATA AS type c1, c2, c3, ..., exemple:

Code: Select all

DATA AS POSITION 100, 100, 200, 200
Afin d'utiliser au mieux ce mode, il est indispensable d'utiliser la commande RESTORE et la fonction READ END : la première permet d'indiquer par où commencer la lecture du données, tandis que le second indique si les données sont terminées.

Re: How READ...DATA work

Posted: Wed Nov 01, 2023 5:19 pm
by wysardry
In other BASIC dialects, I have only ever used READ...DATA to assign values to arrays, which didn't seem the most efficient use of memory.

Is it possible to use it with non-arrays in ugBASIC? I'm a little confused as to how RESTORE will work without line numbers, unless you can only RESTORE to the beginning of the DATA rather than a specific program line.

What I would like to do, is have a string variable such as roomText$ and be able to READ the right string DATA for it based on the value of an integer variable such as roomNum.

Currently, I would likely use SELECT...CASE for that.

Re: How READ...DATA work

Posted: Thu Nov 02, 2023 7:57 am
by spotlessmind1975
Hello wysardry !
wysardry wrote: Wed Nov 01, 2023 5:19 pm What I would like to do, is have a string variable such as roomText$ and be able to READ the right string DATA for it based on the value of an integer variable such as roomNum.
Depending on the power and flexibility of the BASIC language you are considering, these are instructions that allow you to simulate a partially random access file. To explain better, imagine you want to store a series of short descriptions of an adventure game. At first glance, you would put the descriptions in an array and then use the index as the room number:

Code: Select all

DIM desc$(100)
desc$(0) = "This is the room 1"
desc$(1) = "This is another room"
...
Now, imagine instead that each description is in a specific DATA line, and that each line is prefixed by an identifier (label? line number?) that identifies the room.

Code: Select all

100 DATA "This is the room 1"
101 DATA "This is another room"
Now, imagine you have a RESTORE command that allows you to programmatically select which line to start reading from. At this point you may no longer use arrays, because the information is already available, ready to use:

Code: Select all

PROCEDURE showRoomDescription[ room ]
    RESTORE 100+room
    READ description$
    PRINT description$
END PROC

showRoomDescription[ 0 ]
wysardry wrote: Wed Nov 01, 2023 5:19 pm I'm a little confused as to how RESTORE will work without line numbers, unless you can only RESTORE to the beginning of the DATA rather than a specific program line.
The semantics of RESTORE always remain the same, that is: position the reader at the first element to be read of those declared with DATA. The point here is that first element can be absolute (when RESTORE is used alone) or relative (starting from a certain position, when we use a label).

Code: Select all

start:
PRINT "Hello world!"
DATA 42
RESTORE start
READ x
PRINT x
GOTO start
For example, if we introduce a label and then, subsequently, a DATA statement, RESTORE could refer to that label. In this case, it will repeat forever the "Hello world!" string followed by the number 42.

Re: How READ...DATA work

Posted: Thu Nov 02, 2023 11:57 am
by wysardry
spotlessmind1975 wrote: Thu Nov 02, 2023 7:57 am Now, imagine instead that each description is in a specific DATA line, and that each line is prefixed by an identifier (label? line number?) that identifies the room.
When skimming the manual, I hadn't noticed that line numbers could optionally be used. That will make it much easier to use DATA lines.

I'm guessing that as they're optional, you can use line numbers just on the lines with DATA statements and omit them everywhere else?

Code: Select all

100 DATA "This is the room 1"
101 DATA "This is another room"
Now, imagine you have a RESTORE command that allows you to programmatically select which line to start reading from. At this point you may no longer use arrays, because the information is already available, ready to use:

Code: Select all

PROCEDURE showRoomDescription[ room ]
    RESTORE 100+room
    READ description$
    PRINT description$
END PROC

showRoomDescription[ 0 ]
Would it be possible to start numbering the DATA lines from 1 instead of 101 to avoid the need to add 100 to room?

I'm unsure whether the compiler will care if the line numbered 1 is not the first in the program (as DATA should be near the end).
The constants can be integer numbers, floating point numbers or strings: ugBASIC will take care of storing them in the most efficient way possible.
Is it possible to store bits in DATA statements? If not, how do you efficiently assign values to elements of bit arrays?

Re: How READ...DATA work

Posted: Thu Nov 02, 2023 1:05 pm
by spotlessmind1975
wysardry wrote: Thu Nov 02, 2023 11:57 am I'm guessing that as they're optional, you can use line numbers just on the lines with DATA statements and omit them everywhere else?
As in other uses, in ugBASIC line numbers are always optional.
wysardry wrote: Thu Nov 02, 2023 11:57 am Would it be possible to start numbering the DATA lines from 1 instead of 101 to avoid the need to add 100 to room?
Yes, of course. I actually think the final implementation will make use of labels, so eventually not only will you be able to number them from 1, but they could be "out of order" and you will also be able to use a string. I'm working on it these days.
wysardry wrote: Thu Nov 02, 2023 11:57 am I'm unsure whether the compiler will care if the line numbered 1 is not the first in the program (as DATA should be near the end).
There is no restriction on line numbers.
This is a valid program, from an ugBASIC perspective:

Code: Select all

9 PRINT "FIRST LINE"
8 PRINT "SECOND LINE"
7 GOTO 9
The output will be:

Code: Select all

FIRST LINE
SECOND LINE
FIRST LINE
SECOND LINE
FIRST LINE
SECOND LINE
...

Re: How READ...DATA work

Posted: Thu Nov 02, 2023 7:09 pm
by wysardry
spotlessmind1975 wrote: Mon Oct 30, 2023 6:32 pm The constants can be integer numbers, floating point numbers or strings: ugBASIC will take care of storing them in the most efficient way possible.
Is it possible to store bits in DATA statements? If not, how do you efficiently assign values to elements of bit arrays?

Either way, this sounds like a very useful implementation. 8-)

Re: How READ...DATA work

Posted: Fri Nov 03, 2023 7:23 am
by spotlessmind1975
wysardry wrote: Thu Nov 02, 2023 7:09 pm Is it possible to store bits in DATA statements?
Not in "safe" mode because it would not be possible to "package" them. In addition to the difficulty of specifying that the constant is a bit, in memory then 1 bit will take up, at least, two bytes (1 for the type, 1 for the bit). It's a bit much, and it's definitely not efficient.

In "fast" mode, however, it could be in the future. In this case you need to write something like:

Code: Select all

DATA AS BIT 1, 0, 1, 1, 0, 0, 1, 0, ... 
and therefore, at this point, each DATA value will be stored in the same byte, until saturation, and therefore occupation of the next byte, and so on.
wysardry wrote: Thu Nov 02, 2023 7:09 pm If not, how do you efficiently assign values to elements of bit arrays?
Assignment with constants should also work with bit arrays. If it doesn't work, it's a compiler bug, and I should fix it.

Example:

Code: Select all

DIM AS BIT x(8) = #{ 255 }
Makes all elements of x to the value 1.

Re: How READ...DATA work

Posted: Fri Nov 03, 2023 10:20 am
by wysardry
spotlessmind1975 wrote: Fri Nov 03, 2023 7:23 am Assignment with constants should also work with bit arrays. If it doesn't work, it's a compiler bug, and I should fix it.

Example:

Code: Select all

DIM AS BIT x(8) = #{ 255 }
Makes all elements of x to the value 1.
Would that work with much larger arrays?

For example, if you had a bit array with 128 elements, would you assign the values in blocks of 8 bits or use a single large (128 bit) number?

Re: How READ...DATA work

Posted: Sun Nov 05, 2023 11:10 pm
by spotlessmind1975
wysardry wrote: Fri Nov 03, 2023 10:20 am For example, if you had a bit array with 128 elements, would you assign the values in blocks of 8 bits or use a single large (128 bit) number?
No, I would use 16 numbers (16x8 bit = 128 bit).

Re: How READ...DATA work

Posted: Mon Nov 06, 2023 5:40 pm
by wysardry
So, the syntax would be something like this? :-

Code: Select all

DIM AS BIT x(128) = #{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
(If setting every bit to a value of 1.)