From 94353d93bf4de3cf60d85bfa7cbcfacc36b44416 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Sun, 13 Jun 2021 18:04:57 +0100 Subject: [PATCH] Migrated Pl element --- README.md | 2 +- build.txt | 4 +- docs/codegen-module/1-cm.html | 8 + docs/codegen-module/2-ass.html | 6 +- docs/codegen-module/3-su.html | 8 +- docs/codegen-module/6-ae.html | 200 ++++++ docs/codegen-module/6-be.html | 2 +- docs/codegen-module/6-ce.html | 2 +- docs/codegen-module/6-ce2.html | 2 +- docs/codegen-module/6-ee.html | 2 +- docs/codegen-module/6-ee2.html | 2 +- docs/codegen-module/6-fe.html | 2 +- docs/codegen-module/6-ge.html | 2 +- docs/codegen-module/6-ie.html | 2 +- docs/codegen-module/6-ifs.html | 97 +-- docs/codegen-module/6-ii.html | 2 +- docs/codegen-module/6-ir.html | 41 +- docs/codegen-module/6-le.html | 2 +- docs/codegen-module/6-lxc.html | 2 +- docs/codegen-module/6-pe.html | 601 ++++++++++++++++++ docs/codegen-module/6-re.html | 2 +- docs/codegen-module/6-rfse.html | 2 +- docs/codegen-module/6-se.html | 2 +- docs/codegen-module/6-te.html | 2 +- docs/codegen-module/6-ve.html | 2 +- docs/codegen-module/6-ve2.html | 2 +- docs/codegen-module/index.html | 10 + docs/if-module/3-scn.html | 10 +- docs/index-module/2-act.html | 4 +- docs/index-module/2-adj.html | 2 +- docs/index-module/2-ae.html | 226 ------- docs/index-module/2-ie.html | 2 +- docs/index-module/2-inf.html | 2 +- docs/index-module/2-ins.html | 4 +- docs/index-module/2-ki.html | 4 +- docs/index-module/2-me.html | 2 +- docs/index-module/2-pi.html | 2 +- docs/index-module/2-prp.html | 2 +- docs/index-module/2-rls.html | 20 +- docs/index-module/3-act.html | 2 +- docs/index-module/3-bck.html | 2 +- docs/index-module/3-ci.html | 2 +- docs/index-module/3-pe.html | 471 -------------- docs/index-module/3-rgn.html | 2 +- docs/index-module/3-spt.html | 2 +- docs/index-module/3-tm.html | 2 +- docs/index-module/3-tp.html | 2 +- docs/index-module/index.html | 10 - docs/runtime-module/2-ec.html | 22 +- docs/runtime-module/2-hrr.html | 69 +- docs/runtime-module/2-kd.html | 2 +- docs/runtime-module/5-ins.html | 7 +- docs/runtime-module/5-kc.html | 178 ++++-- docs/runtime-module/5-ki.html | 2 +- docs/runtime-module/5-lp.html | 2 +- docs/runtime-module/5-rlb.html | 4 +- docs/runtime-module/5-si.html | 39 +- docs/runtime-module/6-pp.html | 2 +- docs/runtime-module/6-pv.html | 2 +- inform7/Figures/memory-diagnostics.txt | 62 +- inform7/Figures/timings-diagnostics.txt | 27 +- inform7/Tests/Test Internals/Index-Plot.txt | 23 + .../_Results_Ideal/Index-Plot.txt | 41 ++ inform7/if-module/Chapter 3/Scenes.w | 8 +- inform7/index-module/Chapter 3/Plot Element.w | 313 --------- inform7/index-module/Contents.w | 1 - inform7/runtime-module/Chapter 2/Hierarchy.w | 30 + inform7/runtime-module/Chapter 5/Instances.w | 3 - inform7/runtime-module/Chapter 5/Rulebooks.w | 2 +- .../Chapter 5/Scene Instances.w | 39 +- .../codegen-module/Chapter 1/Codegen Module.w | 8 + .../Chapter 6/Index File Services.w | 5 +- inter/codegen-module/Chapter 6/Index Rules.w | 13 +- inter/codegen-module/Chapter 6/Plot Element.w | 445 +++++++++++++ inter/codegen-module/Contents.w | 1 + 75 files changed, 1823 insertions(+), 1313 deletions(-) create mode 100644 docs/codegen-module/6-ae.html create mode 100644 docs/codegen-module/6-pe.html delete mode 100644 docs/index-module/2-ae.html delete mode 100644 docs/index-module/3-pe.html create mode 100644 inform7/Tests/Test Internals/Index-Plot.txt create mode 100644 inform7/Tests/Test Internals/_Results_Ideal/Index-Plot.txt delete mode 100644 inform7/index-module/Chapter 3/Plot Element.w create mode 100644 inter/codegen-module/Chapter 6/Plot Element.w diff --git a/README.md b/README.md index 4bc5a5040..53dcb985e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -v10.1.0-alpha.1+6S39 'Krypton' (12 June 2021) +v10.1.0-alpha.1+6S40 'Krypton' (13 June 2021) ## About Inform 7 diff --git a/build.txt b/build.txt index 87041c3a7..e606d1428 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: alpha.1 -Build Date: 12 June 2021 -Build Number: 6S39 +Build Date: 13 June 2021 +Build Number: 6S40 diff --git a/docs/codegen-module/1-cm.html b/docs/codegen-module/1-cm.html index e59c98986..741e150bd 100644 --- a/docs/codegen-module/1-cm.html +++ b/docs/codegen-module/1-cm.html @@ -90,6 +90,9 @@ which use this module: enum index_page_CLASS enum index_element_CLASS enum index_tlexicon_entry_CLASS +enum simplified_scene_CLASS +enum simplified_end_CLASS +enum simplified_connector_CLASS
 DECLARE_CLASS(I6T_intervention)
@@ -109,6 +112,9 @@ which use this module:
 DECLARE_CLASS(index_element)
 DECLARE_CLASS(index_page)
 DECLARE_CLASS(index_tlexicon_entry)
+DECLARE_CLASS(simplified_scene)
+DECLARE_CLASS(simplified_end)
+DECLARE_CLASS(simplified_connector)
 

§3. Like all modules, this one must define a start and end function:

@@ -126,12 +132,14 @@ which use this module:

§3.1.

enum CODE_GENERATION_MREASON
+enum SCENE_SORTING_MREASON
 

§3.2. Register this module's memory allocation reasons3.2 =

     Memory::reason_name(CODE_GENERATION_MREASON, "code generation workspace for objects");
+    Memory::reason_name(SCENE_SORTING_MREASON, "scene index sorting");
 

§3.3. Register this module's stream writers3.3 = diff --git a/docs/codegen-module/2-ass.html b/docs/codegen-module/2-ass.html index 361285a77..174d3b35c 100644 --- a/docs/codegen-module/2-ass.html +++ b/docs/codegen-module/2-ass.html @@ -813,10 +813,10 @@ function togglePopup(material_id) { } if (isn->isn_type == EXPRESSION_ISNT) { inter_schema_token *t = isn->expression_tokens; - if (t->next) { - if (t->next->next) return NULL; + if (t->next) { + if (t->next->next) return NULL; inter_symbol *i1 = CodeGen::Assimilate::compute_constant_eval(I, pack, IBM, t); - inter_symbol *i2 = CodeGen::Assimilate::compute_constant_eval(I, pack, IBM, t->next); + inter_symbol *i2 = CodeGen::Assimilate::compute_constant_eval(I, pack, IBM, t->next); if ((i1 == NULL) || (i2 == NULL)) return NULL; return CodeGen::Assimilate::compute_constant_binary_operation(CONSTANT_SUM_LIST, I, pack, IBM, i1, i2); } diff --git a/docs/codegen-module/3-su.html b/docs/codegen-module/3-su.html index e28762754..2cb671685 100644 --- a/docs/codegen-module/3-su.html +++ b/docs/codegen-module/3-su.html @@ -119,6 +119,7 @@ function togglePopup(material_id) { inter_tree_location_list *variable_nodes; inter_tree_location_list *equation_nodes; inter_tree_location_list *heading_nodes; + inter_tree_location_list *multiplication_rule_nodes; CLASS_DEFINITION } tree_inventory; @@ -155,6 +156,7 @@ function togglePopup(material_id) { inv->variable_nodes = Synoptic::add_inventory_need(inv, I"_variable"); inv->equation_nodes = Synoptic::add_inventory_need(inv, I"_equation"); inv->heading_nodes = Synoptic::add_inventory_need(inv, I"_heading"); + inv->multiplication_rule_nodes = Synoptic::add_inventory_need(inv, I"_multiplication_rule"); inv->extension_nodes = TreeLists::new(); inv->scene_nodes = TreeLists::new(); @@ -221,7 +223,7 @@ function togglePopup(material_id) { tree_inventory *cached_inventory = NULL; inter_tree *cache_is_for = NULL; -tree_inventory *Synoptic::inv(inter_tree *I) { +tree_inventory *Synoptic::inv(inter_tree *I) { if (cache_is_for == I) return cached_inventory; cache_is_for = I; cached_inventory = Synoptic::new_inventory(I); @@ -252,11 +254,11 @@ function togglePopup(material_id) { return TRUE; } -

+

§2.

-int Synoptic::module_order(const void *ent1, const void *ent2) {
+int Synoptic::module_order(const void *ent1, const void *ent2) {
     itl_entry *E1 = (itl_entry *) ent1;
     itl_entry *E2 = (itl_entry *) ent2;
     if (E1 == E2) return 0;
diff --git a/docs/codegen-module/6-ae.html b/docs/codegen-module/6-ae.html
new file mode 100644
index 000000000..65a62be81
--- /dev/null
+++ b/docs/codegen-module/6-ae.html
@@ -0,0 +1,200 @@
+
+
+	
+		Arithmetic Element
+
+		
+		
+		
+
+
+
+
+
+
+
+
+
+
+		
+	
+	
+		
+		
+ + +

To index dimensional rules.

+ +

§1. These were really indexed for us in metadata generated by the main compiler; +so we do little more than tabulate that data here. +

+ +
+void ArithmeticElement::render(OUTPUT_STREAM) {
+    inter_tree *I = Index::get_tree();
+    tree_inventory *inv = Synoptic::inv(I);
+    TreeLists::sort(inv->kind_nodes, Synoptic::module_order);
+    TreeLists::sort(inv->multiplication_rule_nodes, Synoptic::module_order);
+    HTML_TAG("hr");
+    Index the rubric about quasinumerical kinds1.1;
+    Index the table of quasinumerical kinds1.2;
+    Index the table of multiplication rules1.3;
+}
+
+

§1.1. Index the rubric about quasinumerical kinds1.1 = +

+ +
+    HTML_OPEN("p");
+    HTML_TAG_WITH("a", "calculator");
+    HTML::begin_plain_html_table(OUT);
+    HTML::first_html_column(OUT, 0);
+    HTML_TAG_WITH("img", "border=0 src=inform:/doc_images/calc2.png");
+    WRITE(" ");
+    WRITE("Kinds of value marked with the calculator symbol are numerical - "
+        "these are values we can add, multiply and so on. The range of these "
+        "numbers depends on the Format setting for the project (Glulx format "
+        "supports much higher numbers than Z-code).");
+    HTML::end_html_row(OUT);
+    HTML::end_html_table(OUT);
+    HTML_CLOSE("p");
+
+
  • This code is used in §1.
+

§1.2. Index the table of quasinumerical kinds1.2 = +

+ +
+    HTML_OPEN("p");
+    HTML::begin_plain_html_table(OUT);
+
+    HTML::first_html_column(OUT, 0);
+    WRITE("<b>kind of value</b>");
+    HTML::next_html_column(OUT, 0);
+    WRITE("<b>minimum</b>");
+    HTML::next_html_column(OUT, 0);
+    WRITE("<b>maximum</b>");
+    HTML::next_html_column(OUT, 0);
+    WRITE("<b>dimensions</b>");
+    HTML::end_html_row(OUT);
+
+    for (int i=0; i<TreeLists::len(inv->kind_nodes); i++) {
+        inter_package *pack = Inter::Package::defined_by_frame(inv->kind_nodes->list[i].node);
+        if (Str::len(Metadata::read_optional_textual(pack, I"^min_value")) > 0) {
+            HTML::first_html_column(OUT, 0);
+            WRITE("%S", Metadata::read_optional_textual(pack, I"^printed_name"));
+            HTML::next_html_column(OUT, 0);
+            WRITE("%S", Metadata::read_optional_textual(pack, I"^min_value"));
+            HTML::next_html_column(OUT, 0);
+            WRITE("%S", Metadata::read_optional_textual(pack, I"^max_value"));
+            HTML::next_html_column(OUT, 0);
+            text_stream *dims = Metadata::read_optional_textual(pack, I"^dimensions");
+            if (Str::len(dims) > 0) WRITE("%S", dims); else WRITE("<i>dimensionless</i>");
+            HTML::end_html_row(OUT);
+        }
+    }
+    HTML::end_html_table(OUT);
+    HTML_CLOSE("p");
+
+
  • This code is used in §1.
+

§1.3. This is simply a table of all the multiplications declared in the source +text, sorted into kind order of left and then right operand. +

+ +

Index the table of multiplication rules1.3 = +

+ +
+    if (TreeLists::len(inv->multiplication_rule_nodes) > 0) {
+        HTML_OPEN("p");
+        WRITE("This is how multiplication changes kinds:");
+        HTML_CLOSE("p");
+        HTML_OPEN("p");
+        HTML::begin_plain_html_table(OUT);
+        for (int i=0; i<TreeLists::len(inv->multiplication_rule_nodes); i++) {
+            inter_package *pack = Inter::Package::defined_by_frame(inv->multiplication_rule_nodes->list[i].node);
+            HTML::first_html_column(OUT, 0);
+            int at = (int) Metadata::read_optional_numeric(pack, I"^at");
+            if (at > 0) Index::link(OUT, at);
+            HTML::next_html_column(OUT, 0);
+            WRITE("%S", Metadata::read_optional_textual(pack, I"^left_operand"));
+            HTML::begin_colour(OUT, I"808080");
+            WRITE(" x ");
+            HTML::end_colour(OUT);
+            WRITE("%S", Metadata::read_optional_textual(pack, I"^right_operand"));
+            HTML::begin_colour(OUT, I"808080");
+            WRITE(" = ");
+            HTML::end_colour(OUT);
+            WRITE("%S", Metadata::read_optional_textual(pack, I"^result"));
+            WRITE("&nbsp;&nbsp;&nbsp;&nbsp;");
+            HTML::next_html_column(OUT, 0);
+            WRITE("%S", Metadata::read_optional_textual(pack, I"^left_operand_benchmark"));
+            HTML::begin_colour(OUT, I"808080");
+            WRITE(" x ");
+            HTML::end_colour(OUT);
+            WRITE("%S", Metadata::read_optional_textual(pack, I"^right_operand_benchmark"));
+            HTML::begin_colour(OUT, I"808080");
+            WRITE(" = ");
+            HTML::end_colour(OUT);
+            WRITE("%S", Metadata::read_optional_textual(pack, I"^result_benchmark"));
+            HTML::end_html_row(OUT);
+        }
+        HTML::end_html_table(OUT);
+        HTML_CLOSE("p");
+    }
+
+
  • This code is used in §1.
+ + +
+ + + diff --git a/docs/codegen-module/6-be.html b/docs/codegen-module/6-be.html index f32ae2cc6..4da869872 100644 --- a/docs/codegen-module/6-be.html +++ b/docs/codegen-module/6-be.html @@ -115,7 +115,7 @@ function togglePopup(material_id) { }
diff --git a/docs/codegen-module/6-ce.html b/docs/codegen-module/6-ce.html index e495e4cf7..e85e25c7f 100644 --- a/docs/codegen-module/6-ce.html +++ b/docs/codegen-module/6-ce.html @@ -256,7 +256,7 @@ giving only minimal entries about them. diff --git a/docs/codegen-module/6-ce2.html b/docs/codegen-module/6-ce2.html index ed4d57b71..0ba838c14 100644 --- a/docs/codegen-module/6-ce2.html +++ b/docs/codegen-module/6-ce2.html @@ -150,7 +150,7 @@ simplified form of the iFiction record, without the XML overhead. } diff --git a/docs/codegen-module/6-ee.html b/docs/codegen-module/6-ee.html index a23ab9a71..aaa2a9f1c 100644 --- a/docs/codegen-module/6-ee.html +++ b/docs/codegen-module/6-ee.html @@ -150,7 +150,7 @@ function togglePopup(material_id) { diff --git a/docs/codegen-module/6-ee2.html b/docs/codegen-module/6-ee2.html index cac86e765..d39a99a22 100644 --- a/docs/codegen-module/6-ee2.html +++ b/docs/codegen-module/6-ee2.html @@ -135,7 +135,7 @@ function togglePopup(material_id) { diff --git a/docs/codegen-module/6-fe.html b/docs/codegen-module/6-fe.html index 723249dc5..6b7591ecd 100644 --- a/docs/codegen-module/6-fe.html +++ b/docs/codegen-module/6-fe.html @@ -353,7 +353,7 @@ to match this width, preserving the aspect ratio. diff --git a/docs/codegen-module/6-ge.html b/docs/codegen-module/6-ge.html index 25d9d7411..9ab56cd90 100644 --- a/docs/codegen-module/6-ge.html +++ b/docs/codegen-module/6-ge.html @@ -82,7 +82,7 @@ function togglePopup(material_id) { } diff --git a/docs/codegen-module/6-ie.html b/docs/codegen-module/6-ie.html index c83748803..8ea8d10fd 100644 --- a/docs/codegen-module/6-ie.html +++ b/docs/codegen-module/6-ie.html @@ -288,7 +288,7 @@ pragma is set: diff --git a/docs/codegen-module/6-ifs.html b/docs/codegen-module/6-ifs.html index 448e79d69..a2b9d2434 100644 --- a/docs/codegen-module/6-ifs.html +++ b/docs/codegen-module/6-ifs.html @@ -83,7 +83,7 @@ function togglePopup(material_id) { indexing_tree = I; } -inter_tree *Index::get_tree(void) { +inter_tree *Index::get_tree(void) { return indexing_tree; } @@ -817,76 +817,25 @@ to show, hide and colour things: } void Index::index_actual_element(OUTPUT_STREAM, text_stream *elt) { - if (Str::eq_wide_string(elt, L"Bh")) { - BehaviourElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"Cd")) { - CardElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"Rl")) { - RelationsElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"Ev")) { - EventsElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"Fi")) { - FiguresElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"Tb")) { - TablesElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"Vl")) { - ValuesElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"RS")) { - RulesForScenesElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"Xt")) { - ExtrasElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"St")) { - StandardsElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"C")) { - ContentsElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"In")) { - InnardsElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"Vb")) { - VerbsElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"Gz")) { - GazetteerElement::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"Lx")) { - LexiconElement::render(OUT); - return; - } + if (Str::eq_wide_string(elt, L"Ar")) { ArithmeticElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Bh")) { BehaviourElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"C")) { ContentsElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Cd")) { CardElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Ev")) { EventsElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Fi")) { FiguresElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Gz")) { GazetteerElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"In")) { InnardsElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Lx")) { LexiconElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Rl")) { RelationsElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"RS")) { RulesForScenesElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"St")) { StandardsElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Tb")) { TablesElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Vb")) { VerbsElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Vl")) { ValuesElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Xt")) { ExtrasElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Pl")) { PlotElement::render(OUT); return; } #ifdef CORE_MODULE - if (Str::eq_wide_string(elt, L"Pl")) { - IXScenes::render(OUT); - return; - } - if (Str::eq_wide_string(elt, L"Ar")) { - IXArithmetic::render(OUT); - return; - } if (Str::eq_wide_string(elt, L"Mp")) { IXPhysicalWorld::render(OUT); return; @@ -1016,7 +965,7 @@ the source text in the application.

-void Index::link(OUTPUT_STREAM, int wn) {
+void Index::link(OUTPUT_STREAM, int wn) {
     Index::link_to_location(OUT, Lexer::word_location(wn), TRUE);
 }
 
@@ -1071,18 +1020,18 @@ code.
     HTML_CLOSE("a");
 }
 
-void Index::anchor(OUTPUT_STREAM, text_stream *p) {
+void Index::anchor(OUTPUT_STREAM, text_stream *p) {
     HTML_OPEN_WITH("a", "name=%S", p); HTML_CLOSE("a");
 }
 
-void Index::below_link_numbered(OUTPUT_STREAM, int n) {
+void Index::below_link_numbered(OUTPUT_STREAM, int n) {
     WRITE("&nbsp;");
     HTML_OPEN_WITH("a", "href=#A%d", n);
     HTML_TAG_WITH("img", "border=0 src=inform:/doc_images/Below.png");
     HTML_CLOSE("a");
 }
 
-void Index::anchor_numbered(OUTPUT_STREAM, int n) {
+void Index::anchor_numbered(OUTPUT_STREAM, int n) {
     HTML_OPEN_WITH("a", "name=A%d", n); HTML_CLOSE("a");
 }
 
@@ -1188,7 +1137,7 @@ quotes. } diff --git a/docs/codegen-module/6-ii.html b/docs/codegen-module/6-ii.html index df2c312dc..f7ad02b64 100644 --- a/docs/codegen-module/6-ii.html +++ b/docs/codegen-module/6-ii.html @@ -288,7 +288,7 @@ time.) {-index:name} diff --git a/docs/codegen-module/6-ir.html b/docs/codegen-module/6-ir.html index 019adc304..6537b6019 100644 --- a/docs/codegen-module/6-ir.html +++ b/docs/codegen-module/6-ir.html @@ -95,7 +95,7 @@ function togglePopup(material_id) { typedef struct ix_rule_context { struct inter_package *action_context; - struct inter_symbol *scene_context; + struct simplified_scene *scene_context; } ix_rule_context; ix_rule_context IndexRules::action_context(inter_package *an) { @@ -104,21 +104,21 @@ function togglePopup(material_id) { rc.scene_context = NULL; return rc; } -ix_rule_context IndexRules::scene_context(inter_symbol *s) { +ix_rule_context IndexRules::scene_context(simplified_scene *s) { ix_rule_context rc; rc.action_context = NULL; rc.scene_context = s; return rc; } -ix_rule_context IndexRules::no_rule_context(void) { +ix_rule_context IndexRules::no_rule_context(void) { ix_rule_context rc; rc.action_context = NULL; rc.scene_context = NULL; return rc; } -int IndexRules::phrase_fits_rule_context(inter_package *entry, ix_rule_context rc) { +int IndexRules::phrase_fits_rule_context(inter_package *entry, ix_rule_context rc) { if (entry == NULL) return FALSE; if (rc.action_context) { @@ -128,13 +128,14 @@ function togglePopup(material_id) { } if (rc.scene_context) { inter_symbol *scene_symbol = Metadata::read_optional_symbol(entry, I"^during"); - if (scene_symbol != rc.scene_context) return FALSE; + if (scene_symbol == NULL) return FALSE; + if (Inter::Packages::container(scene_symbol->definition) != rc.scene_context->pack) return FALSE; } return TRUE; } int RS_unique_xtra_no = 77777; -void IndexRules::index_rules_box(OUTPUT_STREAM, tree_inventory *inv, +void IndexRules::index_rules_box(OUTPUT_STREAM, tree_inventory *inv, text_stream *titling_text, text_stream *doc_link, inter_package *rb_pack, char *text, int indent, int hide_behind_plus) { if (rb_pack == NULL) return; @@ -216,7 +217,7 @@ function togglePopup(material_id) {

§2.

-int IndexRules::index_rulebook(OUTPUT_STREAM, inter_tree *I, inter_package *rb_pack, text_stream *billing, ix_rule_context rc, int *resp_count) {
+int IndexRules::index_rulebook(OUTPUT_STREAM, inter_tree *I, inter_package *rb_pack, text_stream *billing, ix_rule_context rc, int *resp_count) {
     int suppress_outcome = FALSE, t = 0;
     if (rb_pack == NULL) return 0;
     if (Str::len(billing) > 0) {
@@ -229,7 +230,7 @@ function togglePopup(material_id) {
     return t;
 }
 
-int IndexRules::is_contextually_empty(inter_tree *I, inter_package *rb_pack, ix_rule_context rc) {
+int IndexRules::is_contextually_empty(inter_tree *I, inter_package *rb_pack, ix_rule_context rc) {
     if (rb_pack) {
         inter_symbol *wanted = PackageTypes::get(I, I"_rulebook_entry");
         inter_tree_node *D = Inter::Packages::definition(rb_pack);
@@ -245,7 +246,7 @@ function togglePopup(material_id) {
     return TRUE;
 }
 
-int IndexRules::no_rules(inter_tree *I, inter_package *rb_pack) {
+int IndexRules::no_rules(inter_tree *I, inter_package *rb_pack) {
     int N = 0;
     if (rb_pack) {
         inter_symbol *wanted = PackageTypes::get(I, I"_rulebook_entry");
@@ -306,7 +307,7 @@ function togglePopup(material_id) {
 

-void IndexRules::br_show_linkage_icon(OUTPUT_STREAM, inter_package *prev) {
+void IndexRules::br_show_linkage_icon(OUTPUT_STREAM, inter_package *prev) {
     text_stream *icon_name = NULL;  redundant assignment to appease gcc -O2
     if ((prev == NULL) || (Str::len(Metadata::read_optional_textual(prev, I"^tooltip")) == 0)) {
         HTML::icon_with_tooltip(OUT, I"inform:/doc_images/rulenone.png",
@@ -327,7 +328,7 @@ function togglePopup(material_id) {
 

-int IndexRules::index_rule(OUTPUT_STREAM, inter_tree *I, inter_package *R, inter_package *owner, ix_rule_context rc) {
+int IndexRules::index_rule(OUTPUT_STREAM, inter_tree *I, inter_package *R, inter_package *owner, ix_rule_context rc) {
     int no_responses_indexed = 0;
     int response_box_id = RS_unique_xtra_no++;
     text_stream *name = Metadata::read_optional_textual(R, I"^name");
@@ -352,10 +353,8 @@ function togglePopup(material_id) {
 
 
     WRITE("<i>%S", italicised_text);
-    if (rc.scene_context) {
-        inter_package *scene_pack = Inter::Packages::container(rc.scene_context->definition);
-        WRITE(" during %S", Metadata::read_optional_textual(scene_pack, I"^name"));
-    }
+    if (rc.scene_context)
+        WRITE(" during %S", PlotElement::scene_name(rc.scene_context));
     WRITE("</i>&nbsp;&nbsp;");
 
  • This code is used in §4.
@@ -484,7 +483,7 @@ text to assert a change:

-void IndexRules::index_response(OUTPUT_STREAM, inter_package *rule_pack, inter_package *resp_pack) {
+void IndexRules::index_response(OUTPUT_STREAM, inter_package *rule_pack, inter_package *resp_pack) {
     int marker = (int) Metadata::read_numeric(resp_pack, I"^marker");
     text_stream *text = Metadata::read_textual(resp_pack, I"^index_text");
     WRITE("&nbsp;&nbsp;&nbsp;&nbsp;");
@@ -512,7 +511,7 @@ text to assert a change:
 

§6.

-void IndexRules::index_outcomes(OUTPUT_STREAM, inter_tree *I, inter_package *rb_pack) {
+void IndexRules::index_outcomes(OUTPUT_STREAM, inter_tree *I, inter_package *rb_pack) {
     inter_symbol *wanted = PackageTypes::get(I, I"_rulebook_outcome");
     inter_tree_node *D = Inter::Packages::definition(rb_pack);
     LOOP_THROUGH_INTER_CHILDREN(C, D) {
@@ -550,7 +549,7 @@ text to assert a change:
     }
 }
 
-void IndexRules::rb_index_placements(OUTPUT_STREAM, inter_tree *I, inter_package *rb_pack) {
+void IndexRules::rb_index_placements(OUTPUT_STREAM, inter_tree *I, inter_package *rb_pack) {
     inter_symbol *wanted = PackageTypes::get(I, I"_rulebook_placement");
     inter_tree_node *D = Inter::Packages::definition(rb_pack);
     LOOP_THROUGH_INTER_CHILDREN(C, D) {
@@ -572,7 +571,7 @@ text to assert a change:
 

§7.

-void IndexRules::index_activity(OUTPUT_STREAM, inter_tree *I, inter_package *pack, int indent) {
+void IndexRules::index_activity(OUTPUT_STREAM, inter_tree *I, inter_package *pack, int indent) {
     int empty = (int) Metadata::read_optional_numeric(pack, I"^empty");
 	if (av->indexing_data.activity_indexed) return;
     av->indexing_data.activity_indexed = TRUE;
@@ -588,7 +587,7 @@ text to assert a change:
 

§8.

-void IndexRules::activity_rules_box(OUTPUT_STREAM, inter_tree *I, text_stream *doc_link,
+void IndexRules::activity_rules_box(OUTPUT_STREAM, inter_tree *I, text_stream *doc_link,
     inter_package *av_pack, text_stream *text, int indent, int hide_behind_plus) {
 
     int xtra_no = RS_unique_xtra_no++;
@@ -698,7 +697,7 @@ text to assert a change:
 
  • This code is used in §8 (twice).
diff --git a/docs/codegen-module/6-le.html b/docs/codegen-module/6-le.html index d3994adb0..ab67b7b31 100644 --- a/docs/codegen-module/6-le.html +++ b/docs/codegen-module/6-le.html @@ -94,7 +94,7 @@ function togglePopup(material_id) { }
diff --git a/docs/codegen-module/6-lxc.html b/docs/codegen-module/6-lxc.html index 7e084c997..6b7df79b5 100644 --- a/docs/codegen-module/6-lxc.html +++ b/docs/codegen-module/6-lxc.html @@ -425,7 +425,7 @@ than (say) quicksort is not great.
  • This code is used in §8.
diff --git a/docs/codegen-module/6-pe.html b/docs/codegen-module/6-pe.html new file mode 100644 index 000000000..a80f0446b --- /dev/null +++ b/docs/codegen-module/6-pe.html @@ -0,0 +1,601 @@ + + + + Plot Element + + + + + + + + + + + + + + + + + + +
+ + +

To write the Plot element (Pl) in the index.

+ +
+ +

§1. The mapping of time is on the one hand simpler than the mapping of space +since there is only one dimension, but on the other hand more complex since +scenes can be multiply present at the same instant of time (whereas rooms +cannot be multiply present at the same point in space). We resolve this +with a notation which takes a little bit of on-screen explanation, but +seems natural enough to learn in practice. +

+ +
define MAX_SCENE_ENDS 32  this must exceed 31
+
+
+typedef struct simplified_scene {
+    struct inter_package *pack;
+    int no_ends;
+    struct simplified_end *ends[MAX_SCENE_ENDS];
+    int indexed_already;
+    CLASS_DEFINITION
+} simplified_scene;
+
+typedef struct simplified_end {
+    struct inter_package *end_pack;
+    struct simplified_connector *anchor_connectors;  linked list
+    CLASS_DEFINITION
+} simplified_end;
+
+typedef struct simplified_connector {
+    struct inter_package *con_pack;
+    struct simplified_scene *connect_to;
+    struct simplified_connector *next;  next in list of connectors for a scene end
+    CLASS_DEFINITION
+} simplified_connector;
+
+simplified_scene *PlotElement::simplified(inter_tree *I, inter_package *sc_pack) {
+    simplified_scene *ssc = CREATE(simplified_scene);
+    ssc->pack = sc_pack;
+    ssc->no_ends = 0;
+    ssc->indexed_already = FALSE;
+    inter_symbol *wanted = PackageTypes::get(I, I"_scene_end");
+    inter_symbol *wanted_within = PackageTypes::get(I, I"_scene_connector");
+    inter_tree_node *D = Inter::Packages::definition(sc_pack);
+    LOOP_THROUGH_INTER_CHILDREN(C, D) {
+        if (C->W.data[ID_IFLD] == PACKAGE_IST) {
+            inter_package *entry = Inter::Package::defined_by_frame(C);
+            if (Inter::Packages::type(entry) == wanted) {
+                simplified_end *se = CREATE(simplified_end);
+                se->end_pack = entry;
+                se->anchor_connectors = NULL;
+                LOOP_THROUGH_INTER_CHILDREN(B, C) {
+                    if (B->W.data[ID_IFLD] == PACKAGE_IST) {
+                        inter_package *inner_entry = Inter::Package::defined_by_frame(B);
+                        if (Inter::Packages::type(inner_entry) == wanted_within) {
+                            simplified_connector *scon = CREATE(simplified_connector);
+                            scon->con_pack = inner_entry;
+                            scon->next = NULL;
+                            if (se->anchor_connectors == NULL) {
+                                se->anchor_connectors = scon;
+                            } else {
+                                simplified_connector *last = se->anchor_connectors;
+                                while ((last) && (last->next)) last = last->next;
+                                last->next = scon;
+                            }
+                            scon->connect_to = NULL;
+                        }
+                    }
+                }
+                if (ssc->no_ends >= MAX_SCENE_ENDS) internal_error("too many scene ends");
+                ssc->ends[ssc->no_ends++] = se;
+            }
+        }
+    }
+    return ssc;
+}
+
+int PlotElement::is_entire_game(simplified_scene *ssc) {
+    if (Metadata::read_optional_numeric(ssc->pack, I"^is_entire_game")) return TRUE;
+    return FALSE;
+}
+
+int PlotElement::recurs(simplified_scene *ssc) {
+    if (Metadata::read_optional_numeric(ssc->pack, I"^recurs")) return TRUE;
+    return FALSE;
+}
+
+int PlotElement::never_ends(simplified_scene *ssc) {
+    if (Metadata::read_optional_numeric(ssc->pack, I"^never_ends")) return TRUE;
+    return FALSE;
+}
+
+int PlotElement::starts_at_start_of_play(simplified_scene *ssc) {
+    if (Metadata::read_optional_numeric(ssc->pack, I"^starts")) return TRUE;
+    return FALSE;
+}
+
+int PlotElement::starts_on_condition(simplified_scene *ssc) {
+    if (Metadata::read_optional_numeric(ssc->pack, I"^starts_on_condition")) return TRUE;
+    return FALSE;
+}
+
+int PlotElement::no_ends(simplified_scene *ssc) {
+    return ssc->no_ends;
+}
+
+text_stream *PlotElement::scene_name(simplified_scene *ssc) {
+    return Metadata::read_textual(ssc->pack, I"^name");
+}
+
+text_stream *PlotElement::end_name(simplified_end *se) {
+    return Metadata::read_textual(se->end_pack, I"^name");
+}
+
+text_stream *PlotElement::anchor_condition(simplified_end *se) {
+    return Metadata::read_textual(se->end_pack, I"^condition");
+}
+
+int PlotElement::has_anchor_condition(simplified_end *se) {
+    if (Str::len(PlotElement::anchor_condition(se)) > 0) return TRUE;
+    return FALSE;
+}
+
+int PlotElement::anchor_condition_set_at(simplified_end *se) {
+    return (int) Metadata::read_optional_numeric(se->end_pack, I"^at");
+}
+
+inter_symbol *PlotElement::end_rulebook(simplified_end *se) {
+    return Metadata::read_optional_symbol(se->end_pack, I"^rulebook");
+}
+
+simplified_scene *PlotElement::connects_to(simplified_connector *scon) {
+    if (scon->connect_to) return scon->connect_to;
+    inter_symbol *sc_symbol = Metadata::read_optional_symbol(scon->con_pack, I"^to");
+    if (sc_symbol) {
+        inter_package *to_pack = Inter::Packages::container(sc_symbol->definition);
+        simplified_scene *ssc;
+        LOOP_OVER(ssc, simplified_scene)
+            if (ssc->pack == to_pack) {
+                scon->connect_to = ssc;
+                return ssc;
+            }
+    }
+    internal_error("scene metadata broken: bad connector");
+    return NULL;
+}
+
+int PlotElement::scon_end(simplified_connector *scon) {
+    return (int) Metadata::read_numeric(scon->con_pack, I"^end");
+}
+
+int PlotElement::scon_at(simplified_connector *scon) {
+    return (int) Metadata::read_numeric(scon->con_pack, I"^at");
+}
+
+void PlotElement::render(OUTPUT_STREAM) {
+    inter_tree *I = Index::get_tree();
+    tree_inventory *inv = Synoptic::inv(I);
+    TreeLists::sort(inv->scene_nodes, PlotElement::scene_order);
+    TreeLists::sort(inv->rulebook_nodes, Synoptic::module_order);
+
+    int no_scenes = TreeLists::len(inv->scene_nodes);
+    simplified_scene **plot = Memory::calloc(no_scenes, sizeof(simplified_scene *), SCENE_SORTING_MREASON);
+    for (int i=0; i<no_scenes; i++)
+        plot[i] = PlotElement::simplified(I, Inter::Package::defined_by_frame(inv->scene_nodes->list[i].node));
+
+    Tabulate the scenes1.1;
+    Show the legend for the scene table icons1.2;
+    Give details of each scene in turn1.3;
+    Memory::I7_array_free(plot, SCENE_SORTING_MREASON, no_scenes, sizeof(simplified_scene *));
+}
+
+
  • The structure simplified_scene is accessed in 6/ir and here.
  • The structure simplified_end is private to this section.
  • The structure simplified_connector is accessed in 2/ass and here.
+

§1.1. The sorted ordering is used as-is later on, when we get to the details, but +for the tabulation it's refined further. First we have the start-of-play +scenes, in sorted order; then scenes with a condition for their beginning +(end 0), in sorted order; then scenes that don't, and which haven't been +covered as a result of one of the earlier ones, also in sorted order. (This +third category is usually empty except for scenes the author has forgotten +about and created but never made use of.) +

+ +

Tabulate the scenes1.1 = +

+ +
+    simplified_scene *ssc;
+    LOOP_OVER(ssc, simplified_scene)
+        if ((PlotElement::starts_at_start_of_play(ssc)) || (PlotElement::is_entire_game(ssc)))
+            PlotElement::index_from_scene(OUT, plot, ssc, 0, START_OF_PLAY_END, NULL);
+    LOOP_OVER(ssc, simplified_scene)
+        if ((PlotElement::starts_on_condition(ssc)) && (PlotElement::is_entire_game(ssc) == FALSE))
+            PlotElement::index_from_scene(OUT, plot, ssc, 0, START_OF_PLAY_END, NULL);
+    LOOP_OVER(ssc, simplified_scene)
+        if (ssc->indexed_already == FALSE)
+            PlotElement::index_from_scene(OUT, plot, ssc, 0, NEVER_HAPPENS_END, NULL);
+
+
  • This code is used in §1.
+

§1.2. Show the legend for the scene table icons1.2 = +

+ +
+    HTML_OPEN("p"); WRITE("Legend: ");
+    PlotElement::scene_icon_legend(OUT, "WPB", "Begins when play begins");
+    WRITE("; ");
+    PlotElement::scene_icon_legend(OUT, "WhenC", "can begin whenever some condition holds");
+    WRITE("; ");
+    PlotElement::scene_icon_legend(OUT, "Segue", "follows when a previous scene ends");
+    WRITE("; ");
+    PlotElement::scene_icon_legend(OUT, "Simul", "begins simultaneously");
+    WRITE("; ");
+    PlotElement::scene_icon_legend(OUT, "WNever", "never begins");
+    WRITE("; ");
+    PlotElement::scene_icon_legend(OUT, "ENever", "never ends");
+    WRITE("; ");
+    PlotElement::scene_icon_legend(OUT, "Recurring", "recurring (can happen more than once)");
+    WRITE(". <i>Scene names are italicised when and if they appear for a second "
+        "or subsequent time because the scene can begin in more than one way</i>.");
+    HTML_CLOSE("p");
+
+
  • This code is used in §1.
+

§1.3. Give details of each scene in turn1.3 = +

+ +
+    Index::anchor(OUT, I"SDETAILS");
+    simplified_scene *ssc;
+    LOOP_OVER(ssc, simplified_scene) {
+        HTML_TAG("hr");
+        Give details of a specific scene1.3.1;
+    }
+
+
  • This code is used in §1.
+

§1.3.1. The curious condition about end 1 here is to avoid printing "Ends: Never" +in cases where fancier ends for the scene exist, so that the scene can, in +fact, end. +

+ +

Give details of a specific scene1.3.1 = +

+ +
+    Index the name and recurrence status of the scene1.3.1.1;
+    if (PlotElement::is_entire_game(ssc)) Explain the Entire Game scene1.3.1.2;
+
+    for (int end=0; end<PlotElement::no_ends(ssc); end++) {
+        if ((end == 1) && (PlotElement::no_ends(ssc) > 2) &&
+            (PlotElement::has_anchor_condition(ssc->ends[1]) == FALSE) &&
+            (ssc->ends[1]->anchor_connectors==NULL))
+            continue;
+        Index the conditions for this scene end to occur1.3.1.4;
+        Index the rules which apply when this scene end occurs1.3.1.5;
+        if (end == 0) Index the rules which apply during this scene1.3.1.3;
+    }
+
+
  • This code is used in §1.3.
+

§1.3.1.1. Index the name and recurrence status of the scene1.3.1.1 = +

+ +
+    HTML::open_indented_p(OUT, 1, "hanging");
+    Index::anchor_numbered(OUT, ssc->allocation_id);
+    WRITE("<b>The <i>%S</i> scene</b>", Metadata::read_textual(ssc->pack, I"^name"));
+    int at = (int) Metadata::read_optional_numeric(ssc->pack, I"^at");
+    if (at > 0) Index::link(OUT, at);
+    if (PlotElement::recurs(ssc)) WRITE("&nbsp;&nbsp;<i>recurring</i>");
+    HTML_CLOSE("p");
+
+ +

§1.3.1.2. Explain the Entire Game scene1.3.1.2 = +

+ +
+    HTML::open_indented_p(OUT, 1, "tight");
+    WRITE("The Entire Game scene is built-in. It is going on whenever play is "
+        "going on. (It is recurring so that if the story ends, but then resumes, "
+        "it too will end but then begin again.)");
+    HTML_CLOSE("p");
+
+ +

§1.3.1.3. Index the rules which apply during this scene1.3.1.3 = +

+ +
+    int rbc = 0;
+    for (int i=0; i<TreeLists::len(inv->rulebook_nodes); i++) {
+        inter_package *pack = Inter::Package::defined_by_frame(inv->rulebook_nodes->list[i].node);
+        if (IndexRules::is_contextually_empty(I, pack, IndexRules::scene_context(ssc)) == FALSE) {
+            if (rbc++ == 0) {
+                HTML::open_indented_p(OUT, 1, "hanging");
+                WRITE("<i>During this scene:</i>");
+                HTML_CLOSE("p");
+            }
+            HTML::open_indented_p(OUT, 2, "hanging");
+            WRITE("<i>%S</i>", Metadata::read_textual(pack, I"^printed_name")); HTML_CLOSE("p");
+            int ignore_me = 0;
+            IndexRules::index_rulebook(OUT, I, pack, I"", IndexRules::scene_context(ssc), &ignore_me);
+        }
+    }
+
+ +

§1.3.1.4. Index the conditions for this scene end to occur1.3.1.4 = +

+ +
+    HTML::open_indented_p(OUT, 1, "hanging");
+    WRITE("<i>%s ", (end==0)?"Begins":"Ends");
+    if (end >= 2) WRITE("%S ", PlotElement::end_name(ssc->ends[end]));
+    WRITE("when:</i> ");
+    int count = 0;
+    Index the play-begins condition1.3.1.4.1;
+    Index the I7 condition for a scene to end1.3.1.4.2;
+    Index connections to other scene ends1.3.1.4.3;
+    if (count == 0) WRITE("<b>never</b>");
+    HTML_CLOSE("p");
+
+ +

§1.3.1.4.1. Index the play-begins condition1.3.1.4.1 = +

+ +
+    if ((end==0) && (PlotElement::starts_at_start_of_play(ssc))) {
+        if (count > 0) {
+            HTML_TAG("br");
+            WRITE("<i>or when:</i> ");
+        }
+        WRITE("<b>play begins</b>");
+        count++;
+    }
+
+ +

§1.3.1.4.2. Index the I7 condition for a scene to end1.3.1.4.2 = +

+ +
+    if (PlotElement::has_anchor_condition(ssc->ends[end])) {
+        if (count > 0) {
+            HTML_TAG("br");
+            WRITE("<i>or when:</i> ");
+        }
+        WRITE("%S", PlotElement::anchor_condition(ssc->ends[end]));
+        int at = PlotElement::anchor_condition_set_at(ssc->ends[end]);
+        if (at > 0) Index::link(OUT, at);
+        count++;
+    }
+
+ +

§1.3.1.4.3. Index connections to other scene ends1.3.1.4.3 = +

+ +
+    for (simplified_connector *scon = ssc->ends[end]->anchor_connectors; scon; scon=scon->next) {
+        if (count > 0) {
+            HTML_TAG("br");
+            WRITE("<i>or when:</i> ");
+        }
+        simplified_scene *to_ssc = PlotElement::connects_to(scon);
+        text_stream *NW = PlotElement::scene_name(to_ssc);
+        WRITE("<b>%S</b> <i>%s</i>", NW, (PlotElement::scon_end(scon)==0)?"begins":"ends");
+        if (PlotElement::scon_end(scon) >= 2) WRITE(" %S", PlotElement::end_name(to_ssc->ends[PlotElement::scon_end(scon)]));
+        Index::link(OUT, PlotElement::scon_at(scon));
+        count++;
+    }
+
+ +

§1.3.1.5. Index the rules which apply when this scene end occurs1.3.1.5 = +

+ +
+    inter_symbol *rb = PlotElement::end_rulebook(ssc->ends[end]);
+    inter_package *rb_pack = Inter::Packages::container(rb->definition);
+    if (IndexRules::no_rules(I, rb_pack) > 0) {
+        HTML::open_indented_p(OUT, 1, "hanging");
+        WRITE("<i>What happens:</i>"); HTML_CLOSE("p");
+        int ignore_me = 0;
+        IndexRules::index_rulebook(OUT, I, rb_pack, I"", IndexRules::no_rule_context(), &ignore_me);
+    }
+
+ +

§2. Table of Scenes. We finally return to the table of scenes. The following is recursive, and +is called at the top level for each scene in turn which starts at the start +of play (see above). +

+ +

A scene entry can be arrived at in three ways: through one of its ends, in +which case end is the number (0 for begins, 1 for standard ends, and so on), +or through being already active at the start of play, or through being covered +in the index even though it never happens in play. This means we need two +additional end numbers. They are only ever used at the top level, that is, +on the initial call when depth is 0. +

+ +
define START_OF_PLAY_END -1
+define NEVER_HAPPENS_END -2
+
+
+void PlotElement::index_from_scene(OUTPUT_STREAM, simplified_scene **plot,
+    simplified_scene *ssc, int depth, int end, simplified_scene *sc_from) {
+    HTML::open_indented_p(OUT, depth+1, "tight");
+    Indicate the route by which this scene was reached2.1;
+    Name the scene in the table, italicised if we've seen it already2.2;
+    if (ssc->indexed_already == FALSE) {
+        Show the never-ends icon if appropriate2.3;
+        Show the recurring icon if appropriate2.4;
+    }
+    HTML_CLOSE("p");
+    if (ssc->indexed_already) return;
+    ssc->indexed_already = TRUE;
+    Indent to tabulate other scenes connected to the ends of this one2.5;
+}
+
+

§2.1. Indicate the route by which this scene was reached2.1 = +

+ +
+    switch(end) {
+        case 0: PlotElement::scene_icon(OUT, "Simul"); break;
+        case 1: PlotElement::scene_icon(OUT, "Segue"); break;
+        case START_OF_PLAY_END: break;
+        case NEVER_HAPPENS_END: PlotElement::scene_icon(OUT, "WNever"); break;
+        default:
+            PlotElement::scene_icon(OUT, "Segue");
+            WRITE("[ends %S]&nbsp;", PlotElement::end_name(sc_from->ends[end])); break;
+    }
+    if ((ssc->indexed_already == FALSE) || (depth == 0)) {
+        if (PlotElement::is_entire_game(ssc)) PlotElement::scene_icon(OUT, "WPB");
+        else if (PlotElement::starts_on_condition(ssc)) PlotElement::scene_icon(OUT, "WhenC");
+        if (PlotElement::starts_at_start_of_play(ssc)) PlotElement::scene_icon(OUT, "WPB");
+    }
+
+
  • This code is used in §2.
+

§2.2. Name the scene in the table, italicised if we've seen it already2.2 = +

+ +
+    if (ssc->indexed_already) WRITE("<i>");
+    WRITE("%S", Metadata::read_textual(ssc->pack, I"^name"));
+    if (ssc->indexed_already) WRITE("</i>");
+    else Index::below_link_numbered(OUT, ssc->allocation_id);
+
+
  • This code is used in §2.
+

§2.3. Show the never-ends icon if appropriate2.3 = +

+ +
+    if (PlotElement::never_ends(ssc))
+        PlotElement::scene_icon_append(OUT, "ENever");
+
+
  • This code is used in §2.
+

§2.4. Show the recurring icon if appropriate2.4 = +

+ +
+    if (PlotElement::recurs(ssc))
+        PlotElement::scene_icon_append(OUT, "Recurring");
+
+
  • This code is used in §2.
+

§2.5. And this is where the routine recurses, so that consequent scenes are +tabulated underneath the present one, indented one step further in (since +indentation is coupled to depth). First we recurse to scenes which end when +this one does; then to scenes which begin when this one ends. +

+ +

Indent to tabulate other scenes connected to the ends of this one2.5 = +

+ +
+    simplified_scene *ssc2;
+    LOOP_OVER(ssc2, simplified_scene) {
+        for (simplified_connector *scon = ssc2->ends[0]->anchor_connectors; scon; scon=scon->next)
+            if ((PlotElement::connects_to(scon) == ssc) && (PlotElement::scon_end(scon) >= 1))
+                PlotElement::index_from_scene(OUT, plot, ssc2, depth + 1, PlotElement::scon_end(scon), ssc);
+    }
+    LOOP_OVER(ssc2, simplified_scene) {
+        for (simplified_connector *scon = ssc2->ends[0]->anchor_connectors; scon; scon=scon->next)
+            if ((PlotElement::connects_to(scon) == ssc) && (PlotElement::scon_end(scon) == 0))
+                PlotElement::index_from_scene(OUT, plot, ssc2, depth, PlotElement::scon_end(scon), ssc);
+    }
+
+
  • This code is used in §2.
+

§3. We have been using: +

+ +
+void PlotElement::scene_icon(OUTPUT_STREAM, char *si) {
+    PlotElement::scene_icon_unspaced(OUT, si); WRITE("&nbsp;&nbsp;");
+}
+
+void PlotElement::scene_icon_append(OUTPUT_STREAM, char *si) {
+    WRITE("&nbsp;&nbsp;"); PlotElement::scene_icon_unspaced(OUT, si);
+}
+
+void PlotElement::scene_icon_legend(OUTPUT_STREAM, char *si, char *gloss) {
+    PlotElement::scene_icon_unspaced(OUT, si); WRITE("&nbsp;<i>%s</i>", gloss);
+}
+
+void PlotElement::scene_icon_unspaced(OUTPUT_STREAM, char *si) {
+    HTML_TAG_WITH("img", "border=0 src=inform:/scene_icons/%s.png", si);
+}
+
+

§4. Lastly: the following is the criterion used for sorting the scenes into +their indexing order. The Entire Game always comes first, and then come the +rest in ascending alphabetical order. +

+ +
+int PlotElement::scene_order(const void *ent1, const void *ent2) {
+    itl_entry *E1 = (itl_entry *) ent1;
+    itl_entry *E2 = (itl_entry *) ent2;
+    if (E1 == E2) return 0;
+    inter_tree_node *P1 = E1->node;
+    inter_tree_node *P2 = E2->node;
+    inter_package *sc1 = Inter::Package::defined_by_frame(P1);
+    inter_package *sc2 = Inter::Package::defined_by_frame(P2);
+    if (Metadata::read_optional_numeric(sc1, I"^is_entire_game")) return -1;
+    if (Metadata::read_optional_numeric(sc2, I"^is_entire_game")) return 1;
+    text_stream *SW1 = Metadata::read_textual(sc1, I"^name");
+    text_stream *SW2 = Metadata::read_textual(sc2, I"^name");
+    return Str::cmp(SW1, SW2);
+}
+
+ + +
+ + + diff --git a/docs/codegen-module/6-re.html b/docs/codegen-module/6-re.html index 73133ff5d..54afe9c5e 100644 --- a/docs/codegen-module/6-re.html +++ b/docs/codegen-module/6-re.html @@ -112,7 +112,7 @@ function togglePopup(material_id) { }
diff --git a/docs/codegen-module/6-rfse.html b/docs/codegen-module/6-rfse.html index 68ac9e41a..f9656b844 100644 --- a/docs/codegen-module/6-rfse.html +++ b/docs/codegen-module/6-rfse.html @@ -94,7 +94,7 @@ function togglePopup(material_id) { }
diff --git a/docs/codegen-module/6-se.html b/docs/codegen-module/6-se.html index b24e2d275..42bbca22b 100644 --- a/docs/codegen-module/6-se.html +++ b/docs/codegen-module/6-se.html @@ -275,7 +275,7 @@ their contents in logical order. }
diff --git a/docs/codegen-module/6-te.html b/docs/codegen-module/6-te.html index 439b8f7e0..ed33c6fc7 100644 --- a/docs/codegen-module/6-te.html +++ b/docs/codegen-module/6-te.html @@ -250,7 +250,7 @@ Helvetica-style lower case "x", but life is full of compromises.
diff --git a/docs/codegen-module/6-ve.html b/docs/codegen-module/6-ve.html index d51d6a76f..8cf996a78 100644 --- a/docs/codegen-module/6-ve.html +++ b/docs/codegen-module/6-ve.html @@ -168,7 +168,7 @@ function togglePopup(material_id) { diff --git a/docs/codegen-module/6-ve2.html b/docs/codegen-module/6-ve2.html index b4fda3b62..915b9a263 100644 --- a/docs/codegen-module/6-ve2.html +++ b/docs/codegen-module/6-ve2.html @@ -116,7 +116,7 @@ function togglePopup(material_id) { } diff --git a/docs/codegen-module/index.html b/docs/codegen-module/index.html index 949290946..f240dd493 100644 --- a/docs/codegen-module/index.html +++ b/docs/codegen-module/index.html @@ -421,6 +421,16 @@ Lexicon Element
- To write the Lexicon element (Lx) in the index.

+
  • +

    + Arithmetic Element - + To index dimensional rules.

    +
  • +
  • +

    + Plot Element - + To write the Plot element (Pl) in the index.

    +
  • diff --git a/docs/if-module/3-scn.html b/docs/if-module/3-scn.html index 564c66764..38f87bb07 100644 --- a/docs/if-module/3-scn.html +++ b/docs/if-module/3-scn.html @@ -196,8 +196,6 @@ which can cause it, or can be "anchored" to any number of ends of other scenes — to express which, the scene_connector structure is used.

    -
    define MAX_SCENE_ENDS 32  this must exceed 31
    -
     typedef struct scene {
         struct instance *as_instance;  the constant for the name of the scene
    @@ -205,7 +203,7 @@ scenes — to express which, the 
         int start_of_play;  if begins when play begins
         int marker;  used to detect potentially infinite recursion when scene changes occur
         int no_ends;  how many ends the scene has
    -    struct scene_end ends[MAX_SCENE_ENDS];
    +    struct scene_end ends[MAX_SCENE_ENDS];
         int indexed;  temporary storage during Scenes index creation
         CLASS_DEFINITION
     } scene;
    @@ -300,6 +298,12 @@ to translate this to other languages.)
         if (Kinds::eq(K, K_scene)) return PLUGIN_DATA_ON_SUBJECT(scenes, I->as_subject);
         return NULL;
     }
    +
    +int Scenes::is_entire_game(instance *I) {
    +    if ((SC_entire_game) && (Scenes::from_named_constant(I) == SC_entire_game))
    +        return TRUE;
    +    return FALSE;
    +}
     

    §14. Creating and parsing ends.

    diff --git a/docs/index-module/2-act.html b/docs/index-module/2-act.html index dc0cfbf37..5e664d8b7 100644 --- a/docs/index-module/2-act.html +++ b/docs/index-module/2-act.html @@ -78,7 +78,7 @@ struct activity_crossref *next; } activity_crossref; - +

    §2.

    @@ -102,7 +102,7 @@
     }
     
    diff --git a/docs/index-module/2-adj.html b/docs/index-module/2-adj.html index 6846a8c4a..9a8525290 100644 --- a/docs/index-module/2-adj.html +++ b/docs/index-module/2-adj.html @@ -96,7 +96,7 @@ prefaced "(of a rulebook)", "(of an activity)", and so on. diff --git a/docs/index-module/2-ae.html b/docs/index-module/2-ae.html deleted file mode 100644 index 952b06023..000000000 --- a/docs/index-module/2-ae.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - Arithmetic Element - - - - - - - - - - - - - - - -
    - - -

    To index dimensional rules.

    - -

    §1.

    - -
    -void IXArithmetic::render(OUTPUT_STREAM) {
    -    HTML_TAG("hr");
    -    Index the rubric about quasinumerical kinds1.1;
    -    Index the table of quasinumerical kinds1.2;
    -    Index the table of multiplication rules1.3;
    -}
    -
    -

    §1.1. Index the rubric about quasinumerical kinds1.1 = -

    - -
    -    HTML_OPEN("p");
    -    HTML_TAG_WITH("a", "calculator");
    -    HTML::begin_plain_html_table(OUT);
    -    HTML::first_html_column(OUT, 0);
    -    HTML_TAG_WITH("img", "border=0 src=inform:/doc_images/calc2.png");
    -    WRITE("&nbsp;");
    -    WRITE("Kinds of value marked with the <b>calculator symbol</b> are numerical - "
    -        "these are values we can add, multiply and so on. The range of these "
    -        "numbers depends on the Format setting for the project (Glulx format "
    -        "supports much higher numbers than Z-code).");
    -    HTML::end_html_row(OUT);
    -    HTML::end_html_table(OUT);
    -    HTML_CLOSE("p");
    -
    - -

    §1.2. Index the table of quasinumerical kinds1.2 = -

    - -
    -    HTML_OPEN("p");
    -    HTML::begin_plain_html_table(OUT);
    -
    -    HTML::first_html_column(OUT, 0);
    -    WRITE("<b>kind of value</b>");
    -    HTML::next_html_column(OUT, 0);
    -    WRITE("<b>minimum</b>");
    -    HTML::next_html_column(OUT, 0);
    -    WRITE("<b>maximum</b>");
    -    HTML::next_html_column(OUT, 0);
    -    WRITE("<b>dimensions</b>");
    -    HTML::end_html_row(OUT);
    -
    -    kind *R;
    -    LOOP_OVER_BASE_KINDS(R)
    -        if (Kinds::Behaviour::is_quasinumerical(R)) {
    -            if (Kinds::is_intermediate(R)) continue;
    -            HTML::first_html_column(OUT, 0);
    -            Kinds::Index::index_kind(OUT, R, FALSE, FALSE);
    -            HTML::next_html_column(OUT, 0);
    -            Index the minimum positive value for a quasinumerical kind1.2.1;
    -            HTML::next_html_column(OUT, 0);
    -            Index the maximum positive value for a quasinumerical kind1.2.2;
    -            HTML::next_html_column(OUT, 0);
    -            if (Kinds::Dimensions::dimensionless(R)) WRITE("<i>dimensionless</i>");
    -            else {
    -                unit_sequence *deriv = Kinds::Behaviour::get_dimensional_form(R);
    -                Kinds::Dimensions::index_unit_sequence(OUT, deriv, TRUE);
    -            }
    -            HTML::end_html_row(OUT);
    -        }
    -    HTML::end_html_table(OUT);
    -    HTML_CLOSE("p");
    -
    - -

    §1.2.1. At run-time, the minimum positive value is of course 1, but because of -scaling this can appear to be much lower. -

    - -

    Index the minimum positive value for a quasinumerical kind1.2.1 = -

    - -
    -    if (Kinds::eq(R, K_number)) WRITE("1");
    -    else {
    -        text_stream *p = Kinds::Behaviour::get_index_minimum_value(R);
    -        if (Str::len(p) > 0) WRITE("%S", p);
    -        else LiteralPatterns::index_value(OUT,
    -            LiteralPatterns::list_of_literal_forms(R), 1);
    -    }
    -
    - -

    §1.2.2. Index the maximum positive value for a quasinumerical kind1.2.2 = -

    - -
    -    if (Kinds::eq(R, K_number)) {
    -        if (TargetVMs::is_16_bit(Task::vm())) WRITE("32767");
    -        else WRITE("2147483647");
    -    } else {
    -        text_stream *p = Kinds::Behaviour::get_index_maximum_value(R);
    -        if (Str::len(p) > 0) WRITE("%S", p);
    -        else {
    -            if (TargetVMs::is_16_bit(Task::vm()))
    -                LiteralPatterns::index_value(OUT,
    -                    LiteralPatterns::list_of_literal_forms(R), 32767);
    -            else
    -                LiteralPatterns::index_value(OUT,
    -                    LiteralPatterns::list_of_literal_forms(R), 2147483647);
    -        }
    -    }
    -
    - -

    §1.3. This is simply a table of all the multiplications declared in the source -text, sorted into kind order of left and then right operand. -

    - -

    Index the table of multiplication rules1.3 = -

    - -
    -    kind *L, *R, *O;
    -    int NP = 0, wn;
    -    LOOP_OVER_MULTIPLICATIONS(L, R, O, wn) {
    -        if (NP++ == 0) {
    -            HTML_OPEN("p");
    -            WRITE("This is how multiplication changes kinds:");
    -            HTML_CLOSE("p");
    -            HTML_OPEN("p");
    -            HTML::begin_plain_html_table(OUT);
    -        }
    -        HTML::first_html_column(OUT, 0);
    -        if (wn >= 0) Index::link(OUT, wn);
    -        HTML::next_html_column(OUT, 0);
    -        Kinds::Index::index_kind(OUT, L, FALSE, FALSE);
    -        HTML::begin_colour(OUT, I"808080");
    -        WRITE(" x ");
    -        HTML::end_colour(OUT);
    -        Kinds::Index::index_kind(OUT, R, FALSE, FALSE);
    -        HTML::begin_colour(OUT, I"808080");
    -        WRITE(" = ");
    -        HTML::end_colour(OUT);
    -        Kinds::Index::index_kind(OUT, O, FALSE, FALSE);
    -        WRITE("&nbsp;&nbsp;&nbsp;&nbsp;");
    -        HTML::next_html_column(OUT, 0);
    -        LiteralPatterns::index_benchmark_value(OUT, L);
    -        HTML::begin_colour(OUT, I"808080");
    -        WRITE(" x ");
    -        HTML::end_colour(OUT);
    -        LiteralPatterns::index_benchmark_value(OUT, R);
    -        HTML::begin_colour(OUT, I"808080");
    -        WRITE(" = ");
    -        HTML::end_colour(OUT);
    -        LiteralPatterns::index_benchmark_value(OUT, O);
    -        HTML::end_html_row(OUT);
    -    }
    -    if (NP > 0) { HTML::end_html_table(OUT); HTML_CLOSE("p"); }
    -
    - - - -
    - - - diff --git a/docs/index-module/2-ie.html b/docs/index-module/2-ie.html index a2b2409aa..a89a5e105 100644 --- a/docs/index-module/2-ie.html +++ b/docs/index-module/2-ie.html @@ -311,7 +311,7 @@ dictionary. } diff --git a/docs/index-module/2-inf.html b/docs/index-module/2-inf.html index 83a9959fd..16cad0696 100644 --- a/docs/index-module/2-inf.html +++ b/docs/index-module/2-inf.html @@ -194,7 +194,7 @@ state of being boolean, and the given certainty levels: } diff --git a/docs/index-module/2-ins.html b/docs/index-module/2-ins.html index 9ccc34f7e..2a226d338 100644 --- a/docs/index-module/2-ins.html +++ b/docs/index-module/2-ins.html @@ -89,7 +89,7 @@ function togglePopup(material_id) { struct instance_usage *next; } instance_usage; - +

    §2.

    @@ -203,7 +203,7 @@ constant value.
     }
     
    diff --git a/docs/index-module/2-ki.html b/docs/index-module/2-ki.html index 70e26b5be..421ec7706 100644 --- a/docs/index-module/2-ki.html +++ b/docs/index-module/2-ki.html @@ -522,7 +522,7 @@ as "0 kg", "0 hectares", or whatever is appropriate.

    §6. Indexing kind names.

    -void Kinds::Index::index_kind(OUTPUT_STREAM, kind *K, int plural, int with_links) {
    +void Kinds::Index::index_kind(OUTPUT_STREAM, kind *K, int plural, int with_links) {
         if (K == NULL) return;
         wording W = Kinds::Behaviour::get_name(K, plural);
         if (Wordings::nonempty(W)) {
    @@ -571,7 +571,7 @@ as "0 kg", "0 hectares", or whatever is appropriate.
     
    diff --git a/docs/index-module/2-me.html b/docs/index-module/2-me.html index f7728d3d5..6a7d4e862 100644 --- a/docs/index-module/2-me.html +++ b/docs/index-module/2-me.html @@ -475,7 +475,7 @@ table of Kinds. } diff --git a/docs/index-module/2-pi.html b/docs/index-module/2-pi.html index 32fdf04a5..11fdbfda6 100644 --- a/docs/index-module/2-pi.html +++ b/docs/index-module/2-pi.html @@ -501,7 +501,7 @@ so we won't list them here. } diff --git a/docs/index-module/2-prp.html b/docs/index-module/2-prp.html index cd95733b5..6bfef317c 100644 --- a/docs/index-module/2-prp.html +++ b/docs/index-module/2-prp.html @@ -143,7 +143,7 @@ function togglePopup(material_id) { } diff --git a/docs/index-module/2-rls.html b/docs/index-module/2-rls.html index 027910833..e16f8ef6e 100644 --- a/docs/index-module/2-rls.html +++ b/docs/index-module/2-rls.html @@ -313,7 +313,7 @@ want this, so:

    §7.

    -int IXRules::index_rulebook(OUTPUT_STREAM, rulebook *rb, char *billing, rule_context rc, int *resp_count) {
    +int IXRules::index_rulebook(OUTPUT_STREAM, rulebook *rb, char *billing, rule_context rc, int *resp_count) {
         int suppress_outcome = FALSE, t;
         if (rb == NULL) return 0;
         if (billing == NULL) internal_error("No billing for rb index");
    @@ -330,7 +330,7 @@ want this, so:
     }
     
     #ifdef IF_MODULE
    -void IXRules::index_action_rules(OUTPUT_STREAM, action_name *an, rulebook *rb,
    +void IXRules::index_action_rules(OUTPUT_STREAM, action_name *an, rulebook *rb,
         int code, char *desc, int *resp_count) {
         int t = 0;
         IXRules::list_suppress_indexed_links();
    @@ -380,7 +380,7 @@ have affected it in this way:
         return t;
     }
     
    -void IXRules::rb_index_placements(OUTPUT_STREAM, rulebook *rb) {
    +void IXRules::rb_index_placements(OUTPUT_STREAM, rulebook *rb) {
         placement_affecting *npl = rb->indexing_data.placement_list;
         while (npl) {
             WRITE("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
    @@ -393,7 +393,7 @@ have affected it in this way:
         }
     }
     
    -void IXRules::index_outcomes(OUTPUT_STREAM, outcomes *outs, int suppress_outcome) {
    +void IXRules::index_outcomes(OUTPUT_STREAM, outcomes *outs, int suppress_outcome) {
         if (suppress_outcome == FALSE) {
             rulebook_outcome *ro;
             LOOP_OVER_LINKED_LIST(ro, rulebook_outcome, outs->named_outcomes) {
    @@ -426,7 +426,7 @@ have affected it in this way:
         }
     }
     
    - +

    §9. Rule contexts. These are mainly (only?) used in indexing, as a way to represent the idea of being the relevant scene or action for a rule.

    @@ -437,20 +437,20 @@ being the relevant scene or action for a rule. struct scene *scene_context; } rule_context; -rule_context IXRules::action_context(action_name *an) { +rule_context IXRules::action_context(action_name *an) { rule_context rc; rc.action_context = an; rc.scene_context = NULL; return rc; } -rule_context IXRules::scene_context(scene *s) { +rule_context IXRules::scene_context(scene *s) { rule_context rc; rc.action_context = NULL; rc.scene_context = s; return rc; } -rule_context IXRules::no_rule_context(void) { +rule_context IXRules::no_rule_context(void) { rule_context rc; rc.action_context = NULL; rc.scene_context = NULL; @@ -470,7 +470,7 @@ text to assert a change:

    -void IXRules::index_response(OUTPUT_STREAM, rule *R, int marker, response_message *resp) {
    +void IXRules::index_response(OUTPUT_STREAM, rule *R, int marker, response_message *resp) {
         WRITE("&nbsp;&nbsp;&nbsp;&nbsp;");
         HTML_OPEN_WITH("span",
             "style=\"color: #ffffff; "
    @@ -494,7 +494,7 @@ text to assert a change:
     }
     
    diff --git a/docs/index-module/3-act.html b/docs/index-module/3-act.html index aace8872f..fb07548ce 100644 --- a/docs/index-module/3-act.html +++ b/docs/index-module/3-act.html @@ -276,7 +276,7 @@ function togglePopup(material_id) { diff --git a/docs/index-module/3-bck.html b/docs/index-module/3-bck.html index 97ebd9182..dde7b09cb 100644 --- a/docs/index-module/3-bck.html +++ b/docs/index-module/3-bck.html @@ -119,7 +119,7 @@ adds backdrop contents to a room called
  • This code is used in §1.
  • diff --git a/docs/index-module/3-ci.html b/docs/index-module/3-ci.html index f3278dbd8..e45810e6b 100644 --- a/docs/index-module/3-ci.html +++ b/docs/index-module/3-ci.html @@ -577,7 +577,7 @@ the HTML index. } diff --git a/docs/index-module/3-pe.html b/docs/index-module/3-pe.html deleted file mode 100644 index 338b25fce..000000000 --- a/docs/index-module/3-pe.html +++ /dev/null @@ -1,471 +0,0 @@ - - - - Plot Element - - - - - - - - - - - - - - - - - - -
    - - -

    Parallel to the World index of space is the Scenes index of time, and in this section we render it as HTML.

    - -
    - -

    §1. The mapping of time is on the one hand simpler than the mapping of space -since there is only one dimension, but on the other hand more complex since -scenes can be multiply present at the same instant of time (whereas rooms -cannot be multiply present at the same point in space). We resolve this -with a notation which takes a little bit of on-screen explanation, but -seems natural enough to learn in practice. -

    - -
    -void IXScenes::render(OUTPUT_STREAM) {
    -    int nr = NUMBER_CREATED(scene);
    -    scene **sorted = Memory::calloc(nr, sizeof(scene *), INDEX_SORTING_MREASON);
    -    Sort the scenes1.1;
    -
    -    Tabulate the scenes1.2;
    -    Show the legend for the scene table icons1.3;
    -    Give details of each scene in turn1.4;
    -
    -    Memory::I7_array_free(sorted, INDEX_SORTING_MREASON, nr, sizeof(scene *));
    -}
    -
    -

    §1.1. As usual, we sort with the C library's qsort. -

    - -

    Sort the scenes1.1 = -

    - -
    -    int i = 0;
    -    scene *sc;
    -    LOOP_OVER(sc, scene) sorted[i++] = sc;
    -    qsort(sorted, (size_t) nr, sizeof(scene *), IXScenes::compare_scenes);
    -
    -
    • This code is used in §1.
    -

    §1.2. The sorted ordering is used as-is later on, when we get to the details, but -for the tabulation it's refined further. First we have the start-of-play -scenes, in sorted order; then scenes with a condition for their beginning -(end 0), in sorted order; then scenes that don't, and which haven't been -covered as a result of one of the earlier ones, also in sorted order. (This -third category is usually empty except for scenes the author has forgotten -about and created but never made use of.) -

    - -

    Tabulate the scenes1.2 = -

    - -
    -    for (int i=0; i<nr; i++) {
    -        scene *sc = sorted[i];
    -        if ((sc->start_of_play) || (sc == SC_entire_game))
    -            IXScenes::index_from_scene(OUT, sc, 0, START_OF_PLAY_END, NULL, sorted, nr);
    -    }
    -    for (int i=0; i<nr; i++) {
    -        scene *sc = sorted[i];
    -        if ((sc->ends[0].anchor_condition) && (sc != SC_entire_game))
    -            IXScenes::index_from_scene(OUT, sc, 0, START_OF_PLAY_END, NULL, sorted, nr);
    -    }
    -    for (int i=0; i<nr; i++) {
    -        scene *sc = sorted[i];
    -        if (sc->indexed == FALSE)
    -            IXScenes::index_from_scene(OUT, sc, 0, NEVER_HAPPENS_END, NULL, sorted, nr);
    -    }
    -
    -
    • This code is used in §1.
    -

    §1.3. Show the legend for the scene table icons1.3 = -

    - -
    -    HTML_OPEN("p"); WRITE("Legend: ");
    -    IXScenes::scene_icon_legend(OUT, "WPB", "Begins when play begins");
    -    WRITE("; ");
    -    IXScenes::scene_icon_legend(OUT, "WhenC", "can begin whenever some condition holds");
    -    WRITE("; ");
    -    IXScenes::scene_icon_legend(OUT, "Segue", "follows when a previous scene ends");
    -    WRITE("; ");
    -    IXScenes::scene_icon_legend(OUT, "Simul", "begins simultaneously");
    -    WRITE("; ");
    -    IXScenes::scene_icon_legend(OUT, "WNever", "never begins");
    -    WRITE("; ");
    -    IXScenes::scene_icon_legend(OUT, "ENever", "never ends");
    -    WRITE("; ");
    -    IXScenes::scene_icon_legend(OUT, "Recurring", "recurring (can happen more than once)");
    -    WRITE(". <i>Scene names are italicised when and if they appear for a second "
    -        "or subsequent time because the scene can begin in more than one way</i>.");
    -    HTML_CLOSE("p");
    -
    -
    • This code is used in §1.
    -

    §1.4. Give details of each scene in turn1.4 = -

    - -
    -    Index::anchor(OUT, I"SDETAILS");
    -    for (int i=0; i<nr; i++) {
    -        HTML_TAG("hr");
    -        scene *sc = sorted[i];
    -        Give details of a specific scene1.4.1;
    -    }
    -
    -
    • This code is used in §1.
    -

    §1.4.1. The curious condition about end 1 here is to avoid printing "Ends: Never" -in cases where fancier ends for the scene exist, so that the scene can, in -fact, end. -

    - -

    Give details of a specific scene1.4.1 = -

    - -
    -    Index the name and recurrence status of the scene1.4.1.1;
    -    if (sc == SC_entire_game) Explain the Entire Game scene1.4.1.2;
    -
    -    for (int end=0; end<sc->no_ends; end++) {
    -        if ((end == 1) && (sc->no_ends > 2) &&
    -            (sc->ends[1].anchor_condition==NULL) && (sc->ends[1].anchor_connectors==NULL))
    -            continue;
    -        Index the conditions for this scene end to occur1.4.1.4;
    -        Index the rules which apply when this scene end occurs1.4.1.5;
    -        if (end == 0) Index the rules which apply during this scene1.4.1.3;
    -    }
    -
    -
    • This code is used in §1.4.
    -

    §1.4.1.1. Index the name and recurrence status of the scene1.4.1.1 = -

    - -
    -    HTML::open_indented_p(OUT, 1, "hanging");
    -    Index::anchor_numbered(OUT, sc->allocation_id);
    -    WRITE("<b>The <i>%+W</i> scene</b>", Scenes::get_name(sc));
    -    Index::link(OUT, Wordings::first_wn(Node::get_text(Instances::get_creating_sentence(sc->as_instance))));
    -    if (PropertyInferences::either_or_state(
    -        Instances::as_subject(sc->as_instance), P_recurring) > 0)
    -        WRITE("&nbsp;&nbsp;<i>recurring</i>");
    -    HTML_CLOSE("p");
    -
    - -

    §1.4.1.2. Explain the Entire Game scene1.4.1.2 = -

    - -
    -    HTML::open_indented_p(OUT, 1, "tight");
    -    WRITE("The Entire Game scene is built-in. It is going on whenever play is "
    -        "going on. (It is recurring so that if the story ends, but then resumes, "
    -        "it too will end but then begin again.)");
    -    HTML_CLOSE("p");
    -
    - -

    §1.4.1.3. Index the rules which apply during this scene1.4.1.3 = -

    - -
    -    int rbc = 0;
    -    rulebook *rb;
    -    LOOP_OVER(rb, rulebook) {
    -        if (Rulebooks::is_contextually_empty(rb, IXRules::scene_context(sc)) == FALSE) {
    -            if (rbc++ == 0) {
    -                HTML::open_indented_p(OUT, 1, "hanging");
    -                WRITE("<i>During this scene:</i>");
    -                HTML_CLOSE("p");
    -            }
    -            HTML::open_indented_p(OUT, 2, "hanging");
    -            WRITE("<i>%+W</i>", rb->primary_name); HTML_CLOSE("p");
    -            int ignore_me = 0;
    -            IXRules::index_rulebook(OUT, rb, "", IXRules::scene_context(sc), &ignore_me);
    -        }
    -    }
    -
    - -

    §1.4.1.4. Index the conditions for this scene end to occur1.4.1.4 = -

    - -
    -    HTML::open_indented_p(OUT, 1, "hanging");
    -    WRITE("<i>%s ", (end==0)?"Begins":"Ends");
    -    if (end >= 2) WRITE("%+W ", sc->ends[end].end_names);
    -    WRITE("when:</i> ");
    -    int count = 0;
    -    Index the play-begins condition1.4.1.4.1;
    -    Index the I7 condition for a scene to end1.4.1.4.2;
    -    Index connections to other scene ends1.4.1.4.3;
    -    if (count == 0) WRITE("<b>never</b>");
    -    HTML_CLOSE("p");
    -
    - -

    §1.4.1.4.1. Index the play-begins condition1.4.1.4.1 = -

    - -
    -    if ((end==0) && (sc->start_of_play)) {
    -        if (count > 0) {
    -            HTML_TAG("br");
    -            WRITE("<i>or when:</i> ");
    -        }
    -        WRITE("<b>play begins</b>");
    -        count++;
    -    }
    -
    - -

    §1.4.1.4.2. Index the I7 condition for a scene to end1.4.1.4.2 = -

    - -
    -    if (sc->ends[end].anchor_condition) {
    -        if (count > 0) {
    -            HTML_TAG("br");
    -            WRITE("<i>or when:</i> ");
    -        }
    -        WRITE("%+W", Node::get_text(sc->ends[end].anchor_condition));
    -        Index::link(OUT, Wordings::first_wn(Node::get_text(sc->ends[end].anchor_condition_set)));
    -        count++;
    -    }
    -
    - -

    §1.4.1.4.3. Index connections to other scene ends1.4.1.4.3 = -

    - -
    -    for (scene_connector *scon = sc->ends[end].anchor_connectors; scon; scon=scon->next) {
    -        if (count > 0) {
    -            HTML_TAG("br");
    -            WRITE("<i>or when:</i> ");
    -        }
    -        wording NW = Instances::get_name(scon->connect_to->as_instance, FALSE);
    -        WRITE("<b>%+W</b> <i>%s</i>", NW, (scon->end==0)?"begins":"ends");
    -        if (scon->end >= 2) WRITE(" %+W", scon->connect_to->ends[scon->end].end_names);
    -        Index::link(OUT, Wordings::first_wn(Node::get_text(scon->where_said)));
    -        count++;
    -    }
    -
    - -

    §1.4.1.5. Index the rules which apply when this scene end occurs1.4.1.5 = -

    - -
    -    if (Rulebooks::is_empty(sc->ends[end].end_rulebook) == FALSE) {
    -        HTML::open_indented_p(OUT, 1, "hanging");
    -        WRITE("<i>What happens:</i>"); HTML_CLOSE("p");
    -        int ignore_me = 0;
    -        IXRules::index_rulebook(OUT, sc->ends[end].end_rulebook, "",
    -            IXRules::no_rule_context(), &ignore_me);
    -    }
    -
    - -

    §2. Table of Scenes. We finally return to the table of scenes. The following is recursive, and -is called at the top level for each scene in turn which starts at the start -of play (see above). -

    - -

    A scene entry can be arrived at in three ways: through one of its ends, in -which case end is the number (0 for begins, 1 for standard ends, and so on), -or through being already active at the start of play, or through being covered -in the index even though it never happens in play. This means we need two -additional end numbers. They are only ever used at the top level, that is, -on the initial call when depth is 0. -

    - -
    define START_OF_PLAY_END -1
    -define NEVER_HAPPENS_END -2
    -
    -
    -void IXScenes::index_from_scene(OUTPUT_STREAM, scene *sc, int depth,
    -    int end, scene *sc_from, scene **sorted, int nr) {
    -    HTML::open_indented_p(OUT, depth+1, "tight");
    -    Indicate the route by which this scene was reached2.1;
    -    Name the scene in the table, italicised if we've seen it already2.2;
    -    if (sc->indexed == FALSE) {
    -        Show the never-ends icon if appropriate2.3;
    -        Show the recurring icon if appropriate2.4;
    -    }
    -    HTML_CLOSE("p");
    -    if (sc->indexed) return;
    -    sc->indexed = TRUE;
    -    Indent to tabulate other scenes connected to the ends of this one2.5;
    -}
    -
    -

    §2.1. Indicate the route by which this scene was reached2.1 = -

    - -
    -    switch(end) {
    -        case 0: IXScenes::scene_icon(OUT, "Simul"); break;
    -        case 1: IXScenes::scene_icon(OUT, "Segue"); break;
    -        case START_OF_PLAY_END: break;
    -        case NEVER_HAPPENS_END: IXScenes::scene_icon(OUT, "WNever"); break;
    -        default:
    -            IXScenes::scene_icon(OUT, "Segue");
    -            WRITE("[ends %+W]&nbsp;", sc_from->ends[end].end_names); break;
    -    }
    -    if ((sc->indexed == FALSE) || (depth == 0)) {
    -        if (sc == SC_entire_game) IXScenes::scene_icon(OUT, "WPB");
    -        else if (sc->ends[0].anchor_condition) IXScenes::scene_icon(OUT, "WhenC");
    -        if (sc->start_of_play) IXScenes::scene_icon(OUT, "WPB");
    -    }
    -
    -
    • This code is used in §2.
    -

    §2.2. Name the scene in the table, italicised if we've seen it already2.2 = -

    - -
    -    if (sc->indexed) WRITE("<i>");
    -    WRITE("%+W", Instances::get_name(sc->as_instance, FALSE));
    -    if (sc->indexed) WRITE("</i>");
    -    else Index::below_link_numbered(OUT, sc->allocation_id);
    -
    -
    • This code is used in §2.
    -

    §2.3. Show the never-ends icon if appropriate2.3 = -

    - -
    -    int ways_to_end = 0;
    -    for (int e=1; e<sc->no_ends; e++) {
    -        if (sc->ends[e].anchor_connectors) ways_to_end++;
    -        if (sc->ends[e].anchor_condition) ways_to_end++;
    -    }
    -    if (ways_to_end == 0) IXScenes::scene_icon_append(OUT, "ENever");
    -
    -
    • This code is used in §2.
    -

    §2.4. Show the recurring icon if appropriate2.4 = -

    - -
    -    inference_subject *subj = Instances::as_subject(sc->as_instance);
    -    if (PropertyInferences::either_or_state(subj, P_recurring) > UNKNOWN_CE)
    -        IXScenes::scene_icon_append(OUT, "Recurring");
    -
    -
    • This code is used in §2.
    -

    §2.5. And this is where the routine recurses, so that consequent scenes are -tabulated underneath the present one, indented one step further in (since -indentation is coupled to depth). First we recurse to scenes which end when -this one does; then to scenes which begin when this one ends. -

    - -

    Indent to tabulate other scenes connected to the ends of this one2.5 = -

    - -
    -    for (int i=0; i<nr; i++) {
    -        scene *sc2 = sorted[i];
    -        scene_connector *scon;
    -        for (scon = sc2->ends[0].anchor_connectors; scon; scon=scon->next)
    -            if ((scon->connect_to == sc) && (scon->end >= 1))
    -                IXScenes::index_from_scene(OUT, sc2, depth + 1, scon->end, sc, sorted, nr);
    -    }
    -    for (int i=0; i<nr; i++) {
    -        scene *sc2 = sorted[i];
    -        scene_connector *scon;
    -        for (scon = sc2->ends[0].anchor_connectors; scon; scon=scon->next)
    -            if ((scon->connect_to == sc) && (scon->end == 0))
    -                IXScenes::index_from_scene(OUT, sc2, depth, scon->end, sc, sorted, nr);
    -    }
    -
    -
    • This code is used in §2.
    -

    §3. We have been using: -

    - -
    -void IXScenes::scene_icon(OUTPUT_STREAM, char *si) {
    -    IXScenes::scene_icon_unspaced(OUT, si); WRITE("&nbsp;&nbsp;");
    -}
    -
    -void IXScenes::scene_icon_append(OUTPUT_STREAM, char *si) {
    -    WRITE("&nbsp;&nbsp;"); IXScenes::scene_icon_unspaced(OUT, si);
    -}
    -
    -void IXScenes::scene_icon_legend(OUTPUT_STREAM, char *si, char *gloss) {
    -    IXScenes::scene_icon_unspaced(OUT, si); WRITE("&nbsp;<i>%s</i>", gloss);
    -}
    -
    -void IXScenes::scene_icon_unspaced(OUTPUT_STREAM, char *si) {
    -    HTML_TAG_WITH("img", "border=0 src=inform:/scene_icons/%s.png", si);
    -}
    -
    -

    §4. Lastly: the following is the criterion used for sorting the scenes into -their indexing order. The Entire Game always comes first, and then come the -rest in ascending alphabetical order. -

    - -
    -int IXScenes::compare_scenes(const void *ent1, const void *ent2) {
    -    const scene *sc1 = *((const scene **) ent1);
    -    const scene *sc2 = *((const scene **) ent2);
    -    if ((sc1 == SC_entire_game) && (sc2 != SC_entire_game)) return -1;
    -    if ((sc1 != SC_entire_game) && (sc2 == SC_entire_game)) return 1;
    -    wording SW1 = Instances::get_name(sc1->as_instance, FALSE);
    -    wording SW2 = Instances::get_name(sc2->as_instance, FALSE);
    -    return Wordings::strcmp(SW1, SW2);
    -}
    -
    - - -
    - - - diff --git a/docs/index-module/3-rgn.html b/docs/index-module/3-rgn.html index 08c649570..eb9adb969 100644 --- a/docs/index-module/3-rgn.html +++ b/docs/index-module/3-rgn.html @@ -76,7 +76,7 @@ } diff --git a/docs/index-module/3-spt.html b/docs/index-module/3-spt.html index bf347bf8c..c5f20fdd7 100644 --- a/docs/index-module/3-spt.html +++ b/docs/index-module/3-spt.html @@ -165,7 +165,7 @@ it already turns up under its owner. } diff --git a/docs/index-module/3-tm.html b/docs/index-module/3-tm.html index 7426b1404..e3392b4e6 100644 --- a/docs/index-module/3-tm.html +++ b/docs/index-module/3-tm.html @@ -96,7 +96,7 @@ } diff --git a/docs/index-module/3-tp.html b/docs/index-module/3-tp.html index 2c41804ec..a74cd1861 100644 --- a/docs/index-module/3-tp.html +++ b/docs/index-module/3-tp.html @@ -93,7 +93,7 @@ usually appear anywhere. } diff --git a/docs/index-module/index.html b/docs/index-module/index.html index 1a593df9c..e1b813d7a 100644 --- a/docs/index-module/index.html +++ b/docs/index-module/index.html @@ -128,11 +128,6 @@ Phrasebook Index
    - To compile most of the HTML page for the Phrasebook index.

    -
  • -

    - Arithmetic Element - - To index dimensional rules.

    -
  • @@ -164,11 +159,6 @@ The Map - Indexing the player's initial position.

  • -
  • -

    - Plot Element - - Parallel to the World index of space is the Scenes index of time, and in this section we render it as HTML.

    -
  • Actions - diff --git a/docs/runtime-module/2-ec.html b/docs/runtime-module/2-ec.html index dd6f4bc59..a749d40d3 100644 --- a/docs/runtime-module/2-ec.html +++ b/docs/runtime-module/2-ec.html @@ -108,10 +108,10 @@ instruction last emitted, not after it.

  • EmitCode::up then returns us back to where we were.
  • -void EmitCode::up(void) {
    +void EmitCode::up(void) {
         Produce::up(Emit::tree());
     }
    -void EmitCode::down(void) {
    +void EmitCode::down(void) {
         Produce::down(Emit::tree());
     }
     
    @@ -127,7 +127,7 @@ have made, net:

    §5. Structural.

    -void EmitCode::code(void) {
    +void EmitCode::code(void) {
         Produce::code(Emit::tree());
     }
     
    @@ -140,7 +140,7 @@ start of a function.
     

    -void EmitCode::comment(text_stream *text) {
    +void EmitCode::comment(text_stream *text) {
         if (Functions::a_function_is_being_compiled() == FALSE)
             internal_error("code comment emitted outside function");
         inter_ti ID = Inter::Warehouse::create_text(Emit::warehouse(), Emit::package());
    @@ -153,7 +153,7 @@ start of a function.
     

    -void EmitCode::val_number(inter_ti N) {
    +void EmitCode::val_number(inter_ti N) {
         Produce::val(Emit::tree(), K_number, LITERAL_IVAL, N);
     }
     
    @@ -165,11 +165,11 @@ start of a function.
         Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 0);
     }
     
    -void EmitCode::val_iname(kind *K, inter_name *iname) {
    +void EmitCode::val_iname(kind *K, inter_name *iname) {
         Produce::val_iname(Emit::tree(), K, iname);
     }
     
    -void EmitCode::val_text(text_stream *text) {
    +void EmitCode::val_text(text_stream *text) {
         Produce::val_text(Emit::tree(), text);
     }
     
    @@ -185,7 +185,7 @@ start of a function.
         Produce::val_nothing(Emit::tree());
     }
     
    -void EmitCode::val_symbol(kind *K, inter_symbol *S) {
    +void EmitCode::val_symbol(kind *K, inter_symbol *S) {
         Produce::val_symbol(Emit::tree(), K, S);
     }
     
    @@ -255,7 +255,7 @@ this can be achieved with an Inter -void EmitCode::cast(kind *F, kind *T) { +void EmitCode::cast(kind *F, kind *T) { Produce::cast(Emit::tree(), F, T); }
    @@ -322,11 +322,11 @@ in such cases, this function must exist in the kits somewhere.

    -void EmitCode::inv(inter_ti bip) {
    +void EmitCode::inv(inter_ti bip) {
         Produce::inv_primitive(Emit::tree(), bip);
     }
     
    -void EmitCode::call(inter_name *fn_iname) {
    +void EmitCode::call(inter_name *fn_iname) {
         Produce::inv_call_iname(Emit::tree(), fn_iname);
     }
     
    diff --git a/docs/runtime-module/2-hrr.html b/docs/runtime-module/2-hrr.html
    index d12571141..000ceedc4 100644
    --- a/docs/runtime-module/2-hrr.html
    +++ b/docs/runtime-module/2-hrr.html
    @@ -953,6 +953,11 @@ that the compiler can refer to it.
     enum INSTANCE_INDEX_KIND_MD_HL
     enum INSTANCE_IS_OBJECT_MD_HL
     enum INSTANCE_IS_SCENE_MD_HL
    +enum INSTANCE_IS_ENTIRE_GAME_MD_HL
    +enum INSTANCE_SCENE_STARTS_MD_HL
    +enum INSTANCE_SCENE_STARTS_ON_CONDITION_MD_HL
    +enum INSTANCE_SCENE_RECURS_MD_HL
    +enum INSTANCE_SCENE_NEVER_ENDS_MD_HL
     enum INSTANCE_IS_EXF_MD_HL
     enum INSTANCE_FILE_VALUE_MD_HL
     enum INSTANCE_FILE_IS_BINARY_MD_HL
    @@ -968,6 +973,15 @@ that the compiler can refer to it.
     enum INSTANCE_SOUND_ID_MD_HL
     enum INSTANCE_SSF_MD_HL
     enum INSTANCE_SCF_MD_HL
    +enum SCENE_ENDS_HAP
    +enum SCENE_END_NAME_MD_HL
    +enum SCENE_END_AT_MD_HL
    +enum SCENE_END_CONDITION_MD_HL
    +enum SCENE_END_RULEBOOK_MD_HL
    +enum SCENE_CONNECTORS_HAP
    +enum SCENE_CONNECTOR_TO_MD_HL
    +enum SCENE_CONNECTOR_END_MD_HL
    +enum SCENE_CONNECTOR_AT_MD_HL
     enum INST_SHOWME_MD_HL
     enum INST_SHOWME_FN_HL
     enum INSTANCE_HL
    @@ -998,8 +1012,24 @@ that the compiler can refer to it.
                 H_C_U(INSTANCE_INDEX_KIND_MD_HL,  I"^index_kind")
                 H_C_U(INSTANCE_IS_OBJECT_MD_HL, I"^is_object")
                 H_C_U(INSTANCE_IS_SCENE_MD_HL, I"^is_scene")
    +            H_C_U(INSTANCE_IS_ENTIRE_GAME_MD_HL, I"^is_entire_game")
    +            H_C_U(INSTANCE_SCENE_STARTS_MD_HL, I"^starts")
    +            H_C_U(INSTANCE_SCENE_STARTS_ON_CONDITION_MD_HL, I"^starts_on_condition")
    +            H_C_U(INSTANCE_SCENE_RECURS_MD_HL, I"^recurs")
    +            H_C_U(INSTANCE_SCENE_NEVER_ENDS_MD_HL, I"^never_ends")
                 H_C_U(INSTANCE_SSF_MD_HL,   I"^scene_status_fn")
                 H_C_U(INSTANCE_SCF_MD_HL,   I"^scene_change_fn")
    +            H_BEGIN_AP(SCENE_ENDS_HAP, I"scene_end", I"_scene_end")
    +                H_C_U(SCENE_END_NAME_MD_HL,     I"^name")
    +                H_C_U(SCENE_END_AT_MD_HL,     I"^at")
    +                H_C_U(SCENE_END_CONDITION_MD_HL,     I"^condition")
    +                H_C_U(SCENE_END_RULEBOOK_MD_HL,     I"^rulebook")
    +                H_BEGIN_AP(SCENE_CONNECTORS_HAP, I"scene_connector", I"_scene_connector")
    +                    H_C_U(SCENE_CONNECTOR_TO_MD_HL,     I"^to")
    +                    H_C_U(SCENE_CONNECTOR_END_MD_HL,     I"^end")
    +                    H_C_U(SCENE_CONNECTOR_AT_MD_HL,     I"^at")
    +                H_END
    +            H_END
                 H_C_U(INSTANCE_IS_EXF_MD_HL, I"^is_file")
                 H_C_U(INSTANCE_FILE_VALUE_MD_HL, I"^file_value")
                 H_C_U(INSTANCE_FILE_OWNED_MD_HL, I"^file_owned")
    @@ -1090,6 +1120,9 @@ that the compiler can refer to it.
     enum KIND_DSIZE_MD_HL
     enum KIND_DOCUMENTATION_MD_HL
     enum RUCKSACK_CLASS_MD_HL
    +enum MIN_VAL_INDEX_MD_HL
    +enum MAX_VAL_INDEX_MD_HL
    +enum DIMENSIONS_INDEX_MD_HL
     enum WEAK_ID_HL
     enum ICOUNT_HL
     enum ILIST_HL
    @@ -1127,6 +1160,14 @@ that the compiler can refer to it.
     enum DK_DEFAULT_VALUE_HL
     enum KIND_USAGE_HAP
     enum KIND_CLASS_HL
    +enum MULTIPLICATION_RULE_HAP
    +enum SET_AT_MD_HL
    +enum LEFT_OPERAND_MD_HL
    +enum RIGHT_OPERAND_MD_HL
    +enum RESULT_MD_HL
    +enum LEFT_OPERAND_BM_MD_HL
    +enum RIGHT_OPERAND_BM_MD_HL
    +enum RESULT_BM_MD_HL
     

    §8.1.28. Establish kinds8.1.28 =

    @@ -1161,6 +1202,9 @@ that the compiler can refer to it. H_C_U(KIND_MKDEF_FN_MD_HL, I"^mkdef_fn") H_C_U(KIND_DSIZE_MD_HL, I"^domain_size") H_C_U(RUCKSACK_CLASS_MD_HL, I"^rucksack_class") + H_C_U(MIN_VAL_INDEX_MD_HL, I"^min_value") + H_C_U(MAX_VAL_INDEX_MD_HL, I"^max_value") + H_C_U(DIMENSIONS_INDEX_MD_HL, I"^dimensions") H_C_U(KIND_DOCUMENTATION_MD_HL, I"^documentation") H_C_I(WEAK_ID_HL) H_C_I(ICOUNT_HL) @@ -1195,7 +1239,7 @@ that the compiler can refer to it. H_END H_END H_BEGIN_AP(DERIVED_KIND_HAP, I"derived_kind", I"_derived_kind") - H_C_U(DK_NEEDED_MD_HL, I"^default_value_needed") + H_C_U(DK_NEEDED_MD_HL, I"^default_value_needed") H_C_U(DK_STRONG_ID_HL, I"strong_id") H_C_G(DK_KIND_HL, I"DK") H_C_U(DK_DEFAULT_VALUE_HL, I"default_value") @@ -1207,6 +1251,15 @@ that the compiler can refer to it. H_BEGIN(HierarchyLocations::completion_submodule(I, kinds)) H_BEGIN_AP(KIND_USAGE_HAP, I"kind_usage", I"_kind_usage") H_END + H_BEGIN_AP(MULTIPLICATION_RULE_HAP, I"multiplication_rule", I"_multiplication_rule") + H_C_U(SET_AT_MD_HL, I"^at") + H_C_U(LEFT_OPERAND_MD_HL, I"^left_operand") + H_C_U(RIGHT_OPERAND_MD_HL, I"^right_operand") + H_C_U(RESULT_MD_HL, I"^result") + H_C_U(LEFT_OPERAND_BM_MD_HL, I"^left_operand_benchmark") + H_C_U(RIGHT_OPERAND_BM_MD_HL, I"^right_operand_benchmark") + H_C_U(RESULT_BM_MD_HL, I"^result_benchmark") + H_END H_END
    @@ -1912,7 +1965,7 @@ at which this array should be placed, by calling, e.g.,
    -inter_name *Hierarchy::find(int id) {
    +inter_name *Hierarchy::find(int id) {
         return HierarchyLocations::find(Emit::tree(), id);
     }
     
    @@ -2055,7 +2108,7 @@ compilation unit is meant: that's why it's "synoptic". return HierarchyLocations::attach_new_package(Emit::tree(), NULL, NULL, hap_id); } -package_request *Hierarchy::completion_package(int hap_id) { +package_request *Hierarchy::completion_package(int hap_id) { return HierarchyLocations::attach_new_package(Emit::tree(), NULL, NULL, hap_id); } @@ -2078,7 +2131,7 @@ will automatically trip, in order to enforce the layout rules.

    -package_request *Hierarchy::package_within(int hap_id, package_request *super) {
    +package_request *Hierarchy::package_within(int hap_id, package_request *super) {
         return HierarchyLocations::attach_new_package(Emit::tree(), NULL, super, hap_id);
     }
     
    @@ -2095,17 +2148,17 @@ point system, and for those:

    -void Hierarchy::apply_metadata(package_request *P, int id, text_stream *value) {
    +void Hierarchy::apply_metadata(package_request *P, int id, text_stream *value) {
         inter_name *iname = Hierarchy::make_iname_in(id, P);
         Emit::text_constant(iname, value);
     }
     
    -void Hierarchy::apply_metadata_from_number(package_request *P, int id, inter_ti N) {
    +void Hierarchy::apply_metadata_from_number(package_request *P, int id, inter_ti N) {
         inter_name *iname = Hierarchy::make_iname_in(id, P);
         Emit::numeric_constant(iname, N);
     }
     
    -void Hierarchy::apply_metadata_from_iname(package_request *P, int id, inter_name *val) {
    +void Hierarchy::apply_metadata_from_iname(package_request *P, int id, inter_name *val) {
         inter_name *iname = Hierarchy::make_iname_in(id, P);
         Emit::iname_constant(iname, K_value, val);
     }
    @@ -2117,7 +2170,7 @@ point system, and for those:
         DISCARD_TEXT(ANT)
     }
     
    -void Hierarchy::apply_metadata_from_raw_wording(package_request *P, int id, wording W) {
    +void Hierarchy::apply_metadata_from_raw_wording(package_request *P, int id, wording W) {
         TEMPORARY_TEXT(ANT)
         WRITE_TO(ANT, "%+W", W);
         Hierarchy::apply_metadata(P, id, ANT);
    diff --git a/docs/runtime-module/2-kd.html b/docs/runtime-module/2-kd.html
    index daab9f085..0762783aa 100644
    --- a/docs/runtime-module/2-kd.html
    +++ b/docs/runtime-module/2-kd.html
    @@ -78,7 +78,7 @@ function togglePopup(material_id) {
     

    -int RTKindDeclarations::base_represented_in_Inter(kind *K) {
    +int RTKindDeclarations::base_represented_in_Inter(kind *K) {
         if ((Kinds::Behaviour::is_kind_of_kind(K) == FALSE) &&
             (Kinds::is_proper_constructor(K) == FALSE) &&
             (K != K_void) &&
    diff --git a/docs/runtime-module/5-ins.html b/docs/runtime-module/5-ins.html
    index fcee519cf..84ca490ff 100644
    --- a/docs/runtime-module/5-ins.html
    +++ b/docs/runtime-module/5-ins.html
    @@ -95,12 +95,12 @@ function togglePopup(material_id) {
         return icd;
     }
     
    -inter_name *RTInstances::value_iname(instance *I) {
    +inter_name *RTInstances::value_iname(instance *I) {
         if (I == NULL) return NULL;
         return I->compilation_data.instance_iname;
     }
     
    -package_request *RTInstances::package(instance *I) {
    +package_request *RTInstances::package(instance *I) {
         return I->compilation_data.instance_package;
     }
     
    @@ -166,9 +166,6 @@ using Inter's INSTANCE_IST if (Kinds::Behaviour::is_subkind_of_object(K)) Hierarchy::apply_metadata_from_number(pack, INSTANCE_IS_OBJECT_MD_HL, 1); - if ((K_scene) && (Kinds::eq(K, K_scene))) - Hierarchy::apply_metadata_from_number(pack, - INSTANCE_IS_SCENE_MD_HL, 1); if ((K_sound_name) && (Kinds::eq(K, K_sound_name))) Hierarchy::apply_metadata_from_number(pack, INSTANCE_IS_SOUND_MD_HL, 1); diff --git a/docs/runtime-module/5-kc.html b/docs/runtime-module/5-kc.html index 5689dd92c..f21e2e49a 100644 --- a/docs/runtime-module/5-kc.html +++ b/docs/runtime-module/5-kc.html @@ -266,7 +266,7 @@ of the kind which the constructor makes:

    §4.

    -inter_name *RTKindConstructors::get_iname(kind *K) {
    +inter_name *RTKindConstructors::get_iname(kind *K) {
         if (K == NULL) {
             if (K_number) return RTKindConstructors::get_iname(K_number);
             internal_error("null kind has no printing routine");
    @@ -352,21 +352,21 @@ of the kind which the constructor makes:
     package_request *RTKindConstructors::kind_package(kind *K) {
         return RTKindConstructors::package(K->construct);
     }
    -inter_name *RTKindConstructors::get_inc_iname(kind *K) {
    +inter_name *RTKindConstructors::get_inc_iname(kind *K) {
         if (K == NULL) internal_error("null kind has no inc routine");
         if (K->construct->compilation_data.inc_iname) return K->construct->compilation_data.inc_iname;
         package_request *R = RTKindConstructors::kind_package(K);
         K->construct->compilation_data.inc_iname = Hierarchy::make_iname_in(DECREMENT_FN_HL, R);
         return K->construct->compilation_data.inc_iname;
     }
    -inter_name *RTKindConstructors::get_dec_iname(kind *K) {
    +inter_name *RTKindConstructors::get_dec_iname(kind *K) {
         if (K == NULL) internal_error("null kind has no dec routine");
         if (K->construct->compilation_data.dec_iname) return K->construct->compilation_data.dec_iname;
         package_request *R = RTKindConstructors::kind_package(K);
         K->construct->compilation_data.dec_iname = Hierarchy::make_iname_in(INCREMENT_FN_HL, R);
         return K->construct->compilation_data.dec_iname;
     }
    -inter_name *RTKindConstructors::get_ranger_iname(kind *K) {
    +inter_name *RTKindConstructors::get_ranger_iname(kind *K) {
         if (K == NULL) internal_error("null kind has no ranger fn");
         if (K->construct->compilation_data.ranger_iname) return K->construct->compilation_data.ranger_iname;
         package_request *R = RTKindConstructors::kind_package(K);
    @@ -490,7 +490,7 @@ parsing names of objects, but not as a grammar token in its own right.
     

    -int RTKindConstructors::get_highest_valid_value_as_integer(kind *K) {
    +int RTKindConstructors::get_highest_valid_value_as_integer(kind *K) {
         if (K == NULL) return 0;
         return RTKindConstructors::get_highest_valid_value_as_integer_kc(K->construct);
     }
    @@ -522,7 +522,7 @@ parsing names of objects, but not as a grammar token in its own right.
     }
     
     void RTKindConstructors::compile(void) {
    -    RTKindConstructors::assign_declaration_sequence_numbers();
    +    RTKindConstructors::assign_declaration_sequence_numbers();
         kind_constructor *kc;
         LOOP_OVER(kc, kind_constructor) {
             if ((kc == CON_KIND_VARIABLE) || (kc == CON_INTERMEDIATE)) continue;
    @@ -672,22 +672,112 @@ parsing names of objects, but not as a grammar token in its own right.
             if (Kinds::eq(K, K_players_holdall))
                 Hierarchy::apply_metadata_from_number(pack, RUCKSACK_CLASS_MD_HL, 1);
     
    -        Compile data support functions10.3;
    +        Compile data support functions10.7;
     
             if (kc->compilation_data.declaration_sequence_number >= 0)
                 Produce::annotate_i(RTKindDeclarations::iname(K), DECLARATION_ORDER_IANN,
                     (inter_ti) kc->compilation_data.declaration_sequence_number);
    +
    +        if ((Kinds::Behaviour::is_quasinumerical(K)) && (Kinds::is_intermediate(K) == FALSE)) {
    +            TEMPORARY_TEXT(OUT)
    +            Index the minimum positive value for a quasinumerical kind10.1;
    +            Hierarchy::apply_metadata(pack, MIN_VAL_INDEX_MD_HL, OUT);
    +            Str::clear(OUT);
    +            Index the maximum positive value for a quasinumerical kind10.2;
    +            Hierarchy::apply_metadata(pack, MAX_VAL_INDEX_MD_HL, OUT);
    +            Str::clear(OUT);
    +            Index the dimensions for a quasinumerical kind10.3;
    +            Hierarchy::apply_metadata(pack, DIMENSIONS_INDEX_MD_HL, OUT);
    +            DISCARD_TEXT(OUT)
    +        }
    +
         }
    +    Compile multiplication rules for the index10.4;
     }
     
    -

    §10.1.

    +

    §10.1. Index the minimum positive value for a quasinumerical kind10.1 = +

    + +
    +    if (Kinds::eq(K, K_number)) WRITE("1");
    +    else {
    +        text_stream *p = Kinds::Behaviour::get_index_minimum_value(K);
    +        if (Str::len(p) > 0) WRITE("%S", p);
    +        else LiteralPatterns::index_value(OUT,
    +            LiteralPatterns::list_of_literal_forms(K), 1);
    +    }
    +
    +
    • This code is used in §10.
    +

    §10.2. Index the maximum positive value for a quasinumerical kind10.2 = +

    + +
    +    if (Kinds::eq(K, K_number)) {
    +        if (TargetVMs::is_16_bit(Task::vm())) WRITE("32767");
    +        else WRITE("2147483647");
    +    } else {
    +        text_stream *p = Kinds::Behaviour::get_index_maximum_value(K);
    +        if (Str::len(p) > 0) WRITE("%S", p);
    +        else {
    +            if (TargetVMs::is_16_bit(Task::vm()))
    +                LiteralPatterns::index_value(OUT,
    +                    LiteralPatterns::list_of_literal_forms(K), 32767);
    +            else
    +                LiteralPatterns::index_value(OUT,
    +                    LiteralPatterns::list_of_literal_forms(K), 2147483647);
    +        }
    +    }
    +
    +
    • This code is used in §10.
    +

    §10.3. Index the dimensions for a quasinumerical kind10.3 = +

    + +
    +    if (Kinds::Dimensions::dimensionless(K) == FALSE) {
    +        unit_sequence *deriv = Kinds::Behaviour::get_dimensional_form(K);
    +        Kinds::Dimensions::index_unit_sequence(OUT, deriv, TRUE);
    +    }
    +
    +
    • This code is used in §10.
    +

    §10.4. Compile multiplication rules for the index10.4 = +

    + +
    +    kind *L, *R, *O;
    +    int wn;
    +    LOOP_OVER_MULTIPLICATIONS(L, R, O, wn) {
    +        package_request *pack = Hierarchy::completion_package(MULTIPLICATION_RULE_HAP);
    +        if (wn >= 0) Hierarchy::apply_metadata_from_number(pack, SET_AT_MD_HL, (inter_ti) wn);
    +        TEMPORARY_TEXT(OUT)
    +        WRITE_TO(OUT, "%u", L);
    +        Hierarchy::apply_metadata(pack, LEFT_OPERAND_MD_HL, OUT);
    +        Str::clear(OUT);
    +        WRITE_TO(OUT, "%u", R);
    +        Hierarchy::apply_metadata(pack, RIGHT_OPERAND_MD_HL, OUT);
    +        Str::clear(OUT);
    +        WRITE_TO(OUT, "%u", O);
    +        Hierarchy::apply_metadata(pack, RESULT_MD_HL, OUT);
    +        Str::clear(OUT);
    +        LiteralPatterns::index_benchmark_value(OUT, L);
    +        Hierarchy::apply_metadata(pack, LEFT_OPERAND_BM_MD_HL, OUT);
    +        Str::clear(OUT);
    +        LiteralPatterns::index_benchmark_value(OUT, R);
    +        Hierarchy::apply_metadata(pack, RIGHT_OPERAND_BM_MD_HL, OUT);
    +        Str::clear(OUT);
    +        LiteralPatterns::index_benchmark_value(OUT, O);
    +        Hierarchy::apply_metadata(pack, RESULT_BM_MD_HL, OUT);
    +        DISCARD_TEXT(OUT)
    +    }
    +
    +
    • This code is used in §10.
    +

    §10.5.

     inter_ti kind_sequence_counter = 0;
     
     void RTKindConstructors::assign_declaration_sequence_numbers(void) {
         int N = 0;
    -    RTKindConstructors::assign_dsn_r(&N, KindSubjects::from_kind(K_object));
    +    RTKindConstructors::assign_dsn_r(&N, KindSubjects::from_kind(K_object));
         kind_constructor *kc;
         LOOP_OVER(kc, kind_constructor) {
             if ((kc == CON_KIND_VARIABLE) || (kc == CON_INTERMEDIATE)) continue;
    @@ -706,10 +796,10 @@ parsing names of objects, but not as a grammar token in its own right.
         LOOP_OVER(subj, inference_subject)
             if ((InferenceSubjects::narrowest_broader_subject(subj) == within) &&
                 (InferenceSubjects::is_a_kind_of_object(subj)))
    -            RTKindConstructors::assign_dsn_r(N, subj);
    +            RTKindConstructors::assign_dsn_r(N, subj);
     }
     
    -

    §10.2.

    +

    §10.6.

     void RTKindConstructors::compile_permissions(void) {
    @@ -724,15 +814,15 @@ parsing names of objects, but not as a grammar token in its own right.
         }
     }
     
    -

    §10.3. Compile data support functions10.3 = +

    §10.7. Compile data support functions10.7 =

         if (Kinds::Behaviour::is_an_enumeration(K)) {
             inter_name *printing_rule_name = RTKindConstructors::get_iname(K);
    -        Compile I6 printing routine for an enumerated kind10.3.3;
    -        Compile the A and B routines for an enumerated kind10.3.4;
    -        Compile random-ranger routine for this kind10.3.5;
    +        Compile I6 printing routine for an enumerated kind10.7.3;
    +        Compile the A and B routines for an enumerated kind10.7.4;
    +        Compile random-ranger routine for this kind10.7.5;
         }
         if ((Kinds::Behaviour::is_built_in(K) == FALSE) &&
             (Kinds::Behaviour::is_subkind_of_object(K) == FALSE) &&
    @@ -772,21 +862,21 @@ parsing names of objects, but not as a grammar token in its own right.
             }
             inter_name *printing_rule_name = RTKindConstructors::get_iname(K);
             if (Kinds::Behaviour::is_quasinumerical(K)) {
    -            Compile I6 printing routine for a unit kind10.3.2;
    -            Compile random-ranger routine for this kind10.3.5;
    +            Compile I6 printing routine for a unit kind10.7.2;
    +            Compile random-ranger routine for this kind10.7.5;
             } else {
    -            Compile I6 printing routine for a vacant but named kind10.3.1;
    +            Compile I6 printing routine for a vacant but named kind10.7.1;
             }
         }
     
    • This code is used in §10.
    -

    §10.3.1. A slightly bogus case first. If the source text declares a kind but never +

    §10.7.1. A slightly bogus case first. If the source text declares a kind but never gives any enumerated values or literal patterns, then such values will never appear at run-time; but we need the printing routine to exist to avoid compilation errors.

    -

    Compile I6 printing routine for a vacant but named kind10.3.1 = +

    Compile I6 printing routine for a vacant but named kind10.7.1 =

    @@ -802,13 +892,13 @@ compilation errors.
         EmitCode::up();
         Functions::end(save);
     
    - -

    §10.3.2. A unit is printed back with its earliest-defined literal pattern used as +

    +

    §10.7.2. A unit is printed back with its earliest-defined literal pattern used as notation. If it had no literal patterns, it would come out as decimal numbers, but at present this can't happen.

    -

    Compile I6 printing routine for a unit kind10.3.2 = +

    Compile I6 printing routine for a unit kind10.7.2 =

    @@ -825,8 +915,8 @@ but at present this can't happen.
             Functions::end(save);
         }
     
    - -

    §10.3.3. Compile I6 printing routine for an enumerated kind10.3.3 = +

    +

    §10.7.3. Compile I6 printing routine for an enumerated kind10.7.3 =

    @@ -881,8 +971,8 @@ but at present this can't happen.
     
         Functions::end(save);
     
    - -

    §10.3.4. The suite of standard routines provided for enumerative types is a little +

    +

    §10.7.4. The suite of standard routines provided for enumerative types is a little like the one in Ada (T'Succ, T'Pred, and so on).

    @@ -895,7 +985,7 @@ wrapping around to the first from the last; wrapping around to the last from the first, so that it is the inverse function to A_T1_colour(v). -

    Compile the A and B routines for an enumerated kind10.3.4 = +

    Compile the A and B routines for an enumerated kind10.7.4 =

    @@ -905,20 +995,20 @@ to A_T1_colour(v)    inter_name *iname_i = RTKindConstructors::get_inc_iname(K);
         packaging_state save = Functions::begin(iname_i);
    -    Implement the A routine10.3.4.1;
    +    Implement the A routine10.7.4.1;
         Functions::end(save);
     
         inter_name *iname_d = RTKindConstructors::get_dec_iname(K);
         save = Functions::begin(iname_d);
    -    Implement the B routine10.3.4.2;
    +    Implement the B routine10.7.4.2;
         Functions::end(save);
     
    - -

    §10.3.4.1. There should be a blue historical plaque on the wall here: this was the +

    +

    §10.7.4.1. There should be a blue historical plaque on the wall here: this was the first function ever implemented by emitting Inter code, on 12 November 2017.

    -

    Implement the A routine10.3.4.1 = +

    Implement the A routine10.7.4.1 =

    @@ -951,11 +1041,11 @@ first function ever implemented by emitting Inter code, on 12 November 2017.
     
         EmitCode::up();
     
    - -

    §10.3.4.2. And this was the second, a few minutes later. +

    +

    §10.7.4.2. And this was the second, a few minutes later.

    -

    Implement the B routine10.3.4.2 = +

    Implement the B routine10.7.4.2 =

    @@ -1001,8 +1091,8 @@ first function ever implemented by emitting Inter code, on 12 November 2017.
     
         EmitCode::up();
     
    - -

    §10.3.5. And here we add: +

    +

    §10.7.5. And here we add:

    • (a) R_T1_colour() returns a uniformly random choice of the valid @@ -1011,7 +1101,7 @@ value, which will probably not be useful.)
    • (b) R_T1_colour(a, b) returns a uniformly random choice in between a and b inclusive.
    -

    Compile random-ranger routine for this kind10.3.5 = +

    Compile random-ranger routine for this kind10.7.5 =

    @@ -1080,7 +1170,7 @@ and b inclusive
                 EmitCode::inv(RETURN_BIP);
                 EmitCode::down();
                     smaller = b_s; larger = a_s;
    -                Formula for range10.3.5.1;
    +                Formula for range10.7.5.1;
                 EmitCode::up();
             EmitCode::up();
         EmitCode::up();
    @@ -1088,13 +1178,13 @@ and b inclusive
         EmitCode::inv(RETURN_BIP);
         EmitCode::down();
             smaller = a_s; larger = b_s;
    -        Formula for range10.3.5.1;
    +        Formula for range10.7.5.1;
         EmitCode::up();
     
         Functions::end(save);
     
    -
    • This code is used in §10.3 (twice).
    -

    §10.3.5.1. Formula for range10.3.5.1 = +

    • This code is used in §10.7 (twice).
    +

    §10.7.5.1. Formula for range10.7.5.1 =

    @@ -1119,7 +1209,7 @@ and b inclusive
             EmitCode::up();
         EmitCode::up();
     
    - + diff --git a/docs/runtime-module/5-ki.html b/docs/runtime-module/5-ki.html index 1e41ef723..d28b7134c 100644 --- a/docs/runtime-module/5-ki.html +++ b/docs/runtime-module/5-ki.html @@ -132,7 +132,7 @@ like variables. That's what makes them intermediate.) return invented; } -inter_name *RTKindIDs::weak_iname(kind *K) { +inter_name *RTKindIDs::weak_iname(kind *K) { if (K == NULL) { return RTKindConstructors::UNKNOWN_iname(); } if (Kinds::Behaviour::is_subkind_of_object(K)) K = K_object; kind_constructor *con = Kinds::get_construct(K); diff --git a/docs/runtime-module/5-lp.html b/docs/runtime-module/5-lp.html index 1f264f13a..5397e4c4d 100644 --- a/docs/runtime-module/5-lp.html +++ b/docs/runtime-module/5-lp.html @@ -1474,7 +1474,7 @@ sets the parsed_number

    §5. Printing the I6 variable |value| out in an LP's notation at run-time.

    -void RTLiteralPatterns::printing_routine(inter_name *iname, literal_pattern *lp_list) {
    +void RTLiteralPatterns::printing_routine(inter_name *iname, literal_pattern *lp_list) {
         packaging_state save = Functions::begin(iname);
     
         literal_pattern_name *lpn;
    diff --git a/docs/runtime-module/5-rlb.html b/docs/runtime-module/5-rlb.html
    index 208bdb8da..b4cfb6e2c 100644
    --- a/docs/runtime-module/5-rlb.html
    +++ b/docs/runtime-module/5-rlb.html
    @@ -114,7 +114,7 @@ determined at the linking stage.
     

    -inter_name *RTRulebooks::id_iname(rulebook *B) {
    +inter_name *RTRulebooks::id_iname(rulebook *B) {
         if (B->compilation_data.rb_id_iname == NULL)
             B->compilation_data.rb_id_iname =
                 Hierarchy::make_iname_in(RULEBOOK_ID_HL, RTRulebooks::package(B));
    @@ -229,7 +229,7 @@ rulebook:
             Hierarchy::apply_metadata_from_raw_wording(EP, RULE_INDEX_NAME_MD_HL,
                 R->indexing_data.italicised_text);
             if (R->defn_as_I7_source) {
    -            parse_node *pn = R->defn_as_I7_source->at->down;
    +            parse_node *pn = R->defn_as_I7_source->at->down->down;
                 if ((pn) && (Wordings::nonempty(Node::get_text(pn)))) {
                     TEMPORARY_TEXT(OUT)
                     WRITE("%+W", Node::get_text(pn));
    diff --git a/docs/runtime-module/5-si.html b/docs/runtime-module/5-si.html
    index 865b7c766..0ddcdb13f 100644
    --- a/docs/runtime-module/5-si.html
    +++ b/docs/runtime-module/5-si.html
    @@ -82,13 +82,50 @@ the current locationvoid RTScenes::compile_extra(instance *I) {
         if ((K_scene) && (Instances::of_kind(I, K_scene))) {
             scene *sc = Scenes::from_named_constant(I);
    -        if (sc == NULL) internal_error("sceneless");
    +        package_request *pack = RTInstances::package(I);
    +        Hierarchy::apply_metadata_from_number(pack, INSTANCE_IS_SCENE_MD_HL, 1);
    +        if (Scenes::is_entire_game(I))
    +            Hierarchy::apply_metadata_from_number(pack,
    +                INSTANCE_IS_ENTIRE_GAME_MD_HL, 1);
    +        if (sc->start_of_play)
    +            Hierarchy::apply_metadata_from_number(pack,
    +                INSTANCE_SCENE_STARTS_MD_HL, 1);
    +        else if (sc->ends[0].anchor_condition)
    +            Hierarchy::apply_metadata_from_number(pack,
    +                INSTANCE_SCENE_STARTS_ON_CONDITION_MD_HL, 1);
    +        inference_subject *subj = Instances::as_subject(sc->as_instance);
    +        if (PropertyInferences::either_or_state(subj, P_recurring) > UNKNOWN_CE)
    +            Hierarchy::apply_metadata_from_number(pack,
    +                INSTANCE_SCENE_RECURS_MD_HL, 1);
    +        int ways_to_end = 0;
    +        for (int e=1; e<sc->no_ends; e++) {
    +            if (sc->ends[e].anchor_connectors) ways_to_end++;
    +            if (sc->ends[e].anchor_condition) ways_to_end++;
    +        }
    +        if (ways_to_end == 0)
    +            Hierarchy::apply_metadata_from_number(pack,
    +                INSTANCE_SCENE_NEVER_ENDS_MD_HL, 1);
    +
             text_stream *desc = Str::new();
             WRITE_TO(desc, "scene change fn for "); Instances::write(desc, I);
             Sequence::queue(&RTScenes::change_compilation_agent, STORE_POINTER_scene(sc), desc);
             text_stream *desc2 = Str::new();
             WRITE_TO(desc2, "scene status fn for "); Instances::write(desc, I);
             Sequence::queue(&RTScenes::status_compilation_agent, STORE_POINTER_scene(sc), desc2);
    +
    +        for (int e=0; e<sc->no_ends; e++) {
    +            package_request *EP = Hierarchy::package_within(SCENE_ENDS_HAP, pack);
    +            Hierarchy::apply_metadata_from_raw_wording(EP, SCENE_END_NAME_MD_HL, sc->ends[e].end_names);
    +            Hierarchy::apply_metadata_from_number(EP, SCENE_END_AT_MD_HL, (inter_ti) Wordings::first_wn(Node::get_text(sc->ends[e].anchor_condition_set)));
    +            Hierarchy::apply_metadata_from_raw_wording(EP, SCENE_END_CONDITION_MD_HL, Node::get_text(sc->ends[e].anchor_condition));
    +            Hierarchy::apply_metadata_from_iname(EP, SCENE_END_RULEBOOK_MD_HL, RTRulebooks::id_iname(sc->ends[e].end_rulebook));
    +            for (scene_connector *scon = sc->ends[e].anchor_connectors; scon; scon=scon->next) {
    +                package_request *CP = Hierarchy::package_within(SCENE_CONNECTORS_HAP, EP);
    +                Hierarchy::apply_metadata_from_iname(CP, SCENE_CONNECTOR_TO_MD_HL, RTInstances::value_iname(scon->connect_to->as_instance));
    +                Hierarchy::apply_metadata_from_number(CP, SCENE_CONNECTOR_END_MD_HL, (inter_ti) scon->end);
    +                Hierarchy::apply_metadata_from_number(CP, SCENE_CONNECTOR_AT_MD_HL, (inter_ti) Wordings::first_wn(Node::get_text(scon->where_said)));
    +            }
    +        }
         }
     }
     
    diff --git a/docs/runtime-module/6-pp.html b/docs/runtime-module/6-pp.html index c88de3ab2..4c4d095c1 100644 --- a/docs/runtime-module/6-pp.html +++ b/docs/runtime-module/6-pp.html @@ -100,7 +100,7 @@ function togglePopup(material_id) {

    -void RTPropertyPermissions::emit_kind_permissions(kind *K) {
    +void RTPropertyPermissions::emit_kind_permissions(kind *K) {
         inference_subject *subj = KindSubjects::from_kind(K);
         int c = 0;
         property_permission *pp;
    diff --git a/docs/runtime-module/6-pv.html b/docs/runtime-module/6-pv.html
    index 4a0978511..5a8b7a58f 100644
    --- a/docs/runtime-module/6-pv.html
    +++ b/docs/runtime-module/6-pv.html
    @@ -82,7 +82,7 @@ function togglePopup(material_id) {
         RTPropertyValues::emit_subject(Instances::as_subject(I));
     }
     
    -void RTPropertyValues::compile_values_for_kind(kind *K) {
    +void RTPropertyValues::compile_values_for_kind(kind *K) {
         RTPropertyValues::emit_subject(KindSubjects::from_kind(K));
         RTPropertyValues::check_kind_can_have_property(K);
     }
    diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt
    index f9f8006d0..753e95662 100644
    --- a/inform7/Figures/memory-diagnostics.txt
    +++ b/inform7/Figures/memory-diagnostics.txt
    @@ -1,12 +1,12 @@
    -Total memory consumption was 331729K = 324 MB
    +Total memory consumption was 331079K = 323 MB
     
    -62.2% was used for 1658916 objects, in 326919 frames in 258 x 800K = 206400K = 201 MB:
    +62.0% was used for 1660986 objects, in 326976 frames in 257 x 800K = 205600K = 200 MB:
     
          9.7%  inter_tree_node_array                    46 x 8192 = 376832 objects, 33162688 bytes
    -     6.6%  text_stream_array                        4027 x 100 = 402700 objects, 22680064 bytes
    +     6.7%  text_stream_array                        4036 x 100 = 403600 objects, 22730752 bytes
          4.8%  linked_list                              29551 objects, 16548560 bytes
          3.0%  parse_node                               129396 objects, 10351680 bytes
    -     3.0%  inter_symbol_array                       104 x 1024 = 106496 objects, 10226944 bytes
    +     3.0%  inter_symbol_array                       105 x 1024 = 107520 objects, 10325280 bytes
          2.1%  verb_conjugation                         160 objects, 7425280 bytes
          1.6%  parse_node_annotation_array              345 x 500 = 172500 objects, 5531040 bytes
          1.0%  pcalc_prop_array                         25 x 1000 = 25000 objects, 3400800 bytes
    @@ -18,13 +18,13 @@ Total memory consumption was 331729K = 324 MB
          0.4%  inter_name_generator_array               38 x 1000 = 38000 objects, 1521216 bytes
          0.4%  match_trie_array                         11 x 1000 = 11000 objects, 1496352 bytes
          0.4%  i6_schema_array                          23 x 100 = 2300 objects, 1380736 bytes
    -     0.3%  inter_package                            16417 objects, 1182024 bytes
    -     0.3%  dictionary                               22491 objects, 1079568 bytes
    +     0.3%  inter_package                            16419 objects, 1182168 bytes
    +     0.3%  dictionary                               22495 objects, 1079760 bytes
          0.3%  id_body                                  940 objects, 1075360 bytes
    -     0.3%  inter_symbols_table                      16417 objects, 1050688 bytes
    -     0.3%  dict_entry_array                         316 x 100 = 31600 objects, 1021312 bytes
    +     0.3%  inter_symbols_table                      16419 objects, 1050816 bytes
    +     0.3%  dict_entry_array                         317 x 100 = 31700 objects, 1024544 bytes
          0.2%  adjective_meaning                        202 objects, 1000304 bytes
    -     0.2%  package_request                          10993 objects, 967384 bytes
    +     0.2%  package_request                          10995 objects, 967560 bytes
          0.2%  excerpt_meaning                          3098 objects, 966576 bytes
          0.2%  production                               3871 objects, 898072 bytes
          0.2%  ptoken                                   8379 objects, 871416 bytes
    @@ -43,7 +43,7 @@ Total memory consumption was 331729K = 324 MB
          ----  inter_annotation_array                   1 x 8192 objects, 196640 bytes
          ----  binary_predicate                         321 objects, 169488 bytes
          ----  linguistic_stock_item                    3315 objects, 159120 bytes
    -     ----  hierarchy_location                       982 objects, 149264 bytes
    +     ----  hierarchy_location                       1004 objects, 152608 bytes
          ----  rule_family_data                         400 objects, 147200 bytes
          ----  nonterminal                              759 objects, 139656 bytes
          ----  nascent_array                            1948 objects, 124672 bytes
    @@ -52,7 +52,7 @@ Total memory consumption was 331729K = 324 MB
          ----  imperative_defn                          1376 objects, 99072 bytes
          ----  anl_entry_array                          2 x 1000 = 2000 objects, 96064 bytes
          ----  noun_usage                               2401 objects, 96040 bytes
    -     ----  inter_tree                               6 objects, 91392 bytes
    +     ----  inter_tree                               6 objects, 92592 bytes
          ----  preposition                              273 objects, 87360 bytes
          ----  lexical_cluster                          2516 objects, 80512 bytes
          ----  pcalc_term_array                         2 x 1000 = 2000 objects, 80064 bytes
    @@ -109,14 +109,14 @@ Total memory consumption was 331729K = 324 MB
          ----  booking_list                             407 objects, 13024 bytes
          ----  adjective_iname_holder                   320 objects, 12800 bytes
          ----  pathname                                 292 objects, 11680 bytes
    -     ----  uniqueness_count                         382 objects, 9168 bytes
    +     ----  uniqueness_count                         391 objects, 9384 bytes
          ----  stopwatch_timer                          109 objects, 8720 bytes
          ----  filename                                 208 objects, 8320 bytes
          ----  equation_node                            68 objects, 7616 bytes
          ----  understanding_item_array                 3 x 100 = 300 objects, 7296 bytes
          ----  shared_variable_array                    1 x 100 objects, 7232 bytes
          ----  determiner                               22 objects, 7216 bytes
    -     ----  hierarchy_attachment_point               64 objects, 6144 bytes
    +     ----  hierarchy_attachment_point               67 objects, 6432 bytes
          ----  verb                                     108 objects, 6048 bytes
          ----  text_literal_holder                      144 objects, 5760 bytes
          ----  heading_tree                             20 objects, 5440 bytes
    @@ -156,14 +156,14 @@ Total memory consumption was 331729K = 324 MB
          ----  cached_kind_declaration                  39 objects, 1560 bytes
          ----  noun_filter_token                        22 objects, 1408 bytes
          ----  inter_annotation_form                    35 objects, 1400 bytes
    -     ----  inter_tree_location_list                 33 objects, 1320 bytes
    +     ----  inter_tree_location_list                 34 objects, 1360 bytes
          ----  special_meaning_holder                   33 objects, 1320 bytes
          ----  constant_phrase                          20 objects, 1280 bytes
          ----  build_script                             40 objects, 1280 bytes
          ----  table_column                             16 objects, 1280 bytes
          ----  invocation_options_array                 1 x 100 objects, 1224 bytes
          ----  direction_inference_data                 30 objects, 1200 bytes
    -     ----  tree_inventory_item                      27 objects, 1080 bytes
    +     ----  tree_inventory_item                      28 objects, 1120 bytes
          ----  runtime_kind_structure                   13 objects, 1040 bytes
          ----  quantifier                               16 objects, 1024 bytes
          ----  named_rulebook_outcome                   15 objects, 960 bytes
    @@ -198,13 +198,13 @@ Total memory consumption was 331729K = 324 MB
          ----  door_dir_notice                          5 objects, 320 bytes
          ----  pronoun                                  8 objects, 320 bytes
          ----  grammatical_category                     8 objects, 320 bytes
    -     ----  tree_inventory                           1 object, 304 bytes
    +     ----  tree_inventory                           1 object, 312 bytes
          ----  up_family                                9 objects, 288 bytes
          ----  build_step                               4 objects, 288 bytes
          ----  explicit_bp_data                         5 objects, 280 bytes
    -     ----  door_to_notice                           5 objects, 280 bytes
          ----  compilation_unit                         5 objects, 280 bytes
          ----  contents_entry                           7 objects, 280 bytes
    +     ----  door_to_notice                           5 objects, 280 bytes
          ----  inform_pipeline                          4 objects, 256 bytes
          ----  verb_usage_tier                          5 objects, 240 bytes
          ----  adjective_meaning_family                 7 objects, 224 bytes
    @@ -214,46 +214,46 @@ Total memory consumption was 331729K = 324 MB
          ----  kit_dependency                           4 objects, 192 bytes
          ----  plural_dictionary_entry                  4 objects, 192 bytes
          ----  inform_project                           1 object, 176 bytes
    -     ----  code_generation_target                   4 objects, 160 bytes
    -     ----  inter_architecture                       4 objects, 160 bytes
          ----  imperative_defn_family                   4 objects, 160 bytes
          ----  link_instruction                         4 objects, 160 bytes
    +     ----  code_generation_target                   4 objects, 160 bytes
          ----  inference_subject_family                 5 objects, 160 bytes
    -     ----  element_activation                       4 objects, 128 bytes
    +     ----  inter_architecture                       4 objects, 160 bytes
          ----  codegen_pipeline                         1 object, 128 bytes
    +     ----  element_activation                       4 objects, 128 bytes
          ----  inbuild_nest                             3 objects, 120 bytes
          ----  local_block_value                        2 objects, 112 bytes
          ----  inform_kit_ittt                          2 objects, 96 bytes
    -     ----  article                                  2 objects, 80 bytes
    -     ----  group_together_function                  2 objects, 80 bytes
          ----  compile_task_data                        1 object, 80 bytes
    +     ----  group_together_function                  2 objects, 80 bytes
    +     ----  article                                  2 objects, 80 bytes
          ----  build_methodology                        1 object, 56 bytes
    -     ----  inter_warehouse                          1 object, 56 bytes
          ----  figures_data                             1 object, 56 bytes
    -     ----  HTML_file_state                          1 object, 48 bytes
    +     ----  inter_warehouse                          1 object, 56 bytes
          ----  star_invention                           1 object, 48 bytes
    -     ----  kind_template_definition                 1 object, 40 bytes
    +     ----  HTML_file_state                          1 object, 48 bytes
          ----  loop_over_scope                          1 object, 40 bytes
          ----  by_function_bp_data                      1 object, 40 bytes
    +     ----  kind_template_definition                 1 object, 40 bytes
     
    -37.7% was used for memory not allocated for objects:
    +37.9% was used for memory not allocated for objects:
     
    -    17.6%  text stream storage                      59833332 bytes in 416693 claims
    -     3.6%  dictionary storage                       12430336 bytes in 22491 claims
    +    17.6%  text stream storage                      59984268 bytes in 417738 claims
    +     3.6%  dictionary storage                       12432384 bytes in 22495 claims
          ----  sorting                                  720 bytes in 3 claims
          2.1%  source text                              7200000 bytes in 3 claims
          3.1%  source text details                      10800000 bytes in 2 claims
          ----  linguistic stock array                   81920 bytes in 2 claims
          ----  small word set array                     105600 bytes in 22 claims
    -     0.8%  inter symbols storage                    2820576 bytes in 17432 claims
    +     0.8%  inter symbols storage                    2820832 bytes in 17434 claims
          4.9%  inter bytecode storage                   16802796 bytes in 14 claims
          4.7%  inter links storage                      16174208 bytes in 266 claims
          ----  inter tree location list storage         191232 bytes in 32 claims
    -     0.4%  instance-of-kind counting                1695204 bytes in 1 claim
    +     0.5%  instance-of-kind counting                1695204 bytes in 1 claim
          ----  compilation workspace for objects        21856 bytes in 25 claims
          ----  lists for type-checking invocations      16000 bytes in 1 claim
          ----  code generation workspace for objects    9648 bytes in 9 claims
          ----  emitter array storage                    154432 bytes in 2037 claims
     
    -19.3% was overhead - 65735600 bytes = 64194K = 62 MB
    +19.1% was overhead - 64758368 bytes = 63240K = 61 MB
     
    diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt
    index df374d729..e78c3f41e 100644
    --- a/inform7/Figures/timings-diagnostics.txt
    +++ b/inform7/Figures/timings-diagnostics.txt
    @@ -1,26 +1,25 @@
     100.0% in inform7 run
          53.4% in compilation to Inter
    -         39.4% in //Sequence::undertake_queued_tasks//
    -          3.9% in //MajorNodes::pre_pass//
    -          2.8% in //MajorNodes::pass_1//
    +         39.7% in //Sequence::undertake_queued_tasks//
    +          3.8% in //MajorNodes::pre_pass//
    +          2.9% in //MajorNodes::pass_1//
               1.5% in //ImperativeDefinitions::assess_all//
               0.5% in //MajorNodes::pass_2//
               0.5% in //RTKindConstructors::compile//
               0.5% in //World::stage_V//
    +          0.3% in //CompletionModule::compile//
               0.3% in //ImperativeDefinitions::compile_first_block//
               0.3% in //Sequence::undertake_queued_tasks//
    -          0.1% in //CompletionModule::compile//
               0.1% in //InferenceSubjects::emit_all//
               0.1% in //RTKindConstructors::compile_permissions//
               0.1% in //Task::make_built_in_kind_constructors//
    -          0.1% in //World::stages_II_and_III//
    -          2.6% not specifically accounted for
    -     44.3% in running Inter pipeline
    -         11.2% in inter step 7/14: consolidate-text
    -         10.8% in step preparation
    -          9.0% in inter step 2/14: link
    +          2.2% not specifically accounted for
    +     44.4% in running Inter pipeline
    +         11.0% in inter step 7/14: consolidate-text
    +         11.0% in step preparation
    +          9.1% in inter step 2/14: link
               7.4% in inter step 14/14: generate inform6 -> auto.inf
    -          1.1% in inter step 10/14: make-identifiers-unique
    +          1.2% in inter step 10/14: make-identifiers-unique
               0.3% in inter step 11/14: reconcile-verbs
               0.3% in inter step 13/14: eliminate-redundant-operations
               0.3% in inter step 6/14: assimilate
    @@ -29,6 +28,6 @@
               0.1% in inter step 5/14: resolve-conditional-compilation
               0.1% in inter step 8/14: resolve-external-symbols
               0.1% in inter step 9/14: inspect-plugs
    -          2.7% not specifically accounted for
    -      1.8% in supervisor
    -      0.4% not specifically accounted for
    +          2.6% not specifically accounted for
    +      1.9% in supervisor
    +      0.2% not specifically accounted for
    diff --git a/inform7/Tests/Test Internals/Index-Plot.txt b/inform7/Tests/Test Internals/Index-Plot.txt
    new file mode 100644
    index 000000000..6ba292a96
    --- /dev/null
    +++ b/inform7/Tests/Test Internals/Index-Plot.txt	
    @@ -0,0 +1,23 @@
    +Hypothesis Junction is a room. The Waiting Room is east of Hypothesis Junction.
    +
    +Arrival is a scene. "There's a flourish of trumpets."
    +
    +When Arrival begins: say "There's a flourish of trumpets."
    +
    +Arrival begins when the player is in the Hypothesis Junction for the third turn.
    +
    +Luggage Trouble is a scene. Luggage Trouble begins when Railway Meeting begins.
    +
    +Railway Meeting is a scene. Railway Meeting begins when play begins.
    +
    +Railway Meeting ends when Luggage Trouble ends.
    +
    +Train Stop is a recurring scene. Train Wait is a recurring scene.
    +Train Wait begins when play begins.
    +Train Stop begins when Train Wait ends.
    +Train Wait begins when Train Stop ends.
    +
    +Railway Meeting ends happily when the time of day is 11:00 PM.
    +Railway Meeting ends wisely but sadly when the player is in the Waiting Room.
    +
    +Test index (internal) with Pl.
    diff --git a/inform7/Tests/Test Internals/_Results_Ideal/Index-Plot.txt b/inform7/Tests/Test Internals/_Results_Ideal/Index-Plot.txt
    new file mode 100644
    index 000000000..3f76a1c37
    --- /dev/null
    +++ b/inform7/Tests/Test Internals/_Results_Ideal/Index-Plot.txt	
    @@ -0,0 +1,41 @@
    +1. Pl
    +

      entire game   

    +

      railway meeting 

    +

      luggage trouble   

    +

      train wait     

    +

      train stop     

    +

      train wait

    +

      arrival   

    +

    Legend:  Begins when play begins;  can begin whenever some condition holds;  follows when a previous scene ends;  begins simultaneously;  never begins;  never ends;  recurring (can happen more than once). Scene names are italicised when and if they appear for a second or subsequent time because the scene can begin in more than one way.

    +
    +

    The entire game scene  recurring

    +

    The Entire Game scene is built-in. It is going on whenever play is going on. (It is recurring so that if the story ends, but then resumes, it too will end but then begin again.)

    +

    Begins when: the story has not ended

    +

    Ends when: the story has ended

    +
    +

    The arrival scene 

    +

    Begins when: the player is in the Hypothesis Junction 

    +

    What happens:

    +

        (say "There's a flourish of trumpets.") 

    +

    +

    Ends when: never

    +
    +

    The luggage trouble scene 

    +

    Begins when: railway meeting begins 

    +

    Ends when: never

    +
    +

    The railway meeting scene 

    +

    Begins when: play begins

    +

    Ends when: luggage trouble ends 

    +

    Ends happily when: the time of day is 11:00 PM 

    +

    Ends wisely but sadly when: the player is in the Waiting Room 

    +
    +

    The train stop scene   recurring

    +

    Begins when: train wait ends 

    +

    Ends when: never

    +
    +

    The train wait scene   recurring

    +

    Begins when: play begins
    +or when: train stop ends 

    +

    Ends when: never

    + diff --git a/inform7/if-module/Chapter 3/Scenes.w b/inform7/if-module/Chapter 3/Scenes.w index e7b885221..4ff487bdf 100644 --- a/inform7/if-module/Chapter 3/Scenes.w +++ b/inform7/if-module/Chapter 3/Scenes.w @@ -111,8 +111,6 @@ triumphantly", for instance, might be ends 2 and 3). Each end has a condition which can cause it, or can be "anchored" to any number of ends of other scenes -- to express which, the //scene_connector// structure is used. -@d MAX_SCENE_ENDS 32 /* this must exceed 31 */ - = typedef struct scene { struct instance *as_instance; /* the constant for the name of the scene */ @@ -202,6 +200,12 @@ scene *Scenes::from_named_constant(instance *I) { return NULL; } +int Scenes::is_entire_game(instance *I) { + if ((SC_entire_game) && (Scenes::from_named_constant(I) == SC_entire_game)) + return TRUE; + return FALSE; +} + @h Creating and parsing ends. = diff --git a/inform7/index-module/Chapter 3/Plot Element.w b/inform7/index-module/Chapter 3/Plot Element.w deleted file mode 100644 index 331de229c..000000000 --- a/inform7/index-module/Chapter 3/Plot Element.w +++ /dev/null @@ -1,313 +0,0 @@ -[IXScenes::] Plot Element. - -Parallel to the World index of space is the Scenes index of time, -and in this section we render it as HTML. - -@ The mapping of time is on the one hand simpler than the mapping of space -since there is only one dimension, but on the other hand more complex since -scenes can be multiply present at the same instant of time (whereas rooms -cannot be multiply present at the same point in space). We resolve this -with a notation which takes a little bit of on-screen explanation, but -seems natural enough to learn in practice. - -= -void IXScenes::render(OUTPUT_STREAM) { - int nr = NUMBER_CREATED(scene); - scene **sorted = Memory::calloc(nr, sizeof(scene *), INDEX_SORTING_MREASON); - @; - - @; - @; - @; - - Memory::I7_array_free(sorted, INDEX_SORTING_MREASON, nr, sizeof(scene *)); -} - -@ As usual, we sort with the C library's |qsort|. - -@ = - int i = 0; - scene *sc; - LOOP_OVER(sc, scene) sorted[i++] = sc; - qsort(sorted, (size_t) nr, sizeof(scene *), IXScenes::compare_scenes); - -@ The sorted ordering is used as-is later on, when we get to the details, but -for the tabulation it's refined further. First we have the start-of-play -scenes, in sorted order; then scenes with a condition for their beginning -(end 0), in sorted order; then scenes that don't, and which haven't been -covered as a result of one of the earlier ones, also in sorted order. (This -third category is usually empty except for scenes the author has forgotten -about and created but never made use of.) - -@ = - for (int i=0; istart_of_play) || (sc == SC_entire_game)) - IXScenes::index_from_scene(OUT, sc, 0, START_OF_PLAY_END, NULL, sorted, nr); - } - for (int i=0; iends[0].anchor_condition) && (sc != SC_entire_game)) - IXScenes::index_from_scene(OUT, sc, 0, START_OF_PLAY_END, NULL, sorted, nr); - } - for (int i=0; iindexed == FALSE) - IXScenes::index_from_scene(OUT, sc, 0, NEVER_HAPPENS_END, NULL, sorted, nr); - } - - -@ = - HTML_OPEN("p"); WRITE("Legend: "); - IXScenes::scene_icon_legend(OUT, "WPB", "Begins when play begins"); - WRITE("; "); - IXScenes::scene_icon_legend(OUT, "WhenC", "can begin whenever some condition holds"); - WRITE("; "); - IXScenes::scene_icon_legend(OUT, "Segue", "follows when a previous scene ends"); - WRITE("; "); - IXScenes::scene_icon_legend(OUT, "Simul", "begins simultaneously"); - WRITE("; "); - IXScenes::scene_icon_legend(OUT, "WNever", "never begins"); - WRITE("; "); - IXScenes::scene_icon_legend(OUT, "ENever", "never ends"); - WRITE("; "); - IXScenes::scene_icon_legend(OUT, "Recurring", "recurring (can happen more than once)"); - WRITE(". Scene names are italicised when and if they appear for a second " - "or subsequent time because the scene can begin in more than one way."); - HTML_CLOSE("p"); - - -@ = - Index::anchor(OUT, I"SDETAILS"); - for (int i=0; i; - } - -@ The curious condition about end 1 here is to avoid printing "Ends: Never" -in cases where fancier ends for the scene exist, so that the scene can, in -fact, end. - -@ = - @; - if (sc == SC_entire_game) @; - - for (int end=0; endno_ends; end++) { - if ((end == 1) && (sc->no_ends > 2) && - (sc->ends[1].anchor_condition==NULL) && (sc->ends[1].anchor_connectors==NULL)) - continue; - @; - @; - if (end == 0) @; - } - -@ = - HTML::open_indented_p(OUT, 1, "hanging"); - Index::anchor_numbered(OUT, sc->allocation_id); - WRITE("The %+W scene", Scenes::get_name(sc)); - Index::link(OUT, Wordings::first_wn(Node::get_text(Instances::get_creating_sentence(sc->as_instance)))); - if (PropertyInferences::either_or_state( - Instances::as_subject(sc->as_instance), P_recurring) > 0) - WRITE("  recurring"); - HTML_CLOSE("p"); - -@ = - HTML::open_indented_p(OUT, 1, "tight"); - WRITE("The Entire Game scene is built-in. It is going on whenever play is " - "going on. (It is recurring so that if the story ends, but then resumes, " - "it too will end but then begin again.)"); - HTML_CLOSE("p"); - -@ = - int rbc = 0; - rulebook *rb; - LOOP_OVER(rb, rulebook) { - if (Rulebooks::is_contextually_empty(rb, IXRules::scene_context(sc)) == FALSE) { - if (rbc++ == 0) { - HTML::open_indented_p(OUT, 1, "hanging"); - WRITE("During this scene:"); - HTML_CLOSE("p"); - } - HTML::open_indented_p(OUT, 2, "hanging"); - WRITE("%+W", rb->primary_name); HTML_CLOSE("p"); - int ignore_me = 0; - IXRules::index_rulebook(OUT, rb, "", IXRules::scene_context(sc), &ignore_me); - } - } - -@ = - HTML::open_indented_p(OUT, 1, "hanging"); - WRITE("%s ", (end==0)?"Begins":"Ends"); - if (end >= 2) WRITE("%+W ", sc->ends[end].end_names); - WRITE("when: "); - int count = 0; - @; - @; - @; - if (count == 0) WRITE("never"); - HTML_CLOSE("p"); - -@ = - if ((end==0) && (sc->start_of_play)) { - if (count > 0) { - HTML_TAG("br"); - WRITE("or when: "); - } - WRITE("play begins"); - count++; - } - -@ = - if (sc->ends[end].anchor_condition) { - if (count > 0) { - HTML_TAG("br"); - WRITE("or when: "); - } - WRITE("%+W", Node::get_text(sc->ends[end].anchor_condition)); - Index::link(OUT, Wordings::first_wn(Node::get_text(sc->ends[end].anchor_condition_set))); - count++; - } - -@ = - for (scene_connector *scon = sc->ends[end].anchor_connectors; scon; scon=scon->next) { - if (count > 0) { - HTML_TAG("br"); - WRITE("or when: "); - } - wording NW = Instances::get_name(scon->connect_to->as_instance, FALSE); - WRITE("%+W %s", NW, (scon->end==0)?"begins":"ends"); - if (scon->end >= 2) WRITE(" %+W", scon->connect_to->ends[scon->end].end_names); - Index::link(OUT, Wordings::first_wn(Node::get_text(scon->where_said))); - count++; - } - -@ = - if (Rulebooks::is_empty(sc->ends[end].end_rulebook) == FALSE) { - HTML::open_indented_p(OUT, 1, "hanging"); - WRITE("What happens:"); HTML_CLOSE("p"); - int ignore_me = 0; - IXRules::index_rulebook(OUT, sc->ends[end].end_rulebook, "", - IXRules::no_rule_context(), &ignore_me); - } - -@h Table of Scenes. -We finally return to the table of scenes. The following is recursive, and -is called at the top level for each scene in turn which starts at the start -of play (see above). - -A scene entry can be arrived at in three ways: through one of its ends, in -which case |end| is the number (0 for begins, 1 for standard ends, and so on), -or through being already active at the start of play, or through being covered -in the index even though it never happens in play. This means we need two -additional |end| numbers. They are only ever used at the top level, that is, -on the initial call when |depth| is 0. - -@d START_OF_PLAY_END -1 -@d NEVER_HAPPENS_END -2 - -= -void IXScenes::index_from_scene(OUTPUT_STREAM, scene *sc, int depth, - int end, scene *sc_from, scene **sorted, int nr) { - HTML::open_indented_p(OUT, depth+1, "tight"); - @; - @; - if (sc->indexed == FALSE) { - @; - @; - } - HTML_CLOSE("p"); - if (sc->indexed) return; - sc->indexed = TRUE; - @; -} - -@ = - switch(end) { - case 0: IXScenes::scene_icon(OUT, "Simul"); break; - case 1: IXScenes::scene_icon(OUT, "Segue"); break; - case START_OF_PLAY_END: break; - case NEVER_HAPPENS_END: IXScenes::scene_icon(OUT, "WNever"); break; - default: - IXScenes::scene_icon(OUT, "Segue"); - WRITE("[ends %+W] ", sc_from->ends[end].end_names); break; - } - if ((sc->indexed == FALSE) || (depth == 0)) { - if (sc == SC_entire_game) IXScenes::scene_icon(OUT, "WPB"); - else if (sc->ends[0].anchor_condition) IXScenes::scene_icon(OUT, "WhenC"); - if (sc->start_of_play) IXScenes::scene_icon(OUT, "WPB"); - } - -@ = - if (sc->indexed) WRITE(""); - WRITE("%+W", Instances::get_name(sc->as_instance, FALSE)); - if (sc->indexed) WRITE(""); - else Index::below_link_numbered(OUT, sc->allocation_id); - -@ = - int ways_to_end = 0; - for (int e=1; eno_ends; e++) { - if (sc->ends[e].anchor_connectors) ways_to_end++; - if (sc->ends[e].anchor_condition) ways_to_end++; - } - if (ways_to_end == 0) IXScenes::scene_icon_append(OUT, "ENever"); - -@ = - inference_subject *subj = Instances::as_subject(sc->as_instance); - if (PropertyInferences::either_or_state(subj, P_recurring) > UNKNOWN_CE) - IXScenes::scene_icon_append(OUT, "Recurring"); - -@ And this is where the routine recurses, so that consequent scenes are -tabulated underneath the present one, indented one step further in (since -indentation is coupled to |depth|). First we recurse to scenes which end when -this one does; then to scenes which begin when this one ends. - -@ = - for (int i=0; iends[0].anchor_connectors; scon; scon=scon->next) - if ((scon->connect_to == sc) && (scon->end >= 1)) - IXScenes::index_from_scene(OUT, sc2, depth + 1, scon->end, sc, sorted, nr); - } - for (int i=0; iends[0].anchor_connectors; scon; scon=scon->next) - if ((scon->connect_to == sc) && (scon->end == 0)) - IXScenes::index_from_scene(OUT, sc2, depth, scon->end, sc, sorted, nr); - } - -@ We have been using: - -= -void IXScenes::scene_icon(OUTPUT_STREAM, char *si) { - IXScenes::scene_icon_unspaced(OUT, si); WRITE("  "); -} - -void IXScenes::scene_icon_append(OUTPUT_STREAM, char *si) { - WRITE("  "); IXScenes::scene_icon_unspaced(OUT, si); -} - -void IXScenes::scene_icon_legend(OUTPUT_STREAM, char *si, char *gloss) { - IXScenes::scene_icon_unspaced(OUT, si); WRITE(" %s", gloss); -} - -void IXScenes::scene_icon_unspaced(OUTPUT_STREAM, char *si) { - HTML_TAG_WITH("img", "border=0 src=inform:/scene_icons/%s.png", si); -} - -@ Lastly: the following is the criterion used for sorting the scenes into -their indexing order. The Entire Game always comes first, and then come the -rest in ascending alphabetical order. - -= -int IXScenes::compare_scenes(const void *ent1, const void *ent2) { - const scene *sc1 = *((const scene **) ent1); - const scene *sc2 = *((const scene **) ent2); - if ((sc1 == SC_entire_game) && (sc2 != SC_entire_game)) return -1; - if ((sc1 != SC_entire_game) && (sc2 == SC_entire_game)) return 1; - wording SW1 = Instances::get_name(sc1->as_instance, FALSE); - wording SW2 = Instances::get_name(sc2->as_instance, FALSE); - return Wordings::strcmp(SW1, SW2); -} diff --git a/inform7/index-module/Contents.w b/inform7/index-module/Contents.w index 114f4c835..8c44d4b84 100644 --- a/inform7/index-module/Contents.w +++ b/inform7/index-module/Contents.w @@ -26,7 +26,6 @@ Chapter 3: Indexing for Plugins Backdrops Regions The Map - Plot Element Actions Commands Index diff --git a/inform7/runtime-module/Chapter 2/Hierarchy.w b/inform7/runtime-module/Chapter 2/Hierarchy.w index 225f7a933..6434d65b1 100644 --- a/inform7/runtime-module/Chapter 2/Hierarchy.w +++ b/inform7/runtime-module/Chapter 2/Hierarchy.w @@ -820,6 +820,11 @@ void Hierarchy::establish(void) { @e INSTANCE_INDEX_KIND_MD_HL @e INSTANCE_IS_OBJECT_MD_HL @e INSTANCE_IS_SCENE_MD_HL +@e INSTANCE_IS_ENTIRE_GAME_MD_HL +@e INSTANCE_SCENE_STARTS_MD_HL +@e INSTANCE_SCENE_STARTS_ON_CONDITION_MD_HL +@e INSTANCE_SCENE_RECURS_MD_HL +@e INSTANCE_SCENE_NEVER_ENDS_MD_HL @e INSTANCE_IS_EXF_MD_HL @e INSTANCE_FILE_VALUE_MD_HL @e INSTANCE_FILE_IS_BINARY_MD_HL @@ -835,6 +840,15 @@ void Hierarchy::establish(void) { @e INSTANCE_SOUND_ID_MD_HL @e INSTANCE_SSF_MD_HL @e INSTANCE_SCF_MD_HL +@e SCENE_ENDS_HAP +@e SCENE_END_NAME_MD_HL +@e SCENE_END_AT_MD_HL +@e SCENE_END_CONDITION_MD_HL +@e SCENE_END_RULEBOOK_MD_HL +@e SCENE_CONNECTORS_HAP +@e SCENE_CONNECTOR_TO_MD_HL +@e SCENE_CONNECTOR_END_MD_HL +@e SCENE_CONNECTOR_AT_MD_HL @e INST_SHOWME_MD_HL @e INST_SHOWME_FN_HL @e INSTANCE_HL @@ -862,8 +876,24 @@ void Hierarchy::establish(void) { H_C_U(INSTANCE_INDEX_KIND_MD_HL, I"^index_kind") H_C_U(INSTANCE_IS_OBJECT_MD_HL, I"^is_object") H_C_U(INSTANCE_IS_SCENE_MD_HL, I"^is_scene") + H_C_U(INSTANCE_IS_ENTIRE_GAME_MD_HL, I"^is_entire_game") + H_C_U(INSTANCE_SCENE_STARTS_MD_HL, I"^starts") + H_C_U(INSTANCE_SCENE_STARTS_ON_CONDITION_MD_HL, I"^starts_on_condition") + H_C_U(INSTANCE_SCENE_RECURS_MD_HL, I"^recurs") + H_C_U(INSTANCE_SCENE_NEVER_ENDS_MD_HL, I"^never_ends") H_C_U(INSTANCE_SSF_MD_HL, I"^scene_status_fn") H_C_U(INSTANCE_SCF_MD_HL, I"^scene_change_fn") + H_BEGIN_AP(SCENE_ENDS_HAP, I"scene_end", I"_scene_end") + H_C_U(SCENE_END_NAME_MD_HL, I"^name") + H_C_U(SCENE_END_AT_MD_HL, I"^at") + H_C_U(SCENE_END_CONDITION_MD_HL, I"^condition") + H_C_U(SCENE_END_RULEBOOK_MD_HL, I"^rulebook") + H_BEGIN_AP(SCENE_CONNECTORS_HAP, I"scene_connector", I"_scene_connector") + H_C_U(SCENE_CONNECTOR_TO_MD_HL, I"^to") + H_C_U(SCENE_CONNECTOR_END_MD_HL, I"^end") + H_C_U(SCENE_CONNECTOR_AT_MD_HL, I"^at") + H_END + H_END H_C_U(INSTANCE_IS_EXF_MD_HL, I"^is_file") H_C_U(INSTANCE_FILE_VALUE_MD_HL, I"^file_value") H_C_U(INSTANCE_FILE_OWNED_MD_HL, I"^file_owned") diff --git a/inform7/runtime-module/Chapter 5/Instances.w b/inform7/runtime-module/Chapter 5/Instances.w index e4173b36c..d725d7fbc 100644 --- a/inform7/runtime-module/Chapter 5/Instances.w +++ b/inform7/runtime-module/Chapter 5/Instances.w @@ -87,9 +87,6 @@ void RTInstances::compilation_agent(compilation_subtask *t) { if (Kinds::Behaviour::is_subkind_of_object(K)) Hierarchy::apply_metadata_from_number(pack, INSTANCE_IS_OBJECT_MD_HL, 1); - if ((K_scene) && (Kinds::eq(K, K_scene))) - Hierarchy::apply_metadata_from_number(pack, - INSTANCE_IS_SCENE_MD_HL, 1); if ((K_sound_name) && (Kinds::eq(K, K_sound_name))) Hierarchy::apply_metadata_from_number(pack, INSTANCE_IS_SOUND_MD_HL, 1); diff --git a/inform7/runtime-module/Chapter 5/Rulebooks.w b/inform7/runtime-module/Chapter 5/Rulebooks.w index a22ac7e2f..21c1da8d6 100644 --- a/inform7/runtime-module/Chapter 5/Rulebooks.w +++ b/inform7/runtime-module/Chapter 5/Rulebooks.w @@ -149,7 +149,7 @@ void RTRulebooks::compilation_agent(compilation_subtask *t) { Hierarchy::apply_metadata_from_raw_wording(EP, RULE_INDEX_NAME_MD_HL, R->indexing_data.italicised_text); if (R->defn_as_I7_source) { - parse_node *pn = R->defn_as_I7_source->at->down; + parse_node *pn = R->defn_as_I7_source->at->down->down; if ((pn) && (Wordings::nonempty(Node::get_text(pn)))) { TEMPORARY_TEXT(OUT) WRITE("%+W", Node::get_text(pn)); diff --git a/inform7/runtime-module/Chapter 5/Scene Instances.w b/inform7/runtime-module/Chapter 5/Scene Instances.w index 3433ac1cd..2bd01ff2b 100644 --- a/inform7/runtime-module/Chapter 5/Scene Instances.w +++ b/inform7/runtime-module/Chapter 5/Scene Instances.w @@ -10,13 +10,50 @@ the current |location| or not. void RTScenes::compile_extra(instance *I) { if ((K_scene) && (Instances::of_kind(I, K_scene))) { scene *sc = Scenes::from_named_constant(I); - if (sc == NULL) internal_error("sceneless"); + package_request *pack = RTInstances::package(I); + Hierarchy::apply_metadata_from_number(pack, INSTANCE_IS_SCENE_MD_HL, 1); + if (Scenes::is_entire_game(I)) + Hierarchy::apply_metadata_from_number(pack, + INSTANCE_IS_ENTIRE_GAME_MD_HL, 1); + if (sc->start_of_play) + Hierarchy::apply_metadata_from_number(pack, + INSTANCE_SCENE_STARTS_MD_HL, 1); + else if (sc->ends[0].anchor_condition) + Hierarchy::apply_metadata_from_number(pack, + INSTANCE_SCENE_STARTS_ON_CONDITION_MD_HL, 1); + inference_subject *subj = Instances::as_subject(sc->as_instance); + if (PropertyInferences::either_or_state(subj, P_recurring) > UNKNOWN_CE) + Hierarchy::apply_metadata_from_number(pack, + INSTANCE_SCENE_RECURS_MD_HL, 1); + int ways_to_end = 0; + for (int e=1; eno_ends; e++) { + if (sc->ends[e].anchor_connectors) ways_to_end++; + if (sc->ends[e].anchor_condition) ways_to_end++; + } + if (ways_to_end == 0) + Hierarchy::apply_metadata_from_number(pack, + INSTANCE_SCENE_NEVER_ENDS_MD_HL, 1); + text_stream *desc = Str::new(); WRITE_TO(desc, "scene change fn for "); Instances::write(desc, I); Sequence::queue(&RTScenes::change_compilation_agent, STORE_POINTER_scene(sc), desc); text_stream *desc2 = Str::new(); WRITE_TO(desc2, "scene status fn for "); Instances::write(desc, I); Sequence::queue(&RTScenes::status_compilation_agent, STORE_POINTER_scene(sc), desc2); + + for (int e=0; eno_ends; e++) { + package_request *EP = Hierarchy::package_within(SCENE_ENDS_HAP, pack); + Hierarchy::apply_metadata_from_raw_wording(EP, SCENE_END_NAME_MD_HL, sc->ends[e].end_names); + Hierarchy::apply_metadata_from_number(EP, SCENE_END_AT_MD_HL, (inter_ti) Wordings::first_wn(Node::get_text(sc->ends[e].anchor_condition_set))); + Hierarchy::apply_metadata_from_raw_wording(EP, SCENE_END_CONDITION_MD_HL, Node::get_text(sc->ends[e].anchor_condition)); + Hierarchy::apply_metadata_from_iname(EP, SCENE_END_RULEBOOK_MD_HL, RTRulebooks::id_iname(sc->ends[e].end_rulebook)); + for (scene_connector *scon = sc->ends[e].anchor_connectors; scon; scon=scon->next) { + package_request *CP = Hierarchy::package_within(SCENE_CONNECTORS_HAP, EP); + Hierarchy::apply_metadata_from_iname(CP, SCENE_CONNECTOR_TO_MD_HL, RTInstances::value_iname(scon->connect_to->as_instance)); + Hierarchy::apply_metadata_from_number(CP, SCENE_CONNECTOR_END_MD_HL, (inter_ti) scon->end); + Hierarchy::apply_metadata_from_number(CP, SCENE_CONNECTOR_AT_MD_HL, (inter_ti) Wordings::first_wn(Node::get_text(scon->where_said))); + } + } } } diff --git a/inter/codegen-module/Chapter 1/Codegen Module.w b/inter/codegen-module/Chapter 1/Codegen Module.w index 7e565ef0c..a0803b712 100644 --- a/inter/codegen-module/Chapter 1/Codegen Module.w +++ b/inter/codegen-module/Chapter 1/Codegen Module.w @@ -27,6 +27,9 @@ which use this module: @e index_page_CLASS @e index_element_CLASS @e index_tlexicon_entry_CLASS +@e simplified_scene_CLASS +@e simplified_end_CLASS +@e simplified_connector_CLASS = DECLARE_CLASS(I6T_intervention) @@ -46,6 +49,9 @@ DECLARE_CLASS(tree_inventory_item) DECLARE_CLASS(index_element) DECLARE_CLASS(index_page) DECLARE_CLASS(index_tlexicon_entry) +DECLARE_CLASS(simplified_scene) +DECLARE_CLASS(simplified_end) +DECLARE_CLASS(simplified_connector) @ Like all modules, this one must define a |start| and |end| function: @@ -62,9 +68,11 @@ void CodegenModule::end(void) { @ @e CODE_GENERATION_MREASON +@e SCENE_SORTING_MREASON @ = Memory::reason_name(CODE_GENERATION_MREASON, "code generation workspace for objects"); + Memory::reason_name(SCENE_SORTING_MREASON, "scene index sorting"); @ = ; diff --git a/inter/codegen-module/Chapter 6/Index File Services.w b/inter/codegen-module/Chapter 6/Index File Services.w index a84375018..1834efcde 100644 --- a/inter/codegen-module/Chapter 6/Index File Services.w +++ b/inter/codegen-module/Chapter 6/Index File Services.w @@ -660,12 +660,9 @@ void Index::index_actual_element(OUTPUT_STREAM, text_stream *elt) { if (Str::eq_wide_string(elt, L"Vb")) { VerbsElement::render(OUT); return; } if (Str::eq_wide_string(elt, L"Vl")) { ValuesElement::render(OUT); return; } if (Str::eq_wide_string(elt, L"Xt")) { ExtrasElement::render(OUT); return; } + if (Str::eq_wide_string(elt, L"Pl")) { PlotElement::render(OUT); return; } #ifdef CORE_MODULE - if (Str::eq_wide_string(elt, L"Pl")) { - IXScenes::render(OUT); - return; - } if (Str::eq_wide_string(elt, L"Mp")) { IXPhysicalWorld::render(OUT); return; diff --git a/inter/codegen-module/Chapter 6/Index Rules.w b/inter/codegen-module/Chapter 6/Index Rules.w index d4ba283ab..00990f2f9 100644 --- a/inter/codegen-module/Chapter 6/Index Rules.w +++ b/inter/codegen-module/Chapter 6/Index Rules.w @@ -25,7 +25,7 @@ inter_package *IndexRules::find_activity(tree_inventory *inv, text_stream *marke typedef struct ix_rule_context { struct inter_package *action_context; - struct inter_symbol *scene_context; + struct simplified_scene *scene_context; } ix_rule_context; ix_rule_context IndexRules::action_context(inter_package *an) { @@ -34,7 +34,7 @@ ix_rule_context IndexRules::action_context(inter_package *an) { rc.scene_context = NULL; return rc; } -ix_rule_context IndexRules::scene_context(inter_symbol *s) { +ix_rule_context IndexRules::scene_context(simplified_scene *s) { ix_rule_context rc; rc.action_context = NULL; rc.scene_context = s; @@ -58,7 +58,8 @@ int IndexRules::phrase_fits_rule_context(inter_package *entry, ix_rule_context r } if (rc.scene_context) { inter_symbol *scene_symbol = Metadata::read_optional_symbol(entry, I"^during"); - if (scene_symbol != rc.scene_context) return FALSE; + if (scene_symbol == NULL) return FALSE; + if (Inter::Packages::container(scene_symbol->definition) != rc.scene_context->pack) return FALSE; } return TRUE; } @@ -270,10 +271,8 @@ int IndexRules::index_rule(OUTPUT_STREAM, inter_tree *I, inter_package *R, inter @ = WRITE("%S", italicised_text); - if (rc.scene_context) { - inter_package *scene_pack = Inter::Packages::container(rc.scene_context->definition); - WRITE(" during %S", Metadata::read_optional_textual(scene_pack, I"^name")); - } + if (rc.scene_context) + WRITE(" during %S", PlotElement::scene_name(rc.scene_context)); WRITE("  "); @ diff --git a/inter/codegen-module/Chapter 6/Plot Element.w b/inter/codegen-module/Chapter 6/Plot Element.w new file mode 100644 index 000000000..4ff3b4641 --- /dev/null +++ b/inter/codegen-module/Chapter 6/Plot Element.w @@ -0,0 +1,445 @@ +[PlotElement::] Plot Element. + +To write the Plot element (Pl) in the index. + +@ The mapping of time is on the one hand simpler than the mapping of space +since there is only one dimension, but on the other hand more complex since +scenes can be multiply present at the same instant of time (whereas rooms +cannot be multiply present at the same point in space). We resolve this +with a notation which takes a little bit of on-screen explanation, but +seems natural enough to learn in practice. + +@d MAX_SCENE_ENDS 32 /* this must exceed 31 */ + += +typedef struct simplified_scene { + struct inter_package *pack; + int no_ends; + struct simplified_end *ends[MAX_SCENE_ENDS]; + int indexed_already; + CLASS_DEFINITION +} simplified_scene; + +typedef struct simplified_end { + struct inter_package *end_pack; + struct simplified_connector *anchor_connectors; /* linked list */ + CLASS_DEFINITION +} simplified_end; + +typedef struct simplified_connector { + struct inter_package *con_pack; + struct simplified_scene *connect_to; + struct simplified_connector *next; /* next in list of connectors for a scene end */ + CLASS_DEFINITION +} simplified_connector; + +simplified_scene *PlotElement::simplified(inter_tree *I, inter_package *sc_pack) { + simplified_scene *ssc = CREATE(simplified_scene); + ssc->pack = sc_pack; + ssc->no_ends = 0; + ssc->indexed_already = FALSE; + inter_symbol *wanted = PackageTypes::get(I, I"_scene_end"); + inter_symbol *wanted_within = PackageTypes::get(I, I"_scene_connector"); + inter_tree_node *D = Inter::Packages::definition(sc_pack); + LOOP_THROUGH_INTER_CHILDREN(C, D) { + if (C->W.data[ID_IFLD] == PACKAGE_IST) { + inter_package *entry = Inter::Package::defined_by_frame(C); + if (Inter::Packages::type(entry) == wanted) { + simplified_end *se = CREATE(simplified_end); + se->end_pack = entry; + se->anchor_connectors = NULL; + LOOP_THROUGH_INTER_CHILDREN(B, C) { + if (B->W.data[ID_IFLD] == PACKAGE_IST) { + inter_package *inner_entry = Inter::Package::defined_by_frame(B); + if (Inter::Packages::type(inner_entry) == wanted_within) { + simplified_connector *scon = CREATE(simplified_connector); + scon->con_pack = inner_entry; + scon->next = NULL; + if (se->anchor_connectors == NULL) { + se->anchor_connectors = scon; + } else { + simplified_connector *last = se->anchor_connectors; + while ((last) && (last->next)) last = last->next; + last->next = scon; + } + scon->connect_to = NULL; + } + } + } + if (ssc->no_ends >= MAX_SCENE_ENDS) internal_error("too many scene ends"); + ssc->ends[ssc->no_ends++] = se; + } + } + } + return ssc; +} + +int PlotElement::is_entire_game(simplified_scene *ssc) { + if (Metadata::read_optional_numeric(ssc->pack, I"^is_entire_game")) return TRUE; + return FALSE; +} + +int PlotElement::recurs(simplified_scene *ssc) { + if (Metadata::read_optional_numeric(ssc->pack, I"^recurs")) return TRUE; + return FALSE; +} + +int PlotElement::never_ends(simplified_scene *ssc) { + if (Metadata::read_optional_numeric(ssc->pack, I"^never_ends")) return TRUE; + return FALSE; +} + +int PlotElement::starts_at_start_of_play(simplified_scene *ssc) { + if (Metadata::read_optional_numeric(ssc->pack, I"^starts")) return TRUE; + return FALSE; +} + +int PlotElement::starts_on_condition(simplified_scene *ssc) { + if (Metadata::read_optional_numeric(ssc->pack, I"^starts_on_condition")) return TRUE; + return FALSE; +} + +int PlotElement::no_ends(simplified_scene *ssc) { + return ssc->no_ends; +} + +text_stream *PlotElement::scene_name(simplified_scene *ssc) { + return Metadata::read_textual(ssc->pack, I"^name"); +} + +text_stream *PlotElement::end_name(simplified_end *se) { + return Metadata::read_textual(se->end_pack, I"^name"); +} + +text_stream *PlotElement::anchor_condition(simplified_end *se) { + return Metadata::read_textual(se->end_pack, I"^condition"); +} + +int PlotElement::has_anchor_condition(simplified_end *se) { + if (Str::len(PlotElement::anchor_condition(se)) > 0) return TRUE; + return FALSE; +} + +int PlotElement::anchor_condition_set_at(simplified_end *se) { + return (int) Metadata::read_optional_numeric(se->end_pack, I"^at"); +} + +inter_symbol *PlotElement::end_rulebook(simplified_end *se) { + return Metadata::read_optional_symbol(se->end_pack, I"^rulebook"); +} + +simplified_scene *PlotElement::connects_to(simplified_connector *scon) { + if (scon->connect_to) return scon->connect_to; + inter_symbol *sc_symbol = Metadata::read_optional_symbol(scon->con_pack, I"^to"); + if (sc_symbol) { + inter_package *to_pack = Inter::Packages::container(sc_symbol->definition); + simplified_scene *ssc; + LOOP_OVER(ssc, simplified_scene) + if (ssc->pack == to_pack) { + scon->connect_to = ssc; + return ssc; + } + } + internal_error("scene metadata broken: bad connector"); + return NULL; +} + +int PlotElement::scon_end(simplified_connector *scon) { + return (int) Metadata::read_numeric(scon->con_pack, I"^end"); +} + +int PlotElement::scon_at(simplified_connector *scon) { + return (int) Metadata::read_numeric(scon->con_pack, I"^at"); +} + +void PlotElement::render(OUTPUT_STREAM) { + inter_tree *I = Index::get_tree(); + tree_inventory *inv = Synoptic::inv(I); + TreeLists::sort(inv->scene_nodes, PlotElement::scene_order); + TreeLists::sort(inv->rulebook_nodes, Synoptic::module_order); + + int no_scenes = TreeLists::len(inv->scene_nodes); + simplified_scene **plot = Memory::calloc(no_scenes, sizeof(simplified_scene *), SCENE_SORTING_MREASON); + for (int i=0; iscene_nodes->list[i].node)); + + @; + @; + @; + Memory::I7_array_free(plot, SCENE_SORTING_MREASON, no_scenes, sizeof(simplified_scene *)); +} + +@ The sorted ordering is used as-is later on, when we get to the details, but +for the tabulation it's refined further. First we have the start-of-play +scenes, in sorted order; then scenes with a condition for their beginning +(end 0), in sorted order; then scenes that don't, and which haven't been +covered as a result of one of the earlier ones, also in sorted order. (This +third category is usually empty except for scenes the author has forgotten +about and created but never made use of.) + +@ = + simplified_scene *ssc; + LOOP_OVER(ssc, simplified_scene) + if ((PlotElement::starts_at_start_of_play(ssc)) || (PlotElement::is_entire_game(ssc))) + PlotElement::index_from_scene(OUT, plot, ssc, 0, START_OF_PLAY_END, NULL); + LOOP_OVER(ssc, simplified_scene) + if ((PlotElement::starts_on_condition(ssc)) && (PlotElement::is_entire_game(ssc) == FALSE)) + PlotElement::index_from_scene(OUT, plot, ssc, 0, START_OF_PLAY_END, NULL); + LOOP_OVER(ssc, simplified_scene) + if (ssc->indexed_already == FALSE) + PlotElement::index_from_scene(OUT, plot, ssc, 0, NEVER_HAPPENS_END, NULL); + +@ = + HTML_OPEN("p"); WRITE("Legend: "); + PlotElement::scene_icon_legend(OUT, "WPB", "Begins when play begins"); + WRITE("; "); + PlotElement::scene_icon_legend(OUT, "WhenC", "can begin whenever some condition holds"); + WRITE("; "); + PlotElement::scene_icon_legend(OUT, "Segue", "follows when a previous scene ends"); + WRITE("; "); + PlotElement::scene_icon_legend(OUT, "Simul", "begins simultaneously"); + WRITE("; "); + PlotElement::scene_icon_legend(OUT, "WNever", "never begins"); + WRITE("; "); + PlotElement::scene_icon_legend(OUT, "ENever", "never ends"); + WRITE("; "); + PlotElement::scene_icon_legend(OUT, "Recurring", "recurring (can happen more than once)"); + WRITE(". Scene names are italicised when and if they appear for a second " + "or subsequent time because the scene can begin in more than one way."); + HTML_CLOSE("p"); + + +@ = + Index::anchor(OUT, I"SDETAILS"); + simplified_scene *ssc; + LOOP_OVER(ssc, simplified_scene) { + HTML_TAG("hr"); + @; + } + +@ The curious condition about end 1 here is to avoid printing "Ends: Never" +in cases where fancier ends for the scene exist, so that the scene can, in +fact, end. + +@ = + @; + if (PlotElement::is_entire_game(ssc)) @; + + for (int end=0; end 2) && + (PlotElement::has_anchor_condition(ssc->ends[1]) == FALSE) && + (ssc->ends[1]->anchor_connectors==NULL)) + continue; + @; + @; + if (end == 0) @; + } + +@ = + HTML::open_indented_p(OUT, 1, "hanging"); + Index::anchor_numbered(OUT, ssc->allocation_id); + WRITE("The %S scene", Metadata::read_textual(ssc->pack, I"^name")); + int at = (int) Metadata::read_optional_numeric(ssc->pack, I"^at"); + if (at > 0) Index::link(OUT, at); + if (PlotElement::recurs(ssc)) WRITE("  recurring"); + HTML_CLOSE("p"); + +@ = + HTML::open_indented_p(OUT, 1, "tight"); + WRITE("The Entire Game scene is built-in. It is going on whenever play is " + "going on. (It is recurring so that if the story ends, but then resumes, " + "it too will end but then begin again.)"); + HTML_CLOSE("p"); + +@ = + int rbc = 0; + for (int i=0; irulebook_nodes); i++) { + inter_package *pack = Inter::Package::defined_by_frame(inv->rulebook_nodes->list[i].node); + if (IndexRules::is_contextually_empty(I, pack, IndexRules::scene_context(ssc)) == FALSE) { + if (rbc++ == 0) { + HTML::open_indented_p(OUT, 1, "hanging"); + WRITE("During this scene:"); + HTML_CLOSE("p"); + } + HTML::open_indented_p(OUT, 2, "hanging"); + WRITE("%S", Metadata::read_textual(pack, I"^printed_name")); HTML_CLOSE("p"); + int ignore_me = 0; + IndexRules::index_rulebook(OUT, I, pack, I"", IndexRules::scene_context(ssc), &ignore_me); + } + } + +@ = + HTML::open_indented_p(OUT, 1, "hanging"); + WRITE("%s ", (end==0)?"Begins":"Ends"); + if (end >= 2) WRITE("%S ", PlotElement::end_name(ssc->ends[end])); + WRITE("when: "); + int count = 0; + @; + @; + @; + if (count == 0) WRITE("never"); + HTML_CLOSE("p"); + +@ = + if ((end==0) && (PlotElement::starts_at_start_of_play(ssc))) { + if (count > 0) { + HTML_TAG("br"); + WRITE("or when: "); + } + WRITE("play begins"); + count++; + } + +@ = + if (PlotElement::has_anchor_condition(ssc->ends[end])) { + if (count > 0) { + HTML_TAG("br"); + WRITE("or when: "); + } + WRITE("%S", PlotElement::anchor_condition(ssc->ends[end])); + int at = PlotElement::anchor_condition_set_at(ssc->ends[end]); + if (at > 0) Index::link(OUT, at); + count++; + } + +@ = + for (simplified_connector *scon = ssc->ends[end]->anchor_connectors; scon; scon=scon->next) { + if (count > 0) { + HTML_TAG("br"); + WRITE("or when: "); + } + simplified_scene *to_ssc = PlotElement::connects_to(scon); + text_stream *NW = PlotElement::scene_name(to_ssc); + WRITE("%S %s", NW, (PlotElement::scon_end(scon)==0)?"begins":"ends"); + if (PlotElement::scon_end(scon) >= 2) WRITE(" %S", PlotElement::end_name(to_ssc->ends[PlotElement::scon_end(scon)])); + Index::link(OUT, PlotElement::scon_at(scon)); + count++; + } + +@ = + inter_symbol *rb = PlotElement::end_rulebook(ssc->ends[end]); + inter_package *rb_pack = Inter::Packages::container(rb->definition); + if (IndexRules::no_rules(I, rb_pack) > 0) { + HTML::open_indented_p(OUT, 1, "hanging"); + WRITE("What happens:"); HTML_CLOSE("p"); + int ignore_me = 0; + IndexRules::index_rulebook(OUT, I, rb_pack, I"", IndexRules::no_rule_context(), &ignore_me); + } + +@h Table of Scenes. +We finally return to the table of scenes. The following is recursive, and +is called at the top level for each scene in turn which starts at the start +of play (see above). + +A scene entry can be arrived at in three ways: through one of its ends, in +which case |end| is the number (0 for begins, 1 for standard ends, and so on), +or through being already active at the start of play, or through being covered +in the index even though it never happens in play. This means we need two +additional |end| numbers. They are only ever used at the top level, that is, +on the initial call when |depth| is 0. + +@d START_OF_PLAY_END -1 +@d NEVER_HAPPENS_END -2 + += +void PlotElement::index_from_scene(OUTPUT_STREAM, simplified_scene **plot, + simplified_scene *ssc, int depth, int end, simplified_scene *sc_from) { + HTML::open_indented_p(OUT, depth+1, "tight"); + @; + @; + if (ssc->indexed_already == FALSE) { + @; + @; + } + HTML_CLOSE("p"); + if (ssc->indexed_already) return; + ssc->indexed_already = TRUE; + @; +} + +@ = + switch(end) { + case 0: PlotElement::scene_icon(OUT, "Simul"); break; + case 1: PlotElement::scene_icon(OUT, "Segue"); break; + case START_OF_PLAY_END: break; + case NEVER_HAPPENS_END: PlotElement::scene_icon(OUT, "WNever"); break; + default: + PlotElement::scene_icon(OUT, "Segue"); + WRITE("[ends %S] ", PlotElement::end_name(sc_from->ends[end])); break; + } + if ((ssc->indexed_already == FALSE) || (depth == 0)) { + if (PlotElement::is_entire_game(ssc)) PlotElement::scene_icon(OUT, "WPB"); + else if (PlotElement::starts_on_condition(ssc)) PlotElement::scene_icon(OUT, "WhenC"); + if (PlotElement::starts_at_start_of_play(ssc)) PlotElement::scene_icon(OUT, "WPB"); + } + +@ = + if (ssc->indexed_already) WRITE(""); + WRITE("%S", Metadata::read_textual(ssc->pack, I"^name")); + if (ssc->indexed_already) WRITE(""); + else Index::below_link_numbered(OUT, ssc->allocation_id); + +@ = + if (PlotElement::never_ends(ssc)) + PlotElement::scene_icon_append(OUT, "ENever"); + +@ = + if (PlotElement::recurs(ssc)) + PlotElement::scene_icon_append(OUT, "Recurring"); + +@ And this is where the routine recurses, so that consequent scenes are +tabulated underneath the present one, indented one step further in (since +indentation is coupled to |depth|). First we recurse to scenes which end when +this one does; then to scenes which begin when this one ends. + +@ = + simplified_scene *ssc2; + LOOP_OVER(ssc2, simplified_scene) { + for (simplified_connector *scon = ssc2->ends[0]->anchor_connectors; scon; scon=scon->next) + if ((PlotElement::connects_to(scon) == ssc) && (PlotElement::scon_end(scon) >= 1)) + PlotElement::index_from_scene(OUT, plot, ssc2, depth + 1, PlotElement::scon_end(scon), ssc); + } + LOOP_OVER(ssc2, simplified_scene) { + for (simplified_connector *scon = ssc2->ends[0]->anchor_connectors; scon; scon=scon->next) + if ((PlotElement::connects_to(scon) == ssc) && (PlotElement::scon_end(scon) == 0)) + PlotElement::index_from_scene(OUT, plot, ssc2, depth, PlotElement::scon_end(scon), ssc); + } + +@ We have been using: + += +void PlotElement::scene_icon(OUTPUT_STREAM, char *si) { + PlotElement::scene_icon_unspaced(OUT, si); WRITE("  "); +} + +void PlotElement::scene_icon_append(OUTPUT_STREAM, char *si) { + WRITE("  "); PlotElement::scene_icon_unspaced(OUT, si); +} + +void PlotElement::scene_icon_legend(OUTPUT_STREAM, char *si, char *gloss) { + PlotElement::scene_icon_unspaced(OUT, si); WRITE(" %s", gloss); +} + +void PlotElement::scene_icon_unspaced(OUTPUT_STREAM, char *si) { + HTML_TAG_WITH("img", "border=0 src=inform:/scene_icons/%s.png", si); +} + +@ Lastly: the following is the criterion used for sorting the scenes into +their indexing order. The Entire Game always comes first, and then come the +rest in ascending alphabetical order. + += +int PlotElement::scene_order(const void *ent1, const void *ent2) { + itl_entry *E1 = (itl_entry *) ent1; + itl_entry *E2 = (itl_entry *) ent2; + if (E1 == E2) return 0; + inter_tree_node *P1 = E1->node; + inter_tree_node *P2 = E2->node; + inter_package *sc1 = Inter::Package::defined_by_frame(P1); + inter_package *sc2 = Inter::Package::defined_by_frame(P2); + if (Metadata::read_optional_numeric(sc1, I"^is_entire_game")) return -1; + if (Metadata::read_optional_numeric(sc2, I"^is_entire_game")) return 1; + text_stream *SW1 = Metadata::read_textual(sc1, I"^name"); + text_stream *SW2 = Metadata::read_textual(sc2, I"^name"); + return Str::cmp(SW1, SW2); +} diff --git a/inter/codegen-module/Contents.w b/inter/codegen-module/Contents.w index 3a73f7012..a1fbaa866 100644 --- a/inter/codegen-module/Contents.w +++ b/inter/codegen-module/Contents.w @@ -81,3 +81,4 @@ Chapter 6: Index Gazetteer Element Lexicon Element Arithmetic Element + Plot Element