Structures

 [private | public] structure identifier
    variable-declaration
   {variable declaration}
 end structure
  • Private – An optional keyword which ensures that a structure is only available from within the module it is declared. Structures are private by default.
  • Public – An optional keyword which ensures that a structure is available to other programs or modules.
  • Identifier – A mandatory type name, which follows the standard identifier naming conventions
  • Variable-declaration – One or more variable declarations Type – A mandatory data type. Supported types include boolean, bit, byte, sbyte, short, ushort, integer, uinteger, single, structures, string and char.

A structure is a collection of one or more variable declaration fields. Each field can be a different data type. A structure is an extremely useful and powerful feature of the Firewing language which enables you to assemble dissimilar elements under one single roof. To better understand structures, the following example illustrates how to create a new structure called Time,

Structure Time
   Dim hours As Byte
   Dim minutes As Byte
End Structure

The declaration above informs the compiler that Time contains two byte fields, called hours and minutes. We can now create a variable of type Time, in exactly the same way as you would any other compiler type, such as byte or single. For example,

Dim myTime As Time

Access to an individual field within the variable myTime is achieved by using the dot (.) notation,

myTime.hours = 9
myTime.minutes = 59

A structure can also use another structure in one or more of its field declarations. For example,

' time structure
Structure Time
   Dim hours As Byte
   Dim minutes As Byte
End Structure

' sample structure...
Structure Sample
   Dim theTime As Time
   Dim value As Short
End Structure
Dim mySample As Sample

We now have a type called Sample, who's field members include theTime (of type Time) and value (of type ushort). Again, dot (.) notation is used to access individual field elements,

mySample.theTime.hours = 15
mySample.theTime.minutes = 22
mySample.value = 1024

Structures can also be used with arrays. For example, using the previously declared Sample type, we could declare and access multiple mySample variables by declaring an array,

Dim mySamples(24) As Sample ' array of samples, one every hour

To access each field for every array element, we just need to iterate through the samples array,

Dim index As Byte
For index = 0 To UBound(mySamples)
   mySamples(index).theTime.Hhours = 0
   mySamples(index).theTime.minutes = 0
   mySamples(index).value = 0
Next  

The above code is actually a very verbose way of initializing all fields to zero, but it does demonstrate how each field can be accessed. It should be noted that by using the inbuilt compiler command erase, the above can be achieved by using,

Erase(Samples) 

Unions

In the previous structure example, the total size of the structure is the sum of all members of the structure. For example, Time has two member fields (hours and minutes) and each field is one byte in size. Therefore, the total size of the structure is two bytes. A union works differently in that member fields can share the same address space. For example,

Structure Status
   Dim val As Byte
   Dim enabled As Val.0
   Dim connected As Val.1
   Dim overrun As Val.2
End Structure

The member fields enabled, connected and overrun are aliased to the byte variable val. They don't have separate storage requirements - they are shared with val. For example,

 
Dim myStatus As Status
myStatus.val = 0 ' clear status
myStatus.connected = 1

In the above example, we can access the structure as a byte value or access individual bits. Importantly, the total structure size is only one byte. You can apply all the standard aliasing rules to structures. For example,

 
Structure IPAddr
   Dim val(4) As Byte
   Dim IP As val(0).AsUInteger
End Structure

Sub Main()
   Dim myAddr As IPAddr
   myAddr.IP = &HFFFFFFFF
   myAddr.val(0) = &H00
End Sub

In this example, the IP address structure only uses 4 bytes of storage. In some cases, it may not be possible to create a union through aliasing alone. For example, the member field type may be another structure. In these situations, you can use the union keyword, like this:

Structure Word 
   Dim LSB As Byte 
   Dim MSB As Byte 
End Structure 

Structure Value 
   Union byteVal As Byte  
   Union wordVal As Word 
   Union floatVal As Single
End Structure

In the above example, the size of the structure is equal to the size of the largest member field which is 4 bytes (the size of single). Another way to think of the union keyword is that it 'resets' the internal offset address of the member field to zero. For example,

 
Structure TValue
   Dim floatVal As Single ' offset = 0 (0 + 4 byte = 4)
   Dim wordVal As UShort  ' offset = 4 (4 + 2 byte = 6) 
   Dim byteVal As Byte    ' offset = 6 (6 + 1 byte = 7)
End Structure             ' total storage requirement = 7

The above structure declaration shows the starting offset address, with the total storage requirement for the structure. Now take a look at the same structure, but this time with the union keyword:

 
Structure Value
   Union floatVal As Single ' offset = 0 (0 + 4 byte = 4)
   Union wordVal As UShort  ' offset = 0 (0 + 2 byte = 2) 
   Union byteVal As Byte    ' offset = 0 (0 + 1 byte = 1)
End Structure               ' total storage requirement = 4

User Types

 [private | public] Type identifier = Type
  • Private – An optional keyword which ensures that an alias is only available from within the module it is declared. Variables are private by default.
  • Public – An optional keyword which ensures that an alias is available to other programs or modules.
  • Identifier – A mandatory and previously declared variable name, which follows the standard identifier naming conventions
  • Type – A mandatory data type. Supported types include boolean, bit, byte, sbyte, short, ushort, integer, uinteger, single, structures, string and char.

You can create your own specific user type based on an existing data type or structure. This has two main purposes:

  • To ensure a rigorous application of type checking. See type casting later in this reference.
  • To enable overloaded operations to identify which overloaded routine to call when the data presented is of a similar data type. See overloading later in this reference)

Here is an example of a user type:

Type myType = Byte
Dim myVar As myType