Variables

Top  Previous  Next

A variable is a temporary storage location for information in your program.  Think of it as memory for the data used in your program. Variable names can be any identifier you choose as long as they do not conflict with any reserved word or constant.

Emergence BASIC supports source global, program global and local variables. Source global variables are defined outside of any subroutine and are usable by any part of the code contained within the source file it is defined in. Program global variables are the same as source global but are made usable to any source file in your program by using the GLOBAL keyword. Local variables are defined within a subroutine between the SUB and ENDSUB keywords and are only usable by the code within that subroutine.

 

Defining variables

Variables must be defined before use either with the DEF statement or automatically defined by assigning a value. Automatic definition of variables can be disabled using the AUTODEFINE statement. Variables can also be defined using the reverse type method by specify the variable type first, followed by the identifier.

Examples

DEF name as STRING
name = "John Doe"
'Defines an integer variable by automatic assignment definition.
myNumber = 1
'Reverse type method. Identical to DEF name2 as STRING
STRING name2

Program global variables located in other source files can be accessed using the EXTERN keyword in place of DEF. Create a program global variable by using the GLOBAL keyword along with the DEF statement.
 

'in file1
GLOBAL _gCodeName
DEF _gCodeName as STRING
...
'in file 2
EXTERN _gCodeName as STRING
PRINT _gCodeName

 

Variable types

A variables type tells the compiler what kind of data a variable can contain. Emergence BASIC supports numerous built in types and user types can also be described using the TYPE statement. Once a variable is defined to a specific type it cannot be changed to a different type. The exception of this is the POINTER type which can point to any data type using type-casting. Built in variable types are reserved words and color highlighted in the editor as red by default. See Figure 1 for a list of built in variable types

 

Variable Assignments

Variables are assigned values either directly with the = symbol or indirectly by a function or statement.   Variables can be assigned the contents of other variables as long as they are the same type or an appropriate conversion can be performed by the compiler.   For example, an integer variable can be assigned the contents of a float variable but will loose its fractional value:
 

DEF WorkDays:FLOAT
DEF Days:INT
WorkDays = 13.5
Days = WorkDays
PRINT Days

Will print the number ‘13’ as the fractional value of ‘.5’ was lost in the conversion of  FLOAT to INT.

Any assignment conversions that cannot be performed by the compiler will generate an Invalid Assignment error in the Build window of the IDE. An example of an invalid assignment would be trying to assign a number to a string
 

DEF Name$,Name2$:STRING
DEF Initial:CHAR
Name$ = "John Doe"
Name2$ ="Julie Doe"
Initial = "A"
Name$ = Name2$
REM this next line produces an error
Name2$ = 100

The compiler will also generate an error if you try and assign a value to a constant.

 

Arrays

An array is a collection of data of the same type. Arrays are referenced by their variable name and an index. Think of a box of cookies. Each row of cookies can be thought of as an array.  EBASIC supports arrays up to five array dimensions. When using an array the index is enclosed in brackets '[ ]'.
 

DEF age[20]:INT
age[0] = 40
age[1] = 32

 

As noted in the above example you access an array using an ‘index’ into the array. Indices start at 0 so the maximum index will be one less than the value specified in the DEF statement.  To create a multidimensional array use the comma to separate dimensions.
 

DEF myarray[20,20]:INT
DEF BigArray[10,10,10,10,10]:FLOAT
myarray[0,1] = 5 

An array may be initialized by using a list of data parameters. Each line can have up to 100 data elements and the array can be initialized starting with a certain element.
 

DEF myarray[10]:INT
'initialize the first 7 elements
myarray = 1,10,23,2,4,16,27
'initialize the last 3 elements
myarray[7] = 5,18,42

Array dimensions in the DEF statement must either be a numeric constant or resolve to a constant when compiling. Dynamic arrays are supported by using the NEW statement or using memory with ALLOCMEM.

 

The ISTRING type

ISTRING is an advanced STRING type that can be defined and accessed like an array. ISTRING can then be used anywhere a normal string would be expected. Unlike a normal STRING variable the maximum length of an ISTRING is limited only by available memory.
 

OPENCONSOLE
'Define a string of exactly 30 characters
DEF name[30]:ISTRING
name = "john Smith"
name[0] = "J"
PRINT name
PRINT "Press any key to close"
DO:UNTIL INKEY$ <> ""
CLOSECONSOLE
END

 

The IWSTRING type

IWSTRING is an advanced WSTRING type that can be defined and accessed like an array. IWSTRING can then be used anywhere a normal Unicode string would be expected. Unlike a normal WSTRING variable the maximum length of an IWSTRING is limited only by available memory.
 

OPENCONSOLE
'Define a string of exactly 30 characters
DEF name[30]:IWSTRING
name = L"john Smith"
name[0] = L"J"
PRINT W2S(name)
PRINT "Press any key to close"
DO:UNTIL INKEY$ <> ""
CLOSECONSOLE
END

User defined variable types (UDT)

The TYPE statement begins defining a user variable type. The new type will contain all of the variables between TYPE and ENDTYPE. Accessing the variables in a user type is done with the dot operator ‘.’.  Any variable type can be defined between TYPE and ENDTYPE. Once a user variable type is defined you can create variables of that type using the DEF statement or by assigning. Emergence BASIC UDT's conform to ANSI standards for element packing. The element packing value can be changed if needed, see the TYPE command for details.
 

TYPE phonerecord
   DEF Name:STRING
   DEF Age:INT
   DEF Phone[20]:ISTRING
ENDTYPE
DEF Rec:phonerecord
Rec.Name = "Joe Smith"
Rec.Age = 35
Rec.Phone = "555-555-1212"

All strings and arrays are stored by value in an Emergence BASIC UDT. If you require a reference to a string in a UDT for an API function use the POINTER type in place of the STRING type.

Unions

A union is a special form of UDT where all member variables share the same memory. The size of a union is the size of the largest member aligned to the element packing value.  Emergence BASIC supports both unions embedded in TYPE definitions and  named unions defined outside of a TYPE definition.  Unions are used primarily as a memory saving technique when separate UDT definitions might differ by only the type of a single member variable.  Examples:
 

TYPE number
  INT numtype
  UNION
      FLOAT flValue
      UINT uiValue
  ENDUNION
ENDTYPE
 
DEF n1,n2 as NUMBER
n1.numtype = 1: '1 = float, 2 = uint
n1.uiValue = 1002
n2.numtype = 2
n2.flValue = 123.45f

In the above example both flValue and uiValue share the same memory within the UDT.  Only one is in use at any time.  The size of the UDT is 8 bytes, instead of 12 if we did not use the union.

Creating aliases for variable types with TYPEDEF

The TYPEDEF (type define) statement allows referring to a built in variable type by a different name. This can aid in code readability and conversion of source code from other languages. For example some common variable types found in C are 'byte', 'bool', 'HANDLE', etc. which are themselves aliases for an unsigned character, integer and unsigned integer.  These type names can be duplicated in EBASIC using the following statements:
 

TYPEDEF byte CHAR
TYPEDEF bool INT
TYPEDEF HANDLE UINT

You can also use a previous type define to create a new one as in:

 

TYPEDEF HWND HANDLE

Once a variable type has been aliased with TYPEDEF it can be used in place of the actual type.
 

DEF bDone as bool
DEF hWnd as HWND

It is important to note that the name does not change how the variable is used. Internally after the above is executed a bool type would still be an INT.  Its just a convenient way of keeping track what a variable is being used for.


Figure 1. Built in variable types:

TYPE

AUTODEFINE

USAGE

DIRECT ASSIGN

SIZE IN BYTES

WORD

NO

Unsigned short integer from 0  to 65535

YES

2

SWORD

NO

Signed short integer from –32,768 to 32,767

YES

2

INT

YES

Signed integer

YES

4

UINT

YES

Unsigned integer

YES

4

INT64

YES

Signed large integer

YES

8

UINT64

NO

Unsigned large integer

YES

8

FLOAT

YES

Single precision numbers

YES

4

DOUBLE

YES

Double precision numbers

YES

8

STRING

YES

Text up to 254 characters

YES

255

WSTRING

TES

Unicode text up to 254 characters

YES

512

ISTRING

NO

Dimensionable string.

YES

Variable

IWSTRING

NO

Dimensionable unicode string.

YES

Variable

CHAR

NO

Single character of text or any number from 0 to 255

YES

1

SCHAR

NO

Signed character. Integer value from -128 to 127

YES

1

WINDOW

NO

WINDOW UDT

NO

N/A

DIALOG

NO

DIALOG UDT

NO

N/A

FILE

NO

ASCII file I/O

NO

N/A

BFILE

NO

Binary file I/O

NO

N/A

MEMORY

NO

Allocated memory

YES

N/A

POINTER

NO

Variable reference

YES

N/A

COMREF

NO

COM object pointer

YES

4

DATABLOCK

NO

Reserved. Used by DATA functions.

NO

N/A

ANYTYPE

NO

Variable subroutine parameters.

NO

8

HEAP

NO

Reserved. Special return pointer used by string functions.

YES

4

WHEAP

NO

Reserved. Special return pointer used by string functions.

YES

4