The Interface to MDAL Engine Definitions.
(make-range min: 2 max: 2)
(make-range min: 2 max: 2)
#t if the given INODE-CONFIG specifies that only one instance
of this inode may exist.
Verify that a parsed FIELD-VALUE is a legal input. Raises an exception
illegal-value on failure, otherwise returns the field value.
Note that for modifier, reference, and label commands, only a type check
is performed. If NO-EXN is provided and
#f is returned on
validation failure, rather than raising an exception.
MDEF: MASTER CONFIGURATION
Check whether the MDEF engine-version AVAILABLE-VERSION is compatible with REQUESTED-VERSION. Versions are considered compatible if the major versions match, and the minor version argument of AVAILABLE-VERSION is greater than or equal to the minor version argument of REQUESTED-VERSION.
Convert the engine-version struct VERSION to a real number.
Return the configuration ID of the mmod M.
Return the command config for the given ID.
Return the inode config for the given ID.
Predicate to check if the group inode ID is has the
Predicate to determine if the order of the group inode ID may be edited. Orders are editable except when the group is unordered, has a fixed block length, and contains exactly 2 fields (the length field, and a single reference field).
Returns the endianness of the configuration's target platform.
Return the ID of the parent of the given inode in the given inode tree
Return the inode type of the parent node of INODE-ID.
Return the list of ancestor IDs of the given inode in the given inode tree The returned list is sorted from the closest ancestor to the most distant.
Return the IDs of the direct child nodes of INODE-ID in the given inode tree ITREE.
return the IDs of the direct child nodes of a given parent inode ID in the given mdef, filtered by type
Returns the row index of the field subnode FIELD-ID in instances of the block node BLOCK-ID.
Return the source command of a given inode
Get the default value of a given inode mdef
Returns a list that matches the length of a row in the order block of
the group GROUP-ID, where values are either
#f depending on
whether the matching order field is a base field or not. Fields are
considered base fields if they are either a Length field, or a block
#t if the field node FIELD-ID is a base field of an order node.
MMOD: OUTPUT NODES
MDEF PARSER + COMPILER GENERATOR
The Compiler Generator
Libmdal does not come with a default compiler for transforming MDAL
modules into the desired binary or asm output. Instead, a dedicated
compiler procedure is generated for each MDAL configuration. This
procedure takes as input an
mmod structure and the current origin
(assembly start address) and produces a list of resolved output nodes
(onodes), which can be further processed into binary or assembly output.
The compiler procedure is stored in the mdef-compiler field of the
relevant mdef structure.
The compiler function itself is generated as follows:
An AST for the Schemta assembler is generated, based on the specification
given in the MDEF configuration. Furthermore, for each element in the
specified list of output elements, an output node (onode,
Onodes are initially in an "unresolved" state, unless their output can be
evaluated at the time the compiler is generated.
An onode consist of - a type specifier (see below for available types) - a value field, which is #f for unresolved nodes, and may hold a result once the onode is resolved - an onode-fn field, which for resolved nodes is set to #f, and otherwise holds a procedure that, when applied to the onode, will attempt to resolve it.
The main compiler repeatedly iterates over the list of onodes, applying
the onode-fn procedures, until all onodes are resolved, or a preset pass
limit is exceeded, in which case the compiler fails with an exception of
compiler-failed. When an onode is resolved, it typically generates
new assembly level symbol bindings. Once all ondes are resolved, the
generated symbols are passed to the Schemta assembler, which will then
attempt to resolve the initial AST.
The following onode types are permitted:
asm: Takes some asm code as input and returns the assembled output.
The compiler generator will attempt to resolve asm onodes
immediately and cache the results.
comment: An assembly level comment. Ignored in binary output.
field: A single value, usually generated from a constant or an igroup
ifield. Field specifications hold a "compose" expression, which
is transformed into a procedure that generates the output.
symbol: Produces an assembly level symbol, set to the current origin.
Onodes may have an ID (which must be unique). Identified onodes may be referenced by other onodes. This is almost always required for groups and blocks.
Onode-fn procedures have the signature
(proc onode parent-inode mdef md-symbols)
onode is the onode itself,
parent-inode is FIXME a misnomer,
it is the parent inode instance,
mdef is the module's
mdef structure, and
md-symbols is a list of
additional mdal symbols generated.
Onode-fns output a list containing the processed onode, and the updated list
Resolve a numeric reference to an intermediate AST representation. TO is an oblock ID, and VAL is the integer result of evaluating a compose (sub)expression.
Resolve a symbolic reference to an intermediate AST representation. TO is an oblock ID, and VAL is the integer result of evaluating a compose (sub)expression.
Calculate the result of applying the modifier command value MODIFIER-VAL to the integer value RAW-VAL.
Transform the field node instance value CURRENT-VAL according to the given MDAL COMMAND-CONFIG.
Evaluate a group field node instance, resolving
ukey values as
needed. This always returns the effective field value, ie. an empty node
instance returns the default value of the underlying command.
Helper for 'eval-block-field`. Finds the last set field instance of the field node at FIELD-INDEX before ROW in the BLOCK-INSTANCE.
Evaluate the field in position FIELD-INDEX in ROW of the given
BLOCK-INSTANCE. Evaluation will backtrace if the field node
COMMAND-CONFIG has the
use-last-set flag. Backtracing can be disabled
by passing NO-BACKTRACE as
#t. This is useful for determining whether
a specific field instance is set.
Get the inode type of the parent of node NODE-ID.
Resize all non-order blocks in the given igroup instance to SIZE, and emit a new igroup instance with a new order. If SIZE is #f, then all blocks will be merged. If the igroup is ordered and the order provides a loop point, then blocks will be split accordingly. The loop point is moved to the nearest multiple of SIZE if necessary.
make-oblock. Resolve the oblock node value.
Returns a list containing the oblock in car and updated origin in cadr.
Do a single compiler pass run over the given otree. Returns a list containing the updated otree in the 1st slot, the updated origin in the 2nd slot, and the updated list of symbols in the 3rd slot.
Compile a local onode tree. Returns a list containing the resolved tree in the first slot, the updated origin in the 2nd slot, and the updated list of md-symbols in the 3rd slot. Will throw an exception of type 'compiler-failed if the otree cannot be resolved after 3 passes.
Generate a compiler from the given output config expression.
proto-mdef must be a mdef struct with all fields resolved
except the mdef-comiler itself.
The compiler is a procedure taking 2 arguments: an mmod structure,
and an origin (address at which to compile). It returns a list of output
nodes, which can be further processed by
The compiler will throw an exception of type 'compiler-failed
if it cannot resolve all output nodes after 3 passes.
Evaluate the engine-version keyword argument of an mdal-mdef expression.
Evaluate the given
mdef s-expression, and return a mdef record.
Generate an mdef struct from an .mdef file.
parent-dir is the file path to the parent directory of the directory
containing the .mdef file.