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.
(validate-field-value MDEF FIELD-ID FIELD-VALUE #!optional NO-EXN)
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
(engine-versions-compatible? AVAILABLE-VERSION REQUESTED-VERSION)
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.
(mdef-command-ref ID CFG)
Return the command config for the given ID.
(mdef-inode-ref ID CFG)
Return the inode config for the given ID.
Returns the endianness of the configuration's target platform.
(mdef-get-parent-node-id INODE-ID ITREE)
Return the ID of the parent of the given inode in the given inode tree
(mdef-get-parent-node-type INODE-ID MDEF)
Return the inode type of the parent node of INODE-ID.
(mdef-get-node-ancestors-ids INODE-ID ITREE)
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.
(mdef-get-subnode-ids INODE-ID ITREE)
Return the IDs of the direct child nodes of INODE-ID in the given inode tree ITREE.
(mdef-get-subnode-type-ids INODE-ID MDEF TYPE)
return the IDs of the direct child nodes of a given parent inode ID in the given mdef, filtered by type
(mdef-get-block-field-index BLOCK-ID FIELD-ID MDEF)
Returns the row index of the field subnode FIELD-ID in instances of the block node BLOCK-ID.
(mdef-get-inode-source-command NODE-ID MDEF)
Return the source command of a given inode
(mdef-get-node-default NODE-ID MDEF)
Get the default value of a given inode mdef
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:
For each element in the list of output elements specified in the MDEF
configuration, an output node (onode,
onode structure) is generated.
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 size field, which holds the size of the output in bytes, and may be initally #f until the node is resolved - a value field, which is #f for unresolved nodes, and holds the list of output bytes 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
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 current-org md-symbols)
onode is the onode itself,
parent-inode is FIXME a misnomer,
it is the parent inode instance,
mdef is the module's
current-org is the
current asm origin address, and
md-symbols is a list of additional mdal
Onode-fns output a list containing the processed onode, the next origin
address (if it can be deduced, otherwise #f), and the updated list of
(eval-effective-field-val CURRENT-VAL COMMAND-CONFIG #!optional MODIFIER-VAL)
Transform the field node instance value CURRENT-VAL according to the given MDAL COMMAND-CONFIG.
(eval-group-field FIELD-NODE INSTANCE-ID 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.
(backtrace-block-fields BLOCK-INSTANCE START-ROW FIELD-INDEX)
Helper for 'eval-block-field`. Finds the last set field instance of the field node at FIELD-INDEX before ROW in the BLOCK-INSTANCE.
(eval-block-field BLOCK-INSTANCE FIELD-INDEX ROW COMMAND-CONFIG #!optional NO-BACKTRACE)
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-parent-node-type NODE-ID MDEF)
Get the inode type of the parent of node NODE-ID.
(resize-blocks PARENT-INODE-INSTANCE PARENT-INODE-ID SIZE MDEF)
Resize all non-order blocks in the given igroup instance to SIZE, and emit a new igroup instance with a new order.
make-oblock. Resolve the oblock node value.
Returns a list containing the oblock in car and updated origin in cadr.
(do-compiler-pass OTREE PARENT-INODE MDEF ORIGIN MD-SYMBOLS)
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-otree OTREE PARENT-INODE MDEF ORIGIN MD-SYMBOLS)
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.
(make-compiler OUTPUT-EXPR PROTO-MDEF MDEF-DIR PATH-PREFIX)
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.
(read-mdef MDEF ID MDEF-DIR PATH-PREFIX)
Evaluate the given
mdef s-expression, and return a mdef record.
(file->mdef PARENT-DIR MDEF-NAME #!optional (PATH-PREFIX ""))
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.