Input Specification¶
ZOTI-Gen structures are specified using:
a serialization format (e.g. JSON or YAML) representing the structure of the code blocks, their hierarchy and bindings;
an extended Jinja2 template format contained as strings by the
code
entries of the serialization format.a simpler templated string format to define glue macros in some of the binding entries.
Format Schema¶
ZOTI-Gen input files are describing code blocks using a serialization format. Similarly to other ZOTI tools, ZOTI-Gen stores modules in a ZOTI-YAML container, hence input files contain the arguments passed to its constructor, among which a preamble object and a document object.
Preamble¶
Apart from the mandatory module entry containing the qualified name of the current module, ZOTI-Gen preambles need to contain the following entry:
top
(string)the name of the “top” block from which all other blocks are recursively referenced.
Document¶
A ZOTI-Gen document consists in a list of block
entries. Each entry
would fill in an equivalent class container hence we use the class API
documnentation to document the entry schemas.
block
¶
A block describes a unit of code that might be related to other
blocks through bindings and might contain a
template. Internally it is represented using a
zoti_gen.core.Block
class. Blocks are described using
the following entries;
- name:
(mandatory, string) the unique ID of the block
- type:
(Reference) points to an externally-defined library template which would fill in the corresponding entries below, as documented in Template Libraries page.
- requirement:
(dict) block prerequisites
- label:
(list) label entries, each with a unique name
- param:
(dict) generic parameters passed as-is to the template renderer, accessed with the param key.
- instance:
(list) other blocks instantiated from this one.
- code:
(Template) containing this block’s Code Template. Rendered witn the context:
name=comp.name, # component's name
label=comp.label, # resolved labels
param=comp.param, # parameters
placeholder={ # only one placeholder
"code": comp.code
},
- prototype:
(Template) defines this block’s type signature, as provided from a type system. Rendered with the following context:
label=comp.label, # resolved labels
param=comp.param, # parameters
placeholder=rinst, # recursivly-expanded block instances
requirement
¶
Illustrates prerequisites for the parent element. Internally it is
represented using a zoti_gen.core.Requirement
class. It may
contain the following entries:
label
¶
A label is the low-level code equivalent of a ‘port’. Its function
is to provide a name which can be used in bindings and glue
generation. Internally it is represented using a
zoti_gen.core.Label
class.
- name:
(string) unique ID in the scope of the parent block
- glue:
(dict) entries with glue code tailored for various circumstances, provided by the type system and accessible from within the code template using the label.<port_id>.glue key.
- usage:
(Template) defines how this label is to be expanded in the code. Provided by the type system. Rendered with the following context:
p=key, # ID of the current label
label=labels, # complete namespace of resolved labels
param=params, # complete namespace of parameters
instance
¶
Refers to another block and (at minimum) triggers its evaluation by
the the Rendering engine. It can define an
inclusion relation between the parent and the referenced blocks,
in which case the referenced one would occupy the space pointed
out by a placeholder markup in the parent’s
template. Furthermore, the relation between the two blocks can be
enforced by a set of bindings that connects the labels and
parameters of the two blocks. Internally, aln instance is
represented using a zoti_gen.core.Instance
class.
To define a block instance within the parent block the following entries might be used:
- block:
(Reference) points to an existing (i.e. loaded) block.
- placeholder:
(string) the name of the placeholder, as it appears in the parent’s Code Template.
- directive:
(list of strings) directive flags passed to the Rendering engine.
- bind:
(list) bindings between the labels and parameters of the parent block and those of the referenced block.
- usage:
(Template) defines how this block is being instantiated in case it is not expanded inline (e.g., as function call). The template string is defined by the type system. It is rendered with the following contexts, depending on which directive is passed:
expand
is in directives
name=comp.name, # component's name
label=comp.label, # resolved labels
param=comp.param, # parameters
placeholder={ # only one placeholder
"code": comp.code
},
expand
is not in directives
name=comp.name, # component's name
param=comp.param, # parameters
label=b_labels, # bounded (parent) labels
bind
¶
A binding between one of the labels or parameters of the parent
block and a label or parameter of the referenced block.
Internally it is represented using a zoti_gen.core.Bind
class. It needs to contain only one of the following entries:
- label_to_label:
(dict)
- parent:
(str) ID of parent
- child:
(str) ID of child
- usage:
(Template) rendered with context:
p=parent, # ID of parent
label=labels, # entire namespace of resolved labels
param=params, # entire namespace of parameters
- usage_to_label:
(dict)
- child:
(str) ID of child
- usage:
(Template) rendered with context:
label=labels, # entire namespace of resolved labels
param=params, # entire namespace of parameters
- param_to_param:
(dict)
- parent:
(str) Parent parameter
- child:
(str) Child parameter
- value_to_param:
(dict)
- value:
(str) Value as simple string
- child:
(str) Child parameter
Reference¶
A reference is an entry pointing to an object by its qualified name and/or path. Since ZOTI-Gen documents are flat (i.e., they consist in a flat list of block descriptions), and the only objects referenced in ZOTI-Gen are blocks, the only access mechanism implemented is referencing by (block) name. Hence, every reference entry will have the following mandatory fields:
- module:
(string) the full (dot-separated) name of module containing the referenced block, even if that means the current module.
- name:
(string) the name of the referenced block.
For less verbose reference syntax one could check the !ref
keyword in the ZOTI-YAML language extension and
pre-processor.
Code Template¶
Code templates are strings with Jinja2 markup commands evaluated in a custom context built from the resolved block specification. Depending on its role in the input specification (see documentation above), each template is evaluated and rendered using a custom context built from resolved information from the interal representation, most usually having the following context fields:
- label:
contains a dictionary of all resolved
label
entries (see Input Specification), both own and passed via bindings, where the keys are the original (specified) names. Each entry contains possibly updated information (i.e.,name
,usage
andglue
) reflecting the block’s bindings.- param:
usually contains a merged dictionary with this block’s
param
entries and the ones passed via bindings.- placeholder:
will contain rendered code blocks for various declared instances (e.g., as inline code or function call) in the current block’s scope.
Apart from the Jinja2 builtin functions, ZOTI-Gen adds the following functions that can be called from within code templates.
- static JinjaExtensions.find(json: Dict, path: str) Any [source]¶
Returns the element with (the dot-separated) path in a json dictionary, where path is specified as a string. E.g.
{# considering the context {'a': None, 'b':{'foo':{'bar': 'baz'}}} #} { b | find("foo.bar") } {# is the same as #} { b.foo.bar }
both rendering
baz
.
- static JinjaExtensions.setdefaults(json: Any, defaults: Dict) Dict [source]¶
For every direct child of the given json element it (possibly recursively) sets the defaults values if undefined. E.g.:
{% set json = {'a': None, 'b':{'foo':'bar'}} %} {% set defaults = {'foo':'biff', 'baz':'buzz'} %} {% set example = setdefaults(json, defaults) %}
results in
example
containing the dictionary{'a': {'foo':'biff', 'baz':'buzz'}, 'b':{'foo':'bar', 'baz':'buzz'}}
- static JinjaExtensions.eval(context: Dict, string: str) str [source]¶
Renders a Jinja2 string within a context. Useful if both string and context are passed to the current template context.
- static JinjaExtensions.error(msg: str, *args) None [source]¶
Raise an exception from within the template logic.
- static JinjaExtensions.getter(context, elem, *args) str [source]¶
ZOTI-Gen specific formatter that retrieves the type getter macro created by ZOTI-FTN and stored in each label’s
glue
entry and creates an access expresion based on it:{{ getter("data.data.LEN") }} {# is equivalent to #} {{ label.data.glue.data.LEN._get }}({{ label.data.name }})
- static JinjaExtensions.setter(context, elem, *args) str [source]¶
ZOTI-Gen specific formatter that retrieves the type setter macro created by ZOTI-FTN and stored in each label’s
glue
entry and creates an access expression based on it:{{ setter("data.data.c", "i", "x" }} {# is equivalent to #} {{ label.data.glue.data.c._set }}({{ label.data.name }}, i, x)