VSI Templating Language¶
Overview¶
Why¶
Visual System Integrator ilang compiler takes the visual representation of a system and generated several projects from it, one per execution context or subsystem. A project comprises of:
- Generated code in the supported language for that context
- Surrounding build system to generate executable for that context
In order to keep ilang compiler agnostic of the underlying language and build systems for each context, it works through a intermediary language.
What¶
VSI Templating language is a mixed syntax language in which the primary syntax consists of target language and the secondary syntax defines the transformation rules. In order to denote secondary syntax, enclose it by double curly braces i.e {{name}}
.
Rules¶
The secondary syntax for templating is always surrounded by double curly braces.
Anything not surrounded by curly braces is treated as primary syntax of the target language and is not processed.
For instance, consider template A:
const int i = 0;
const char *a = "{{name}}";
will be transformed to:
const int i = 0;
const char *a = "context name";
The secondary syntax of templating language refers to a node by it’s name. In order to point to a child node of a root node, a period is used i.e {{parent.child}}
- Replacement
In it’s most simplest form, a transformation rule is a replacement operation which replaces a given rule by the compile time value of the system. i.e. {{name}} would be replaced with the context name.
- If
If rule is a section rule and is defined in pair. To do an if check on any node, use the operator ?
and to close the section, use /
. For instance, consider the following template:
{{?decaleint}}
const int i = 0;
{{/declareint}}
will be transformed to:
const int i = 0;
Only if declareint
node is set. In case of it not being set, the generated code will not contain this section.
- If Not
If Not rule is a section rule and is defined in pair. To do an if-not check on any node, use the operator !
and to close the section, use /
. For instance, consider the following template:
{{!decaleint}}
const int i = 0;
{{/declareint}}
will be transformed to:
const int i = 0;
Only if declareint
node is NOT set. In case of it being set, the generated code will not contain this section.
- Contains
Contains rule is a section rule and is defined in pair. To do an Contains check on any node, use the operator ~
and to close the section, use /
. For instance, consider the following template:
{{~ctx.TEMPLATE}}
const int i = 0;
{{/ctx.TEMPLATE}}
will be transformed to:
const int i = 0;
Only if ctx contains a child node of string type AND the child node contains ‘TEMPLATE’ i.e. having the value ‘TEMPLATE | CONST’. If the child node doesn’t contain ‘TEMPLATE’, the generated code will not have the section.
- For
For rule is a section iteration rule and is defined in pair. It will do a for loop for the immediate child nodes and will generate 0 to n amount of section. To do a For loop on a node, use the operator #
and to close the section, use /
. For instance, consider the following template:
{{#ctx.blocks}}
const int {{name}} = 0;
{{/ctx.blocks}}
will be transformed to:
const int block1 = 0;
const int block2 = 0;
const int block3 = 0;
If ctx contains a blocks child node with child nodes of type list or type object with a name node, each with value block1, block2 and block3. If no child nodes exist then For acts like an If and the generated code will not have the section.
- `{{.}}`:
Additionally, to access the current child node, a special syntax of `{{.}}` is used.
- `{{@}}`:
In the case if the child node is of type object, the key for the object can be accessed by using `{{@}}`
- `{{..}}`:
In the case if a For block is inside another For block, the parent node value can be accessed by using the `{{..}}` syntax. Also, each upper level can be accessed by denoting number of prefix dots i.e `{{....}}` will access the value of the parent node three level up. The same rule apply to Replacement rules as well as `{{@}}` key rule i.e `{{.@}}` will access the key of the parent For loop, `{{..name}}` will access a node of type string or int in the object two level up.