Expressions


You can write compound expressions in GDL statements. Expressions can be of numerical and string type.
They are constants, variables, parameters or function calls and any combination of these in operators.
Round bracket pairs (( )) (precedence 1) are used to override the default precedence of the operators.

Simple type variables can be given numerical and string values, even in the same script,
and can be used in numerical and string type expressions respectively.
Operations resulting in strings CANNOT be used directly as macro names in macro calls,
or as attribute names in material, fill, line type or style definitions.
Variables given a string value will be treated as such and can be used wherever string values are required.
If later in the script the same variable is given a numerical value,
it will be usable in numerical expressions only until it is given a string value again.
Where possible, in the precompilation process the type of the expressions is checked.

DICT

DICT variableName1[, variableName2...]

Compatibility: introduced in ARCHICAD 23.

GDL supports dictionaries. A variable is declared as a dictionary after the above declaration statement (and cannot be changed to array or simple type or vice versa). Library part parameters can also be dictionaries, by selecting Dictionary type in the parameter list.

After the DICT keyword there can be any number of variable names separated by commas. Each variable will contain hierarchical key and value pairs. A key of the dictionary can be referenced with dot notation. The full path of a key cannot be longer than 255 characters (counting array indices as one character).

Dictionaries and simple type values:

  • simple type (string, integer, floating-point) values can be assigned to dictionary keys,
  • no declaration is necessary, the value type for the key is set by the current value:
    DICT myDictionary
    
    myDictionary.element1 = 1
    myDictionary.element1 = "hello"
    
    print myDictionary

Dictionaries and derived type values:

  • a dictionary can nest array type (with one dimension only) and dictionary type keys,
  • an array inside a dictionary can contain unnamed dictionary or simple types (referenced by the index),
  • however, a standalone array type parameter/variable cannot contain dictionary type elements,
  • a nested array key can be initialized by referencing it right away, no need to declare with DIM in this case,
    DICT myDictionary
    myDictionary.myArray[1] = 1
    myDictionary.myArray[2] = 5
    
    print myDictionary
  • unreferenced indexes of a nested array are automatically initialized according to the type of the first referenced element of the array (string keys to “”, numerical keys to 0, dictionary keys to {}),
    DICT myDictionary
    DICT dictForNesting
    dictForNesting.elem1 = "hello"
    dictForNesting.elem2 = "world"
    
    myDictionary.myArray[2] = dictForNesting
    
    print myDictionary
    
    DICT myDictionary2
    myDictionary2.myArray[3] = 33
    myDictionary2.myArray[4] = 44
    
    print myDictionary2
  • the values of a nested array has to be of the same type (all string, all integer, all floating-point or all dictionary types), this is contrary to how arrays work, so extra caution is needed!
    DICT myDictionary2
    myDictionary2.myArray[1] = 1
    myDictionary2.myArray[2] = 1.0 ! GDL error
  • to change the value types of a nested array, it needs to be reset first: create an empty array, and overwrite the nested array with this new empty array. The type of the next referenced value will set the type for the array after the reset automatically:
    DICT myDictionary
    myDictionary.myArray[1] = "hello"
    print myDictionary
    
    DIM arrayForReset[]
    myDictionary.myArray = arrayForReset
    print myDictionary
    
    myDictionary.myArray[1] = 10000
    print myDictionary
  • changing the type of the first value of a nested array containing that value only, will not change the type of the array!
    DICT myDictionary
    myDictionary.myArray[1] = "hello"
    print myDictionary
    
    myDictionary.myArray[1] = 10000 ! GDL error
    print myDictionary

Initialization and copying:

  • the first reference of the dictionary has to be DICT dictName, a subroutine containing the name of the dictionary can not precede it (same as with DIM arrays),
  • initialization is required before the first use of a key, either explicitly with assignment to the key, or implicitly with assigning a dictionary that contains the key at the right depth.
    DICT myDictionary
    
    myDictionary.level1.a = 1
    myDictionary.level1.b = 2
    myDictionary.level2 = myDictionary.level1
    
    print myDictionary.level2.b
  • writing the dictionary name without actual inner keys references the whole dictionary structure, which is accepted in some cases (CALL, PRINT, LET statements),
  • writing part of the structure references the subtree below that key as a dictionary
    DICT myDictionary
    myDictionary.point1.x = 1
    myDictionary.point1.y = 1
    myDictionary.point1.type = 0
    print myDictionary
    
    DICT myPoint
    myPoint = myDictionary.point1
    print myPoint
    
    myDictionary.point2 = myDictionary.point1
    print myDictionary
  • assigning all or part of a dictionary makes a deep copy of the right-hand side on the left-hand side
    DICT myDictionary, tempPoint
    tempPoint.x = 1
    tempPoint.y = 1
    myDictionary.line.point1 = tempPoint
    
    tempPoint.x = 2
    tempPoint.y = 2
    myDictionary.line.point2 = tempPoint
    
    DICT myLine
    myLine = myDictionary.line
    myDictionary.line.point2.x = 0
    print myLine

Macro calls and requests:

  • in macro calls, dictionary type values can be sent to the macro if there is a dictionary type parameter on the receiving end,
  • RETURNED_PARAMETERS can work with dictionaries: an empty DICT has to be declared on the receiving end (caller object). In the following code myDictionary is a dict type parameter in the macro, _myDictionary is a dict type variable on the caller object side:
    ! caller object Master script
    DICT _myDictionary
    
    _myDictionary.element1 = 1
    _myDictionary.element2 = 2
    
    DICT _dictForReceivedData
    
    call "macroname" parameters all myDictionary = _myDictionary,
                returned_parameters _dictForReceivedData
    
    print _dictForReceivedData
    
    ! in the macro object Master script
    myDictionary.element1 = myDictionary.element1 * 2
    myDictionary.element2 = myDictionary.element2 * 2
    
    end myDictionary
  • LIBRARYGLOBAL requests cannot return dictionary type values.

Visualization and functions:

  • dictionary type parameters are not visible on “All Parameters” page in the “Settings” dialog,
  • dictionary type parameters are not available for Listing display or IFC mappings,
  • text-like visualization works only with the PRINT command (“Check Script” warning and printed to Report window in JSON format),
  • general text handling commands like TEXT2, RICHTEXT2, etc. are not supporting the complete dictionary,
  • however, nested non-dictionary type values can be displayed with them,
    DICT myDictionary
    myDictionary.myArray[1] = "hello"
    myDictionary.myArray[2] = "world"
    
    text2 0, 0, myDictionary.myArray[1] + " " + myDictionary.myArray[2]
    print myDictionary
  • values for a dictionary type parameter can only be set via the Parameter script (no direct user input is available through Parameter list or UI controls), the VALUES command is disabled for this type,
  • however, using non-dictionary parameters for user input can work. In the following code, myDictionary is a dictionary type parameter, stTextInput is a string type parameter (which can be used in User Interface, displayed on the “All Parameters” page, and works together with GLOB_MODPAR_NAME):
    ! in Parameter Script
    myDictionary.text1 = stTextInput
    parameters myDictionary = myDictionary
    
    ! in Master Script
    print myDictionary
    
    ! in 2D script
    TEXT2 0, 0, myDictionary.text1
  • value replacement using the LP_XMLConverter tool is currently unavailable for dictionary type parameters.

HASKEY

HASKEY (dictionary.key)

Returns as a boolean whether key has been previously defined in dictionary (key can include sub-keys).

Example:

DICT myDictionary
myDictionary.point[1].x = 1
myDictionary.point[1].y = 1

print HASKEY(myDictionary.point)        ! true
print HASKEY(myDictionary.point[2])     ! false
print HASKEY(myDictionary.point[1].z)   ! false

REMOVEKEY

REMOVEKEY (dictionary.key)

The function removes the referred key from the dictionary, along with the assigned value(s). If the removal was successful, the return value is 1, othervise 0 (in case the key is non-existent or already deleted).

Example:

DICT myDictionary
myDictionary.myText[1] = "hello"
myDictionary.myOtherText[1] = "world"

print myDictionary

_dummy = REMOVEKEY(myDictionary.myOtherText)
print myDictionary, _dummy

_dummy2 = REMOVEKEY(myDictionary.myNonExistentText)
print myDictionary, _dummy2

DIM

DIM var1[dim_1], var2[dim_1][dim_2], var3[ ],
        var4[ ][ ], var5[dim_1][ ],
        var5[ ][dim_2]

GDL supports one and two dimensional arrays. Variables become arrays after a declaration statement, in which their dimensions are specified. (Dictionary type variables cannot be redeclared as arrays or vice versa.)

After the DIM keyword there can be any number of variable names separated by commas.
var1, var2, … are the array names, while the numbers between the brackets represent the dimensions of the array (numerical constants).
Variable expressions cannot be used as dimensions.
If they are missing, the array is declared to be dynamic (one or both dimensions).

Library part parameters can also be arrays. Their actual dimensions are specified in the library part dialog.
Parameter arrays do not have to be declared in the script and they are dynamic by default.
When referencing the library part using a CALL statement, the actual values of an array parameter can be an array with arbitrary dimensions.

The elements of the arrays can be referenced anywhere in the script but if they are variables, only after the declaration.

var1[num_expr] or var1
var2[num_expr1][num_expr2] or var2[num_expr1] or var2

Writing the array name without actual indices means referencing the whole array (or a line of a two-dimensional array)
which is accepted in some cases (CALL, PRINT, LET, PUT, REQUEST, INPUT, OUTPUT, SPLIT statements).
For dynamic arrays there is no limitation for the actual index value. During the interpretation,
when a non-existing dynamic array element is given a value,
the necessary quantity of memory is allocated and the missing elements are all set to 0 (numerical).

Warning! This may cause an unexpected out of memory error in some cases.
Each index – even of a possibly wrong, huge value – is considered valid, since the interpreter is unable to detect the error condition.
A non-existing dynamic array element is 0 (numerical).

Arrays having a fixed dimension are checked for the validity of the actual index on the fixed dimension.
Array variables with fixed length cannot accept dynamic array values in assignments.
However, dynamic arrays that are given whole array values will take on those values.
This also applies to some statements where whole array references can be used as return parameters. (REQUEST, INPUT, SPLIT).

Array elements can be used in any numerical or string expression. They can be given string or numerical values.

Indices start with 1, and any numerical expression can be used as an index.

Array elements can be of different simple types (numerical, string, group).
The type of the whole array (main type) is the type of its first element ([1] or [1][1]).
Parameter and global variable arrays cannot be of mixed type.

VARDIM1

VARDIM1 (expr)

VARDIM2

VARDIM2 (expr)

These functions return as integers the actual dimension values for the (array) expression specified as a parameter.
They must be used if you want to handle correctly all actual elements of a dynamic array or an array parameter.
If no element of a dynamic array was previously set, the return value is 0. For one-dimensional arrays VARDIM2 returns 0.

Example 1:
Examples for numeric expressions:

Z
5.5
(+15)
-x
a*(b+c)
SIN(x+y)*z
a+r*COS(i*d)
5' 4"
SQR (x^2 + y^2) / (1 - d)
a + b * sin (alpha)
height * width

Example 2:
Examples for string expressions:

"Constant string"
name + STR ("%m", i) + "." + ext
string_param <> "Mode 1"

Example 3:
Examples for expressions using array values:

DIM tab[5], tab2[3][4] ! declaration
tab[1] + tab[2]
tab2[2][3] + A
PRINT tab
DIM f1 [5], v1[], v2[][]
v1[3] = 3     ! v1[1] = 0, v1[2] = 0, array of 3 elements
v2[2][3] = 23 ! all other elements(2 X 3) = 0
PRINT v1, v2
DIM f1 [5], v1[], v2[][]
FOR i = 1 TO VARDIM1(f1)
    f1[i] = i
NEXT i
v1 = f1
v2 [1] = f1
PRINT v1, v2

Example 4:
Examples for expressions using dictionary values:

DICT _exampleDict

! DICT simple key types

_exampleDict.false = (1 = 2)        ! logical false (integer internally)
_exampleDict.true = (1 = 1)         ! logical true (integer internally)
_exampleDict.int = 2                ! integer
_exampleDict.float = 1 / 3          ! floating-point
_exampleDict.string = "Custom text" ! string

! DICT array key type

! initialize array on-the-fly
_exampleDict.array[1] = _exampleDict.float
! append to array on-the-fly
_exampleDict.array[2] = _exampleDict.float * 2
! append to array with automatic initialization of elements in between
_exampleDict.array[4] = _exampleDict.float * 3

! DICT array of DICTs

DIM array[]
DICT _element
_element.a = "A"
_element.b = 1
_exampleDict.array = array          ! change existing array to empty one
_exampleDict.array[2] = _element    ! different vartype than previous

! print DICT array of DICTs
print "\n\t",
    "Print DICT array of DICTs",
    "\n--------------------------------------------------------------------------------\n\t",
    vartype(_exampleDict.array), vardim1(_exampleDict.array), "\n",
    _exampleDict.array,
    "\n--------------------------------------------------------------------------------"

PARVALUE_DESCRIPTION

 PARVALUE_DESCRIPTION (parname [, ind1 [, ind2]])


This function returns the parameter value description string of a numerical parameter specified using the VALUES command statement.
If no description is specified, the returned value is an empty string.

parname: name of the parameter
ind1, ind2: actual indices if the parameter is an array.