1 Declaration of a Structure
Structures must be declared before being used. Once declared, a structure can be used to construct data. This structure type data can be assigned to variables or passed (by reference) to other functions.
To define a structure, the struct.declare tag must be used.
The members of a structure are defined by a name and type.
- The name allows users to reference an element of the structure.
- The type allows users to force the conversion or validation of the specific type.
The types of data supported by the language or other previously-defined structures can be used as a member of any structure.
1.1 Predefined Language Types
A member of a structure can contain any type of data defined by the language.
For example, to create a point2d structure, the following code can be used:
<struct.declare type='point2d'> <field name='x' type='double' /> <field name='y' type='double' /> </struct.declare>
1.2 Types of Structures
Structures can be defined for a specific program in which other previously-defined structures can also be used.
For example, to create a structure using two defined types rectangle point2d the following code can be used:
<struct.declare type='rectangle'> <field name='a' type='point2d' /> <field name='b' type='point2d' /> </struct.declare>
2 Initialization of a Variable in a Structure
Once the structure is declared, it can also be used to declare variables. These variables contain the values of fields defined in the structure. To start a variable with a structure, a tag must be used.
To initiate a point2d structure:
<set name='point'> <struct type='point2d'> <number>10</number> <number>20</number> </struct> </set>
To initiate a rectangle structure:
<set name='rect'> <struct type='rectangle'> <struct type='point2d'> <number>10</number> <number>50</number> </struct> <struct type='point2d'> <number>20</number> <number>80</number> </struct> </struct> </set>
Or using point2d type variables:
<set name='rect'> <struct type='rectangle'> <point1/> <point2/> </struct> </set>
The system will perform the conversion of data type to member type, as standard. If the conversion is not possible, an error will occur. In the following example, the two numbers will be converted to the type double.
3 Access to the Members of a Structure
When a variable is a structure type, each field in the structure can be accessed.
Access to the members of a structure is done through the operator [ .] regarding the variable that contains it. For example: <point.x /> will refer to member x of the variable point.
<println><point.x /></println>
Referencing Structures by ${}
As of June 2018, structure field values can be parsed from ${} variable substitution directly.
<file name="${mystruct.filename}">
4 Visibility of a Structure
The field of a structure starts from the main instance and is visible to all descendants, local or external routines. This also implies that a structure declared in a sub-function is visible from any point in the program.
For example, the structure point2d defined in local function "declare_structs" is visible from the code that belongs to the main part.
<xsql-script name='test'> <body> <function name='declare_structs'> <args/> <body> <struct.declare type='point2d'> <field name='x' type='double' /> <field name='y' type='double' /> </struct.declare> </body> </function> <declare_structs /> <set name='a'> <struct type='point2d'> <number>10</number> <number>20</number> </struct> </set> <println><a/></println> <println>a.x=<a.x /></println> </body> </xsql-script>
5 Observations
Defining a structure with the name of another existing structure is an error. In this situation, a runtime exception will be generated to abort the program.
structure 'point2d' already defined
It is also invalid to use a reserved name for data types in the structure declaration, for example string, object... A runtime exception will be generated to abort the program.
invalid type 'double' for structire declaration
6 Examples
Below are some examples of the use of structures.
6.1 Distance Between Two Points
<xsql-script name='distance'> <body> <struct.declare type='point2d'> <field name='x' type='double' /> <field name='y' type='double' /> </struct.declare> <set name='p1'> <struct type='point2d'> <number>10</number> <number>20</number> </struct> </set> <set name='p2'> <struct type='point2d'> <number>-10</number> <number>-20</number> </struct> </set> <!-- Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) --> <set name='dist'> <math.sqrt> <add> <math.pow> <sub><p1.x/><p2.x/></sub> <number>2</number> </math.pow> <math.pow> <sub><p1.y/><p2.y/></sub> <number>2</number> </math.pow> </add> </math.sqrt> </set> <println>Distance between <p1/> and <p2/> = <dist/></println> </body> </xsql-script> Distance between point2d {x=10.0,y=20.0} and point2d {x=-10.0,y=-20.0} = 44.721359549995796
6.2 A rectangle based on 2 point structures
<xsql-script name='rectangle'> <body> <struct.declare type='point2d'> <field name='x' type='double' /> <field name='y' type='double' /> </struct.declare> <struct.declare type='rectangle'> <field name='a' type='point2d' /> <field name='b' type='point2d' /> </struct.declare> <set name='p1'> <struct type='point2d'> <number>10</number> <number>20</number> </struct> </set> <set name='p2'> <struct type='point2d'> <number>-10</number> <number>-20</number> </struct> </set> <set name='r'> <struct type='rectangle'> <p1/> <p2/> </struct> </set> <println><r/></println> <println>p1.x=<p1.x /></println> <println>p1.y=<p1.y /></println> <println>p2.x=<p2.x /></println> <println>p2.y=<p2.y /></println> <println>r.a.x=<r.a.x /></println> <println>r.a.y=<r.a.y /></println> <println>r.b.x=<r.b.x /></println> <println>r.b.y=<r.b.y /></println> </body> </xsql-script> rectangle {a=point2d {x=10.0,y=20.0},b=point2d {x=-10.0,y=-20.0}} p1.x=10.0 p1.y=20.0 p2.x=-10.0 p2.y=-20.0 r.a.x=10.0 r.a.y=20.0 r.b.x=-10.0 r.b.y=-20.0