diff --git a/README.md b/README.md
index aa260aa71..87320793d 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Inform 7
-v10.1.0-alpha.1+6S94 'Krypton' (9 August 2021)
+v10.1.0-alpha.1+6S95 'Krypton' (10 August 2021)
## About Inform 7
diff --git a/build.txt b/build.txt
index 006055114..8c766b3ab 100644
--- a/build.txt
+++ b/build.txt
@@ -1,3 +1,3 @@
Prerelease: alpha.1
-Build Date: 9 August 2021
-Build Number: 6S94
+Build Date: 10 August 2021
+Build Number: 6S95
diff --git a/colony.txt b/colony.txt
index c829a9c99..56cab4491 100644
--- a/colony.txt
+++ b/colony.txt
@@ -28,7 +28,8 @@ module: "multimedia" at "inform7/multimedia-module" in "docs/multimedia-module"
breadcrumbs: "Home: //overview//" > "Inter Modules: //compiler//"
module: "bytecode" at "inter/bytecode-module" in "docs/bytecode-module"
module: "building" at "inter/building-module" in "docs/building-module"
-module: "codegen" at "inter/codegen-module" in "docs/codegen-module"
+module: "pipeline" at "inter/pipeline-module" in "docs/pipeline-module"
+module: "final" at "inter/final-module" in "docs/final-module"
module: "index" at "inter/index-module" in "docs/index-module"
breadcrumbs: "Home: //overview//" > "Services: //compiler//"
module: "arch" at "services/arch-module" in "docs/arch-module"
diff --git a/docs-src/compiler.inweb b/docs-src/compiler.inweb
index 8fffd6ae2..75dfb8cc7 100755
--- a/docs-src/compiler.inweb
+++ b/docs-src/compiler.inweb
@@ -1,15 +1,55 @@
Title: The Inform 7 compiler
Author: Graham Nelson
-@ The task of the Inform 7 compiler is to take natural-language source text
-and "transpile" it down to lower-level, more orthodox code which another
-compiler can take the rest of the way. Usually, but not necessarily, that
-other compiler is the typeless but otherwise C-like Inform 6 (1996-2003).
+@ The task of Inform to take natural-language source text, merged from the
+author's main source and some "extensions"; to compile that to an intermediate
+format called Inter; merge once again with pre-compiled libraries of Inter
+called "kits"; and then translate the result to a program which a
+more orthodox compiler can take the rest of the way. Because Inform 7 generates
+code for another compiler, rather than directly making an executable itself,
+it is properly speaking a "transpiler".
+
+For two decades that second compiler was always the roughly C-like Inform 6, a
+sturdy 1990s tool for generating interactive fiction "story files" which, after
+processing with the //inblorb// tool, can then be played in a web browser or
+with an "interpreter". In 2021, limited support was added for transpiling a
+general, non-IF-specific form of the language called Basic Inform to ANSI C.
+This can be compiled into more general executable programs using Clang, gcc,
+or other standard C compilers.
+= (hyperlinked text as BoxArt)
+ main source text extension source texts
+ \ /
+ \ / INFORM7 Stage 1 or INBUILD
+ \ /
+ \|/ \|/
+ syntax tree
+ |
+ kit sources |
+ (in Inform 6 code) | INFORM7 Stages 2-4
+ INTER | |
+ \|/ \|/
+ kits as Inter binaries inter tree
+ \ / INFORM7 Stages 5-6 or INTER
+ \|/ \|/
+ single linked inter tree
+ / | \
+ / | \ INFORM7 Stages 5-6 or INTER
+ \|/ \|/ \|/
+ Inform 6 code C code Index mini-website
+ | |
+ INFORM6 | | CLANG/GCC
+ \|/ \|/
+ story file executable
+ |
+ INBLORB |
+ \|/
+ playable website
+=
Inform offers three compiler tools: //inbuild//, //inform7// and //inter//,
though really they are three points of access to the same code base. //inbuild//
contains Stage 1 as a stand-alone tool, //inter// contains Stages 5 and 6 as
-a stand-alone tool, and //inform7// is the entire compiler (Stages 1 to 6) in one.
+a stand-alone tool, but //inform7// is the entire compiler (Stages 1 to 6) in one.
See //inbuild: Manual//, //inform7: Manual//, //inter: Manual// and
//inbuild: Reference Card//, //inform7: Reference Card//, //inter: Reference Card//.
@@ -38,9 +78,10 @@ divided up into "modules", many shared between two or even all three tools.
. . +------------------+ +------------------------+
. . . . | //bytecode//-module | }
. . . . | //building//-module | } Stage 5
- . . . . | //codegen//-module | }
+ . . . . | //pipeline//-module | }
+ . . . . | //final//-module | }
. . . . | ------------------------- |
- . . . . | //index//-module | } Stage 6
+ . . . . | //index//-module | } Stage 6
. . . . +---------------------------+
. . . . . .
+-----------------------------------------------------------------------+
@@ -71,12 +112,12 @@ doing little except to co-ordinate the other modules.
(*) Stage 3. //assertions//, //values// and //knowledge// assemble a world model
and a set of rules and phrases to operate it. //if// and //multimedia// provide
"plugins" with additional features, adapting the language for interactive fiction.
-(*) Stage 4. //imperative// and //runtime// turn the constructs from Stage 2
+(*) Stage 4. //imperative// and //runtime// turn the constructs from Stage 3
into an intermediate bytecode format called Inter.
-(*) Stage 5. //bytecode//, //building// and //codegen// optimise the Inter
-code and translate it to our final output.
+(*) Stage 5. //bytecode//, //building//, //pipeline// and //final// manage,
+create, link/optimise and translate this Inter code, respectively.
(*) Stage 6. //index// generates the human-readable Index pages, which are like
-a small website about the project.
+a small website about the project, from Inter code.
@ All three tools each use a "services" library, made up of a variety of modules
providing services useful for natural language-based programs. At one time this
diff --git a/docs-src/navc.html b/docs-src/navc.html
index a8b3b6547..a28f587c4 100644
--- a/docs-src/navc.html
+++ b/docs-src/navc.html
@@ -24,7 +24,8 @@
[[Menu "Inter Modules"]]
[[Item "bytecode"]]
[[Item "building"]]
-[[Item "codegen"]]
+[[Item "pipeline"]]
+[[Item "final"]]
[[Menu "Services"]]
[[Item "arch"]]
[[Item "calculus"]]
diff --git a/docs/arch-module/1-am.html b/docs/arch-module/1-am.html
index c2b8514d2..a90a1c795 100644
--- a/docs/arch-module/1-am.html
+++ b/docs/arch-module/1-am.html
@@ -43,7 +43,8 @@
§1. The task of the Inform 7 compiler is to take natural-language source text
-and "transpile" it down to lower-level, more orthodox code which another
-compiler can take the rest of the way. Usually, but not necessarily, that
-other compiler is the typeless but otherwise C-like Inform 6 (1996-2003).
+
§1. The task of Inform to take natural-language source text, merged from the
+author's main source and some "extensions"; to compile that to an intermediate
+format called Inter; merge once again with pre-compiled libraries of Inter
+called "kits"; and then translate the result to a program which a
+more orthodox compiler can take the rest of the way. Because Inform 7 generates
+code for another compiler, rather than directly making an executable itself,
+it is properly speaking a "transpiler".
+
For two decades that second compiler was always the roughly C-like Inform 6, a
+sturdy 1990s tool for generating interactive fiction "story files" which, after
+processing with the inblorb tool, can then be played in a web browser or
+with an "interpreter". In 2021, limited support was added for transpiling a
+general, non-IF-specific form of the language called Basic Inform to ANSI C.
+This can be compiled into more general executable programs using Clang, gcc,
+or other standard C compilers.
+
@@ -103,9 +145,10 @@ divided up into "modules", many shared between two or even all three tools.
. . +------------------+ +------------------------+ . . . . | bytecode-module | } . . . . | building-module | } Stage5
- . . . . | codegen-module | }
+ . . . . | pipeline-module | }
+ . . . . | final-module | } . . . . | ------------------------- |
- . . . . | index-module | } Stage6
+ . . . . | index-module | } Stage6 . . . . +---------------------------+ . . . . . .+-----------------------------------------------------------------------+
@@ -138,12 +181,12 @@ doing little except to co-ordinate the other modules.
● Stage 3. assertions, values and knowledge assemble a world model
and a set of rules and phrases to operate it. if and multimedia provide
"plugins" with additional features, adapting the language for interactive fiction.
-
● Stage 4. imperative and runtime turn the constructs from Stage 2
+
● Stage 4. imperative and runtime turn the constructs from Stage 3
into an intermediate bytecode format called Inter.
-
● Stage 5. bytecode, building and codegen optimise the Inter
-code and translate it to our final output.
+
● Stage 5. bytecode, building, pipeline and final manage,
+create, link/optimise and translate this Inter code, respectively.
● Stage 6. index generates the human-readable Index pages, which are like
-a small website about the project.
+a small website about the project, from Inter code.
§2. All three tools each use a "services" library, made up of a variety of modules
providing services useful for natural language-based programs. At one time this
diff --git a/docs/core-module/1-cm.html b/docs/core-module/1-cm.html
index 0258ca1d3..47162b6e2 100644
--- a/docs/core-module/1-cm.html
+++ b/docs/core-module/1-cm.html
@@ -51,7 +51,8 @@ function togglePopup(material_id) {
§1. This section simoly sets up the module in ways expected by foundation, and
+contains no code of interest. The following constant exists only in tools
+which use this module:
+
typedefstructcode_generation {
-structpipeline_step *from_step;
+structpipeline_step *from_step;structinter_tree *from;structcode_generation_target *target;structinter_package *just_this_package;
@@ -139,7 +140,7 @@ only when assembling other material, and not for the final output.
CLASS_DEFINITION} code_generation;
-code_generation *CodeGen::new_generation(pipeline_step *step, inter_tree *I,
+code_generation *CodeGen::new_generation(pipeline_step *step, inter_tree *I,inter_package *just, code_generation_target *target) {code_generation *gen = CREATE(code_generation);gen->from_step = step;
@@ -153,7 +154,7 @@ only when assembling other material, and not for the final output.
returngen;}
-
The structure code_generation is accessed in 4/fc, 4/cal, 4/iap, 4/vrb, 4/ft, 5/fti, 5/fbi, 5/fi, 5/fi6, 5/fnc and here.
+
The structure code_generation is accessed in 2/fc, 2/cal, 2/iap, 2/vrb, 2/ft, 3/fti, 3/fbi, 3/fi, 4/fi6, 5/fnc and here.
§3. At present, at least, a "segment" is nothing more than a wrapper for a text.
But we abstract it in case it's ever useful for it to be more.
@@ -164,7 +165,7 @@ But we abstract it in case it's ever useful for it to be more.
CLASS_DEFINITION} generated_segment;
-generated_segment *CodeGen::new_segment(void) {
+generated_segment *CodeGen::new_segment(void) {generated_segment *seg = CREATE(generated_segment);seg->generated_code = Str::new();returnseg;
@@ -176,7 +177,7 @@ output, because:
-voidCodeGen::write(OUTPUT_STREAM, code_generation *gen) {
+voidCodeGen::write(OUTPUT_STREAM, code_generation *gen) {for (inti=0; i<MAX_CG_SEGMENTS; i++) {if ((gen->segments[i]) && (i != TEMP_CG_SEGMENT))WRITE("%S", gen->segments[i]->generated_code);
@@ -188,7 +189,7 @@ always be done in a way which is then undone, restoring the previous state:
-generated_segment *CodeGen::select(code_generation *gen, inti) {
+generated_segment *CodeGen::select(code_generation *gen, inti) {generated_segment *saved = gen->current_segment;if ((i < 0) || (i >= MAX_CG_SEGMENTS)) internal_error("out of range");if (gen->temporarily_diverted) internal_error("poorly timed selection");
@@ -196,7 +197,7 @@ always be done in a way which is then undone, restoring the previous state:
returnsaved;}
-voidCodeGen::deselect(code_generation *gen, generated_segment *saved) {
+voidCodeGen::deselect(code_generation *gen, generated_segment *saved) {if (gen->temporarily_diverted) internal_error("poorly timed deselection");gen->current_segment = saved;}
@@ -206,9 +207,9 @@ we also have to direct it to a given text.
-voidCodeGen::select_temporary(code_generation *gen, text_stream *T) {
+voidCodeGen::select_temporary(code_generation *gen, text_stream *T) {if (gen->segments[TEMP_CG_SEGMENT] == NULL) {
-gen->segments[TEMP_CG_SEGMENT] = CodeGen::new_segment();
+gen->segments[TEMP_CG_SEGMENT] = CodeGen::new_segment();gen->segments[TEMP_CG_SEGMENT]->generated_code = NULL; }if (gen->temporarily_diverted)
@@ -217,7 +218,7 @@ we also have to direct it to a given text.
gen->segments[TEMP_CG_SEGMENT]->generated_code = T;}
-voidCodeGen::deselect_temporary(code_generation *gen) {
+voidCodeGen::deselect_temporary(code_generation *gen) {gen->temporarily_diverted = FALSE;}
@@ -225,7 +226,7 @@ we also have to direct it to a given text.
-text_stream *CodeGen::current(code_generation *gen) {
+text_stream *CodeGen::current(code_generation *gen) {if (gen->temporarily_diverted)returngen->segments[TEMP_CG_SEGMENT]->generated_code;if (gen->current_segment == NULL) returnNULL;
@@ -236,69 +237,69 @@ we also have to direct it to a given text.
The structure kov_value_stick is accessed in 3/su, 3/ext, 3/lt, 3/rsp, 3/rls, 3/act, 3/act2, 3/ins, 3/knd, 3/prp, 3/rlt, 3/tbl, 3/chr, 3/scn, 3/mlt, 3/uo, 3/vrb, 3/tst and here.
+
The structure kov_value_stick is private to this section.
§2. Representing instances in I6. Partly for historical reasons, partly to squeeze performance out of the
virtual machines used in traditional parser IF, the I6 run-time
implementation of instances and their properties is complicated.
@@ -237,7 +238,7 @@ limited number can be stored this way. Here we choose which.
§4.3. We have in theory 48 Attribute slots to use up, that being the number
available in versions 5 and higher of the Z-machine, but the I6 template
layer consumes so many that only a few slots remain for the user's own
@@ -332,7 +333,7 @@ to be frequently used.
make_attribute = FALSE; }
-
§4.4. At present the I7 compiler makes a decision matching this one for its
own internal needs. We want to make sure its decision matches ours, so we
check that here. (It tells us by marking the property name with the
@@ -351,7 +352,7 @@ check that here. (It tells us by marking the property name with the
internal_error("attribute allocation dispute"); }
-
§4.5. A curiosity of I6 is that attributes must be declared before use, whereas
properties need not be. We generate suitable Attribute statements here.
Note that if the property has been translated onto an existing I6 name, then
@@ -363,18 +364,18 @@ in the I6 template, or some extension), and we therefore do nothing.
§4.6. The weak point in our scheme for making some either/or properties into
Attributes is that run-time code is going to need a fast way to determine
which, since they have to be accessed differently. We rely on the facts that
@@ -401,51 +402,51 @@ compiles an I6 constant for this value.
§5.5. But there's a snag. The above assumes that property values will have the
same ordering at run-time as their definition order here, but that isn't
necessarily true. The run-time ordering depends on how early in the I6
@@ -573,20 +574,20 @@ bother to force them.)
§5.8. Lookup mechanism for properties of value instances. As noted above, if K is a kind which can have properties but is not a subkind
of object, then a property for instances of K is stored in an array called
a "stick". At run-time, given the property number and K, we will need to find
@@ -670,42 +671,42 @@ take lightly in the Z-machine. But speed and flexibility are worth more.
§5.8.1. It's convenient to be able to distinguish, at run-time, which objects are
the VPH objects used only for kind-property indexing; we can test if O is
such an object with the I6 condition (O ofclass VPH_Class).
@@ -730,17 +731,17 @@ words, the number of instances of this kind.
§5.8.3.1. In the event that no value instances have properties, there'll be no
instances of the VPH_Class, and no I6 object will be compiled with a
value_range property; that means I6 code referring to this will fail with an
@@ -807,7 +808,7 @@ just to force the property into being.
if (vph == 0) WRITE("VPH_Class UnusedVPH with value_range 0;\n");
§5.8.5.1. These little arrays are sticks of property values, and they are laid out
as if they were column arrays in a Table data structure. This means they must
be table arrays (which wastes one word of memory) and must have blanked-out
@@ -873,9 +874,9 @@ because I6 doesn't allow function calls in a constant context.
§5.11. The following lets the run-time environment know what properties are
called, and which kinds of object are allowed to have them. This might look
a little odd: why does the run-time code need to know any of that?
@@ -975,23 +976,23 @@ though this won't happen for any property created by I7 source text.
§5.11.2. A complete list here would be wasteful both of space and run-time
checking time, but we only need a list \(O_1, O_2, ..., O_k\) such that for
each \(W\) allowed to have the property, either \(W = O_i\) for some \(i\), or
@@ -1031,30 +1032,30 @@ linearly with the size of the source text, even though \(N\) does.
-intCodeGen::IP::is_kind_of_object(inter_symbol *kind_name) {
+intCodeGen::IP::is_kind_of_object(inter_symbol *kind_name) {if (kind_name == object_kind_symbol) returnFALSE;inter_data_type *idt = Inter::Kind::data_type(kind_name);if (idt == unchecked_idt) returnFALSE;
@@ -1303,7 +1304,7 @@ really make much conceptual sense, and I7 dropped the idea — it has no
-inter_tiCodeGen::IP::kind_of_object_count(inter_symbol *kind_name) {
+inter_tiCodeGen::IP::kind_of_object_count(inter_symbol *kind_name) {if ((kind_name == NULL) || (kind_name == object_kind_symbol)) return0;intN = Inter::Symbols::read_annotation(kind_name, OBJECT_KIND_COUNTER_IANN);if (N >= 0) return (inter_ti) N;
@@ -1311,7 +1312,7 @@ really make much conceptual sense, and I7 dropped the idea — it has no
}
diff --git a/docs/codegen-module/4-vrb.html b/docs/final-module/2-vrb.html
similarity index 90%
rename from docs/codegen-module/4-vrb.html
rename to docs/final-module/2-vrb.html
index fdf345982..4670f0f5c 100644
--- a/docs/codegen-module/4-vrb.html
+++ b/docs/final-module/2-vrb.html
@@ -51,7 +51,8 @@ function togglePopup(material_id) {
§2.2. Here we need some gymnastics. We need to produce a value which the
sometimes shaky I6 expression parser will accept, which turns out to be
quite a constraint. If we were compiling to C, we might try this:
@@ -494,7 +495,7 @@ then the result.
OUTDENT; WRITE(")\n");OUTDENT; WRITE(")\n");
-
@@ -246,7 +247,7 @@ multiple sessions happening at once:
§5. Now for the second operand of the OR_BIP. If there weren't any callings,
we just compile false. (It looks wasteful to have compiled "if (... or false)",
but in that event the use of OP_BIP will be optimised out later: see
-Eliminate Redundant Operations (in codegen).) If there were callings, we default them.
+Eliminate Redundant Operations (in pipeline).) If there were callings, we default them.
diff --git a/docs/imperative-module/2-cl.html b/docs/imperative-module/2-cl.html
index 5b8770961..7af014fcf 100644
--- a/docs/imperative-module/2-cl.html
+++ b/docs/imperative-module/2-cl.html
@@ -51,7 +51,8 @@ function togglePopup(material_id) {
diff --git a/docs/indoc/2-css.html b/docs/indoc/2-css.html
index 976c82b84..c4e3994c4 100644
--- a/docs/indoc/2-css.html
+++ b/docs/indoc/2-css.html
@@ -89,10 +89,10 @@ emphasis; and are also used to mark headwords for indexing, as in
typedefstructspan_notation {
-intsp_purpose; one of the *_SPP constants
-wchar_tsp_left[MAX_PATTERN_LENGTH]; wide C string: the start pattern
+intsp_purpose; one of the *_SPP constants
+wchar_tsp_left[MAX_PATTERN_LENGTH]; wide C string: the start patternintsp_left_len;
-wchar_tsp_right[MAX_PATTERN_LENGTH]; wide C string: and end pattern
+wchar_tsp_right[MAX_PATTERN_LENGTH]; wide C string: and end patternintsp_right_len;structtext_stream *sp_style;CLASS_DEFINITION
diff --git a/docs/indoc/2-haj.html b/docs/indoc/2-haj.html
index 03be92bee..e806a015c 100644
--- a/docs/indoc/2-haj.html
+++ b/docs/indoc/2-haj.html
@@ -405,7 +405,7 @@ used on the Contents page:
HTMLUtilities::extra_icon(OUT, I"extrab");WRITE("';\n");WRITE(" }\n");
-WRITE(" }\n");
+WRITE(" }\n"); }}
diff --git a/docs/indoc/2-rnd.html b/docs/indoc/2-rnd.html
index 453dc6184..809072e41 100644
--- a/docs/indoc/2-rnd.html
+++ b/docs/indoc/2-rnd.html
@@ -719,12 +719,12 @@ down to the last line which is included in the paste.
elseif (c == 't') WRITE_TO(modified, "[=0x0009=]");elseWRITE_TO(modified, "\\%c", c);break;
-case'\"': WRITE_TO(modified, "[=0x0022=]"); break;
-case'\x0a': WRITE_TO(modified, "[=0x000A=]"); break;
-case'\x0d': WRITE_TO(modified, "[=0x000A=]"); break;
-case'\t': WRITE_TO(modified, "[=0x0009=]"); break;
-case'<': WRITE_TO(modified, "[=0x003C=]"); break;
-case'>': WRITE_TO(modified, "[=0x003E=]"); break;
+case'\"': WRITE_TO(modified, "[=0x0022=]"); break;
+case'\x0a': WRITE_TO(modified, "[=0x000A=]"); break;
+case'\x0d': WRITE_TO(modified, "[=0x000A=]"); break;
+case'\t': WRITE_TO(modified, "[=0x0009=]"); break;
+case'<': WRITE_TO(modified, "[=0x003C=]"); break;
+case'>': WRITE_TO(modified, "[=0x003E=]"); break;case'_':if (Str::includes_wide_string_at(text, L"__backslash___", i+1)) {WRITE_TO(modified, "[=0x005C=]"); i+=14;
@@ -741,7 +741,7 @@ down to the last line which is included in the paste.
WRITE_TO(modified, "[=0x0026=]"); }break;
-default:PUT_TO(modified, c); break;
+default:PUT_TO(modified, c); break; } }Str::copy(text, modified);
diff --git a/docs/indoc/2-rr.html b/docs/indoc/2-rr.html
index 784b55405..8a7699a01 100644
--- a/docs/indoc/2-rr.html
+++ b/docs/indoc/2-rr.html
@@ -561,9 +561,9 @@ in tag elements into &quo
for (inti=0, L=Str::len(text); i<L; i++) {intc = Str::get_at(text, i);switch (c) {
-case'\"': WRITE_TO(modified, """); break;
-case'<': WRITE_TO(modified, "<"); break;
-case'>': WRITE_TO(modified, ">"); break;
+case'\"': WRITE_TO(modified, """); break;
+case'<': WRITE_TO(modified, "<"); break;
+case'>': WRITE_TO(modified, ">"); break;case'&':if (Str::get_at(text, i+1) == '#') { PUT_TO(modified, c); break; }intj = i+1;
@@ -571,7 +571,7 @@ in tag elements into &quo
if ((j > i+1) && (Str::get_at(text, j) == ';')) { PUT_TO(modified, c); break; }WRITE_TO(modified, "&");break;
-default:PUT_TO(modified, c); break;
+default:PUT_TO(modified, c); break; } }Str::copy(text, modified);
diff --git a/docs/inflections-module/1-im.html b/docs/inflections-module/1-im.html
index ea731cfa6..995c22ae6 100644
--- a/docs/inflections-module/1-im.html
+++ b/docs/inflections-module/1-im.html
@@ -43,7 +43,8 @@
§3. Memory consumption. The following gives some idea of which classes of object have the most
instances, and also of how Inform's memory tends to be used in practice.
@@ -126,14 +128,14 @@ represent less than 1/1000th of the total.
§4. Preform grammar. The full annotated description of the Preform grammar (see About Preform (in words)),
with optimisation details and hit/miss statistics added, is also long: it's
@@ -391,14 +394,14 @@ sample, showing the nonterminal used to parse literals in Inform 7 source text: