Data Structures

The data structures supported by the simulation language directly map to the D-Bus type system, and their syntax closely follows the syntax used in the GVariant text format, which is itself based on Python syntax. However, there are several variations in the simulation language's syntax, which exist for no good reason at all. They may be resolved in future versions of the simulation language.

Two data structures which the simulation language does not support are: maybe types and Unix FDs. Maybe types are not serialisable over D-Bus and just exist within GVariant, so are not relevant to the simulation language. Unix FDs are serialisable over D-Bus, but not widely used and the simulator currently doesn't have the infrastructure to handle simulating or fuzzing file streams.

Fuzzing of data structures (to produce fuzzy data structures) is achieved by suffixing the data structure with ?. For example, "fuzz me"? evaluates to a fuzzed version of the string “fuzz me”. It is possible to suffix data structures with the fuzzing symbol at any point inside a data structure AST, which will result in just the immediately preceding data structure (and potentially its children) being fuzzed.

Fuzzing a Data Structure AST

{
	"contact-id" : <"1@example.com"?>,
	"alias" : <""?>,
	"presence" : <(3u?, "available", "Status message!"?)>,
}?

Basic Types

Booleans: true, false

Boolean literals are (case sensitively) denoted by true and false. Due to the strict type system, there is no correspondence between boolean values and integers as there is in C.

Strings: delimited by "

String literals can only be delimited by double quotation marks in the simulation language, whereas in GVariant text format, single quotation marks are also allowed. In the simulation language, backslashes (\) are used to escape extra quotation marks, new line characters and for escape sequences: \n, \t, \r, \b and \f, which have the same semantics as in C.

"This is a \"sample string\".\nIt contains a line break."
Object paths: strings with a preceding @o type annotation

No special syntax is required for object paths, but they must have a type annotation and must be a valid object path. There is no support for implicit conversion of normal strings to object paths (or vice-versa). Note that only at-syntax type annotations are supported: the GVariant text format objectpath annotation is not supported.

@o "/org/freedesktop/Telepathy/AccountManager"
Type signatures: strings with a preceding @g type annotation

As with object paths, no special syntax is required for type strings, but they must have a type annotation and must be a valid type signature.

@g "a{sv}"
Numbers: numeric constants followed by the D-Bus type character for their type

The simulation language deviates from the GVariant text format in its handling of numbers. In the simulation language, numbers are written literally, and then the type character for their type is appended. The GVariant text format approach of using type annotations is not supported, but probably should be. Some examples follow.

15u /* 32-bit unsigned integer of value 15 */
-12.5d /* IEEE 754 double of value -12.5 */
255y /* byte of value 255 */
-666666x /* 64-bit signed integer of value -666666 */

Container Types

Tuples/Structs: delimited by ( and ), with elements separated by ,

Tuples must contain zero or more elements, separated by commas. A trailing comma is allowed after the final element if it makes code look nicer. The unit tuple, (), has its own concrete type so does not require a type annotation.

("hello", "world")
Arrays: delimited by [ and ], with elements separated by ,

Arrays must have a concrete type, so empty arrays must be preceded by a type annotation giving their type and the type of their elements. As with tuples, a trailing comma is allowed after the final element of an array if it makes code look nicer.

[1u, 2u, 3u]
@au []
Dictionaries: delimited by { and }, with entries partitioned by : and separated by ,

As with arrays, dictionaries must have a concrete type, so empty dictionaries must be preceded by a type annotation giving their type and the type of their entries. As with tuples and arrays, a trailing comma is allowed after the final entry of a dictionary if it makes code look nicer.

{ "key" : "value", "another key" : "another value" }
{ "key" : <"variant value">, "another key" : <false> }
@a{sv} {}
Variants: delimited by < and >

Since the type of the value of a variant is handled at run time, variants do not need type annotations. Note that variants cannot be fuzzed, but their values can.

<"hello">
<(1u, "some tuple")>

Variables

Variables exist outside of the GVariant type system, added by the simulation language. The simulator uses two scopes for variables: object scope and local scope.

Object-scoped variables are defined in a data block of an object, and are accessible to all transitions in the object (but to nothing outside the object). They are accessed by preceding the variable name with object->. For example: object->VariableName.

Local-scoped variables are defined upon execution of a method- or property-triggered transition. In the case of a method-triggered transition, they're declared as the method's input parameters by the D-Bus interface declaring the method being called. In the case of a property-triggered transition, only the variable value is defined. Local-scoped variables are accessed just using their variable name. For example: value or Parameter1.

Fuzzing of variables is not supported. The variable values must instead be fuzzed before being assigned to the variables (for example, in the data block which originally defines the variable).

Expressions

Container data structures may have expressions as some of their leaf nodes to build the data structure. This is perfectly valid as long as the expressions are well typed. Note that expressions are pure, so evaluation of a data structure can never result in side effects.