mirror of
https://github.com/ganelson/inform.git
synced 2024-07-09 02:24:21 +03:00
138 lines
5 KiB
OpenEdge ABL
138 lines
5 KiB
OpenEdge ABL
Inform Organisation.
|
|
|
|
The standard hierarchy of inter code generated by Inform.
|
|
|
|
@h Status.
|
|
The Inter specification allows great flexibility in how packages are used
|
|
to structure a program, and requires very little.
|
|
|
|
The Inform compiler, however, uses this flexibility in a systematic way,
|
|
as follows.
|
|
|
|
@h Global area and main.
|
|
Inform opens with a version number, then declares package types (as needed
|
|
below), issues pragmas for I6 compiler memory settings, then declares
|
|
primitives for the standard Inform set: it always declares the same set
|
|
of primitives on every run.
|
|
|
|
As required, the rest of the program is in the |main| package, which has
|
|
type |_plain|.
|
|
|
|
@h Compilation modules.
|
|
Inform divides up its material into compilation modules, as follows. Each
|
|
one becomes an inter package of type |_module|, and is a subpackage of |main|.
|
|
|
|
(a) The "generic module" contains built-in definitions of kinds, and the like.
|
|
No source text directly leads to this, and indeed, it can entirely be defined
|
|
without having seen any source text: it will be the same on every run. The
|
|
package is |/main/generic|.
|
|
|
|
(b) Material from the Inform 6 template is assimilated into inter code in
|
|
the "template module", which is |/main/template|.
|
|
|
|
(c) Each extension is a compilation module, including of course the Standard
|
|
Rules, which is |/main/standard_rules|. Subsequent extensions have
|
|
longer names, such as |/main/locksmith_by_emily_short|.
|
|
|
|
(d) Material in the main source text is a single compilation module, and
|
|
goes into |/main/source_text|.
|
|
|
|
(e) The "synoptic module" contains material which was synthesised from all
|
|
of the source material in the other modules, and which can't meaningfully
|
|
be localised. For example, a function at run-time which returns the default
|
|
value for a kind given its weak kind ID has to be synoptic, because its
|
|
definition will include references to every kind defined in the program.
|
|
Such a function doesn't belong to any one block of source text. The
|
|
package is |/main/synoptic|.
|
|
|
|
@ Except for the template module, which is necessarily more free-form,
|
|
each module package then contains some or all of a standard set of
|
|
subpackages (and nothing else). Suppose the module name is |M|. The
|
|
range of possible subpackages is:
|
|
= (text)
|
|
/main/M/actions
|
|
/main/M/activities
|
|
/main/M/adjectives
|
|
/main/M/chronology
|
|
/main/M/conjugations
|
|
/main/M/equations
|
|
/main/M/extensions
|
|
/main/M/functions
|
|
/main/M/grammar
|
|
/main/M/instances
|
|
/main/M/kinds
|
|
/main/M/listing
|
|
/main/M/phrases
|
|
/main/M/properties
|
|
/main/M/relations
|
|
/main/M/rulebooks
|
|
/main/M/rules
|
|
/main/M/tables
|
|
/main/M/variables
|
|
=
|
|
@h Function packages.
|
|
All functions compiled by Inform 7 are expressed in inter code by packages
|
|
of type |_function|. The only externally visible symbol is |call|, which is
|
|
what is invoked. For example:
|
|
= (text as Inter)
|
|
symbol X --> /main/kinds/kind_6/gpr_fn/call
|
|
...
|
|
inv X
|
|
=
|
|
invokes the function defined by the package:
|
|
= (text as Inter)
|
|
/main/kinds/kind_6/gpr_fn
|
|
=
|
|
(Inform conventionally uses names ending in |_fn| for function packages.)
|
|
Functions assimilated from template files are almost exactly similar,
|
|
except that rather than |call| the call symbol has the name of the original
|
|
template function. For example, |RELATION_TY_Distinguish| is assimilated as:
|
|
= (text as Inter)
|
|
/template/functions/RELATION_TY_Distinguish_fn/RELATION_TY_Distinguish
|
|
=
|
|
It is possible for function packages to avoid defining any actual code, by
|
|
defining |call| as an alias for a routine which we'll simply have to assume
|
|
will be present at eventual compile time. For example:
|
|
= (text as Inter)
|
|
package print_fn _function
|
|
symbol public misc call `REAL_NUMBER_TY_Say`
|
|
=
|
|
More often, however, and always for functions derived from Inform 7 source
|
|
text, the package contains a code subpackage, and then defines |call| to
|
|
be that code package:
|
|
= (text as Inter)
|
|
package gpr_fn _function
|
|
package code_block_1 _code
|
|
...
|
|
constant call K_phrase_nothing____nothing = code_block_1
|
|
=
|
|
In fact, though, the package can be much more elaborate. If the code needs
|
|
to manipulate or refer to data not expressible in single words, such as
|
|
lists or texts, then it will probably need to create and subsequently destroy
|
|
a stack frame. The mechanism will then be:
|
|
= (text as Inter)
|
|
package gpr_fn _function
|
|
package code_block_1 _code
|
|
...
|
|
constant kernel K_phrase_nothing____nothing = code_block_1
|
|
package code_block_2 _code
|
|
...
|
|
constant call K_phrase_nothing____nothing = code_block_2
|
|
=
|
|
The "shell" routine of code, the one receiving the |call|, creates a stack
|
|
fram and then calls the "kernel" routine, which does the actual work; when
|
|
that returns to the "shell", the stack frame is disposed of again.
|
|
|
|
Function packages will also contain definitions of any static data they
|
|
need: for example, if an Inform 7 phrase contains a reference to the
|
|
constant |{ 1 , 2 , 3 }| then a function package for it will define a
|
|
constant with a name such as |block_constant_1|. In short, as far as
|
|
possible, function packages are self-contained.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|