3.1 Objects, values and types
Objects are emBASIC's abstraction for data. All data in an emBASIC program
is represented by objects of DPBM pool. Every object has an identity,
a type and a value. An object's identity never changes once it has been
created; you may think of it as the object's address in memory.
An object's type is also unchangeable. It determines the operations that
an object supports and also defines the possible values for objects of
that type.
Objects are never explicitly destroyed; however, when they become unreachable
they may be garbage-collected. Garbage collection is implemented, as long
as no objects are collected that are still reachable.
3.2 The standard type hierarchy
Below is a list of the types that are built into emBASIC. Extension modules
written in C can't define additional types. Future versions of emBASIC
may add types to the type hierarchy.
3.2.1 Primitive types
EmBasic supports 11 primitive types:
|
INT8 |
signed 8 bit wide |
|
INT |
signed 16 bit wide |
|
LONG |
signed 32 bit wide |
|
BYTE |
unsigned 8 bit wide |
|
WORD |
unsigned 16 bit wide |
|
DWORD |
unsigned 32 bit wide |
|
FLOAT |
32 bit wide float data IEEE-754 |
|
DOUBLE |
64 bit wide float data IEEE-754 |
|
BIT |
boolean, values TRUE or FALSE |
|
CHAR |
Single 8-bit character |
|
STRING |
Variable length character string |
The type of a variable is usually not set by the programmer; rather, it
is decided at runtime by emBASIC depending on the context in which that
variable is used. In some cases cast conversion may take place.
3.2.2 Compound types
emBASIC supports two compound types: arrays and structures.
Arrays can have one, two or three dimensions. Arrays must be declared
explicitly. The total number of elements in an array must not exceed 65536.
Structures are declared as user datatypes.
Messages are specific structures used to declare message variables to
be used in the network message exchange and communication with the system
tasks. A message datatype differs from standard structures by special
routing fields like command number and bus type.
3.3 Variable declarations
EmBasic supports implicit and explicit variable declaration methods.
3.3.1 Implicit declaration
Implicit declaration, also known as autovariables are defined only for
primitive datatypes. One can declare a variable using a special postfix
like '%' for integer variables and '$' for strings. This however is rarely
used and is not mandatory.
Hence, if you make a simple assignment like x = 99 emBASIC regards this
as integer by default, and mystr = “It’s me” will be
accepted as string.
3.3.2 Explicit declaration
To declare a variable the DECL or DECLARE keywords can be used. They
set the datatype and optionally can accept an assignment for an initial
value. If no value is assigned, emBASIC assumes a neutral value for this
datatype. Also they declare the scope of variables. By default all variables
are private to the current task or sequence. Add the PUBLIC keyword to
the declaration clause to make the variable global:
DECLARE PUBLIC flag AS BIT = FALSE
Implicitely declared variables within a function or subroutine become
local to it, while explicitly declared ones are available from the surrounding
task/sequence. Add the LOCAL keyword to make them local to the function/subroutine:
DECLARE LOCAL flag AS BIT
CONST is used instead of DECL to specify a constant; it must be followed
by an assignment. Explicit declarations are made with the DECLARE statement
described below.
3.4 Datatypes
3.4.1 Primitive datatypes
The explicit declaration statement for primitive datatype has the following
format:
CONST|DECL|DECLARE [PUBLIC|LOCAL] variable AS type [
= {value|list} ]
Examples:
|
Declaring a double variable with a neutral value |
DECLARE interval AS DOUBLE |
|
Declaring a string variable with an initial value |
DECLARE message AS STRING = "It's too dark" |
|
Declaring i, j and k as plain integer
variables with initial values 1, 2 and 3 |
DECLARE i, j, k AS INT = 1, 2, 3 |
|
Declaring i, j and k as plain integer variables with an initial
value of 7 for i and neutral values for j and k |
DECLARE i, j, k AS INT = 7 |
|
Declaring a 1-dimensional array with 1000 elements. The index must
not exceed 999 as the array starts from 0 |
DECL line[1000] AS DOUBLE |
|
Declaring a 2-dimensional array with initial values. The assignment
sets elements [0,0]; [0,1]; [0,2]; [1,0]; [1,1] and [1,2] |
DECL square[2,3] AS CHAR = 'q', 'w', 'e', 'r',
't', 'y' |
|
Declaring a global 3-dimensional array
with neutral values |
DECL PUBLIC cube[10,10,10] AS FLOAT |
|
Declaring an integer constant with an initial value of 0xFF |
CONST maxval AS INTEGER = 0xFF
or: CONST maxval AS INTEGER = FFH |
|
|
|
3.4.2 IO datatype
To ease the handling of process input and output, ports like digital
or analog inputs, counters or pulse output devices, these can be declared
as process variables. The declaration links the variable name to a physical
port and takes various parameters such as the type of i/o, a module number
in a modular hardware like ELZET80’s TSM or DinX, the number of
an input or output within the module (the “channel”) and a
function name for software (Express-I/O) -simulated functions like pulse
generation using a standard digital output.
The explicit declaration statement for I/O datatypes has the following
format:
DECLARE [scope] variable AS io_type direction [VECTOR]
(bus, module, channel)
[ USING “xpname” ]
|
scope |
vector |
|
variable |
identifier (variable name) |
|
io_type |
one of DIGITAL, ANALOG, EVTCNT, FREQ, PWM |
|
direction |
one of INPUT, OUTPUT |
|
bus |
one of $CPU, $TSM, $I2C) |
|
module |
module number as set on address switch |
|
channel |
channel within module 1..n |
|
xpname |
XP program name to use (EDGE, PULSE,...) |
Examples:
DECL myMotor AS DIGITAL OUTPUT ($CPUBUS, $DOUT, 1)
DECL mySwitch AS DIGITAL INPUT ($CPUBUS, $DIN, 7)
DECL Generator AS COUNTER ($CPUBUS, $EVTCNT, 0)
### Not sure whether $DIN is necessary - probably only with $CPUBUS
DECL vec AS DIGITAL INPUT VECTOR ($TSMBUS,$DIN,module,
NULL)
3.4.3 Timer datatype
emBASIC has timer variables that can be declared as up or down counters.
They can be set and read. The system increments or decrements (depending
on INC or DEC clause) all timers every millisecond multiplied times the
value of @TIMEFAC system variable.
DECL timervariable AS [PERIODIC] TIMER INTERVAL
value {INC|DEC}
3.4.4 Custom datatypes
emBASIC supports the definition of custom datatypes.###
3.4.5 Structures
To define a custom structure, put the desired component declarations
on consecutive lines of the TYPE definition body. Each time the line is
entered; emBASIC checks this line and adds it to the structure to be created.
TYPE product AS STRUCT
id AS INTEGER
name AS STRING
ENDTYPE
To access a member of a structure use a primary
name followed by a period and component name. For example:
product.id = 5678
product.name = “hairdryer”
3.4.6 Enumerations
Enumeration types are defined with DEF ENUM followed by all enumeration
constants:
TYPE color_enum AS ENUM = (red, blue, green, pink)
TYPE tool_enum AS ENUM = (hammer, wrench, pliers, screwdriver)
Usually, enumerations start from zero and count up. If you like to introduce
another starting point, simply make an assignment like :=, followed by
the value. If you like all items to have different values, assign values
to each of them:
TYPE month_enum AS ENUM (january =1,february,december )
TYPE color_e AS ENUM ( rose = 0xE1E4FF, gray = 0x908070)
You can use the enumerations by declaring a variable to be of an enumeration
type:
DECL color AS color_e
colore =
3.4.7 Date and Time
There is a number of date/time functions supported in emBASIC. They
operate with the special DATETIME structure described later in this chapter.
DECL birthday AS DATETIME ###
The SYSTIME data structure contains the broken down
Gregorian date value. It is defined as follows:
typedef struct {
short millisecond; /* millisecs after the second -- [0, 999] */
short second; /* seconds after the minute -- [0, 60] */
short minute; /* minutes after the hour -- [0, 59] */
short hour; /* hours since midnight -- [0, 23] */
short day; /* day of the month -- [1, 31] */
short month; /* months since January -- [0, 11] */
short year; /* years since 1900 */
short wday; /* days since Sunday -- [0, 6] */
} SYSTIME;
|