The ugBASIC supports various data types. Variable can be defined with
a specific datatype by using the command DIM
, the command VAR
or by suffixes on the variable name. It also support decimal math for the default
implementation of the floating point system, and the construction of array
variables using the DIM
keyword, as well.
Basic syntax:
DIM x AS INTEGER
VAR y AS STRING
z = "string"
KEYWORD | SUFFIX | RANGE | SIZE (bytes) |
---|---|---|---|
BYTE CHAR | 0..255 | 1 | |
SIGNED BYTE | @ | -127..127 | 1 |
WORD | 0..65.535 | 2 | |
INT INTEGER SIGNED WORD | % | -32.767..32.767 | 2 |
DWORD | 0..4.294.967.295 | 4 | |
LONG SIGNED DWORD | & | -2.147.483.648..2.147.483.648 | 4 |
ADDRESS | 0..65.535 | 2 |
INT
(SIGNED WORD
). However, it is possible
to change the default type with the OPTION DEFAULT TYPE
command:OPTION DEFAULT TYPE LONG
42
, it is implicitly
converted to a numeric type using the standard (wide) approach,
that converts the number in a 2 byte value, or better, into the default data type. It is also available a optimized (narrow) approach,
that converts the number in the most compact space, i.e. 1 byte.OPTION TYPE WIDE
command: in this mode, the number
is converted into the default data type, which is the INT
(SIGNED WORD
)
type, and it occupies 2 bytes.OPTION TYPE NARROW
command: in this mode, the number is converted into the smallest
data type capable of containing the number. So 42
is converted to a
SIGNED BYTE
value that occupies 1 byte. 150
will be translated to SIGNED WORD
since is greater than 127
. OPTION TYPE UNSIGNED
command,
and the 150
will be converted into a simple (unsigned) BYTE
.BYTE
and CHAR
are the most efficient data type, since it is the data type more similar
to the one managed by 8 bit CPUs. The BYTE
is typically used as array indices and loops.
The CHAR
is used for single character;SIGNED BYTE
is the signed version of BYTE
: it means that support any
negative and boolean values (TRUE
is -1 and FALSE
is 0);WORD
offers an higher range of positive values with fast computation performances;INT
(or INTEGER
or SIGNED WORD
) offers an higher range of values and
they support negative numbers, although it is fast but not faster than WORD
;ADDRESS
is similar to WORD
but it can be used to specify memory addresses,
like in POKE
or PEEK
commands;DWORD
offers an even higher range of positive values, but it is slower than WORD
;SIGNED DWORD
(or LONG
) offers an higher range of values and they support negative numbers, although it is not faster than DWORD
.Numbers (numeric literals) can be written in any of the following numberal systems: decimal, hexadecimal and binary. Each form can be expressed in various ways. As described by the previous chapter, binary and hexadecimal numbers are assumed unsigned or signed based on default data type.
NUMERAL | FORMAT | EXAMPLE |
---|---|---|
Decimal | [-]... | 42 |
Hexadecimal | $... &H... 0x... [0-9]...h [0-9]...H | 042h |
Binary | %... | %11000110 |
Strings are fixed-length or variable length series of ASCII characters.
You can define (fixed) length strings by enclosing text inside double quotes ("
):
"this is a static string!"
You can assign fixed string to variables, and this will transform them in dynamic strings:
x = "this is a dynamic string!"
MID$(x, 1, 4) = "that"
PRINT x : ' it will print "that is a dynamic string!"
Depending on which target you are considering, dynamic strings can be a maximum of 255 characters
or 127 characters long, and take up to 1024 bytes. You can change this overall limit. Furthermore,
ugBASIC is able to handle a maximum of 256 (or 128)
different ones at the same time, and you can change this limit, too.
There is no limit for static strings.
In order to optimize the occupied memory, or to increase the possibilities of the language,
it is possible to define the maximum number of dynamic strings that the language must be able
to process. This is done with the DEFINE STRING COUNT
instruction:
DEFINE STRING COUNT 100
The maximum value is 128 on targets based on MOTOROLA 6809 and
256 on all the other targets.
In general, each dynamic string needs 4 bytes to be fully described, in addition obviously
to the space occupied by the actual characters of the string itself. This means that, if
the maximum number of strings that can be processed simultaneously is set as 100
,
as in the previous example, they will occupy 400 bytes.
In order to optimize the occupied memory, or to increase the possibilities of the language,
it is possible to define the maximum space allocated for dynamic strings that the language must be able
to manage. This is done with the DEFINE STRING SIZE
instruction:
DEFINE STRING SIZE 1024
The maximum value depends on the available memory. Moreover, to manage dynamic garbage
collection, we realize that the space occupied will actually be double. So, in the previous
example, the effective memory used by strings will be 2048 bytes.
In ugBASIC the graphical data, the audio data and any other programs's resource
is managed by specific data types,
that acts as an "handle" for the real data. Since the language is isomorphic, it hides the meaning of this handles in a such way that you can only use them in a
isomorphic way. The only resource that is not specialized is BUFFER
.
KEYWORD | KIND |
---|---|
BLIT | Blit operation (definition) |
BUFFER | Generic memory area |
COLOR | Color |
DOJOKA | Handle to DOJO connection |
IMAGE | Single image |
IMAGES | Multiple frames on a single image |
MUSIC | Music track (notes and instruments) |
POSITION | Position on the screen |
SEQUENCE | Multiple images a single image |
SPRITE | Sprite (hardware animable graphic) |
MSPRITE | Multiplexed sprite (hardware animable graphic) |
THREAD | Thread (task) identifier |
TILE | Single tile (character based) |
TILES | Multiple tiles as single tile (character based) |
TILEMAP | Map of tiles |
TILESET | Set of tiles (character/graphic based) |
BUFFER
data type is used to represent a memory area of any kind,
from a spare memory to a specific and big resource. Currently, you are not able to manipulate
this kind of data type in way different from defining them and using them when you need them.
Obviously, you can copy a buffer in another, assign it, compare or convert into another kind
of resource, like IMAGE
, but it is done by compiler at compilation time.
x = #[42424242] : ' this define a buffer of 4 bytes, each of $42 (hexadecimal)
x = #[42424242 : ' the same, but you can omit the last character
BUFFER
using a string. In that case,
embedded sequences can be used to represent non-printing characters:
x = "{42}{42}{42}{42}" : ' this define a buffer of 4 bytes, each of $42 (hexadecimal)
Z(...)
,
which allows you to generate sequences of zeros. You can also use the implicit method,
by loading the buffer from an external file:x = LOAD("buffer.dat")
x = (IMAGE) LOAD("image.bin")
x = (IMAGES) LOAD("images.bin")
LOAD
primitives, that are able to load and convert data at the same time,
generating valid handles.
The ugBASIC language provides a series of instructions and primitives
to handle the BIT
data type, i.e. 0
or
1
.
BIT
variables can be used directly or in expressions.
It is possible to define BIT
type variables and arrays of the
same type. The former will actually occupy only one bit, because they will be
"collected" as much as possible in the same byte, while the latter will be
collected in a minimum space. For example:
DIM x AS BIT, y AS BIT, z AS BIT : ' x, y and z occupy 1 bytes
DIM k(38) AS BIT : ' k will occupy 5 bytes
The HAS BIT
/ HAS NOT BIT
instruction works directly with integer data
types, and allows you to check whether a bit of that number is set
or not, and is a more concise form than using bitmask comparisons.
There are other two forms: BIT bit OF value
and
BIT( value, bit )
that makes the same check.
For example:
x = y HAS BIT 4 : ' this is like y AND 32
x = y HAS NOT BIT 4 : ' this is like y AND 239
x = BIT 4 OF y : ' this is like y AND 32
If you have found a problem, if you think there is a bug or, more
simply, you would like something to be improved, write a topic on the official forum, or open an issue on GitHub.
Thank you!