From 23cb64fdd2a1d2654278e48eecded9455647872d Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Fri, 5 Mar 2021 23:36:25 +0000 Subject: [PATCH] Further work on plugin calls for actions --- docs/assertions-module/3-dbtr.html | 4 +- docs/assertions-module/3-pr.html | 2 +- docs/assertions-module/4-ass.html | 27 +- docs/assertions-module/4-ass2.html | 2 +- docs/assertions-module/4-pk.html | 2 +- docs/assertions-module/4-rpt.html | 8 +- docs/assertions-module/4-tc.html | 460 ++++++++---------- docs/assertions-module/5-tc.html | 2 +- docs/assertions-module/6-cu.html | 10 +- docs/calculus-module/5-smp.html | 4 +- docs/core-module/3-pc.html | 93 +++- docs/if-module/3-scn.html | 35 +- docs/if-module/4-ac.html | 106 ++++ docs/if-module/4-act.html | 4 +- docs/if-module/4-ak.html | 206 ++++++++ docs/if-module/4-anaa.html | 107 +++- docs/if-module/4-anl.html | 32 +- docs/if-module/4-ann.html | 14 +- docs/if-module/4-ap.html | 234 ++++----- docs/if-module/4-ap2.html | 88 +--- docs/if-module/4-apc.html | 36 +- docs/if-module/4-as.html | 26 +- docs/if-module/4-av.html | 6 +- docs/if-module/4-ea.html | 149 ++++++ docs/if-module/4-gng.html | 16 +- docs/if-module/4-nap.html | 6 +- docs/if-module/4-pap.html | 225 +++++---- docs/if-module/5-gpr.html | 2 +- docs/if-module/5-gt2.html | 4 +- docs/if-module/5-pp.html | 58 ++- docs/if-module/5-tfg.html | 2 +- docs/if-module/index.html | 15 + docs/imperative-module/4-chr.html | 3 +- docs/imperative-module/6-pi.html | 2 +- docs/runtime-module/5-act.html | 2 +- docs/runtime-module/5-ap.html | 3 +- docs/values-module/2-cnd.html | 112 ++--- docs/values-module/2-dsc.html | 2 +- docs/values-module/2-dsh.html | 16 +- docs/values-module/2-rvl.html | 125 ++--- docs/values-module/2-spc.html | 10 +- docs/values-module/3-ll.html | 2 +- docs/values-module/4-cap.html | 14 +- docs/values-module/4-ets.html | 4 +- docs/values-module/4-teav.html | 30 -- docs/values-module/4-varc.html | 2 +- inform7/Downloads/preform-diagnostics.txt | 158 +++--- inform7/Downloads/syntax-diagnostics.txt | 2 +- inform7/Figures/memory-diagnostics.txt | 6 +- inform7/Figures/timings-diagnostics.txt | 28 +- inform7/Tests/Groups/actions.testgroup | 2 + .../assertions-module/Chapter 4/Assertions.w | 15 +- .../Chapter 4/Refine Parse Tree.w | 4 +- .../assertions-module/Chapter 4/The Creator.w | 58 +-- inform7/core-module/Chapter 3/Plugin Calls.w | 38 +- inform7/if-module/Chapter 3/Scenes.w | 13 + .../if-module/Chapter 4/Action Conditions.w | 25 + inform7/if-module/Chapter 4/Action Kinds.w | 115 +++++ .../if-module/Chapter 4/Action Name Names.w | 2 +- .../Chapter 4/Action Pattern Clauses.w | 2 +- inform7/if-module/Chapter 4/Action Patterns.w | 75 +-- .../if-module/Chapter 4/Action Variables.w | 2 +- inform7/if-module/Chapter 4/Actions Plugin.w | 84 ++-- .../Actions-Only Nodes and Annotations.w | 74 +++ .../if-module/Chapter 4/Explicit Actions.w | 68 +++ .../Chapter 4/Named Action Patterns.w | 4 +- .../Chapter 4/Parse Action Patterns.w | 27 +- inform7/if-module/Chapter 5/Grammar Tokens.w | 4 +- inform7/if-module/Chapter 5/Parsing Plugin.w | 16 + inform7/if-module/Contents.w | 3 + .../imperative-module/Chapter 4/Chronology.w | 3 +- .../Chapter 6/Parse Invocations.w | 2 +- .../Chapter 5/Action Patterns.w | 3 +- inform7/runtime-module/Chapter 5/Actions.w | 2 +- inform7/values-module/Chapter 2/Conditions.w | 49 +- inform7/values-module/Chapter 2/Dash.w | 10 +- inform7/values-module/Chapter 2/Rvalues.w | 45 +- .../values-module/Chapter 3/Literal Lists.w | 2 +- .../Chapter 4/Conditions and Phrases.w | 10 +- .../Chapter 4/Enter the S-Parser.w | 4 +- .../Chapter 4/Type Expressions and Values.w | 28 -- .../Chapter 5/Simplifications.w | 4 +- 82 files changed, 1913 insertions(+), 1386 deletions(-) create mode 100644 docs/if-module/4-ac.html create mode 100644 docs/if-module/4-ak.html create mode 100644 docs/if-module/4-ea.html create mode 100644 inform7/if-module/Chapter 4/Action Conditions.w create mode 100644 inform7/if-module/Chapter 4/Action Kinds.w create mode 100644 inform7/if-module/Chapter 4/Explicit Actions.w diff --git a/docs/assertions-module/3-dbtr.html b/docs/assertions-module/3-dbtr.html index 97484e7af..a46eb5bc0 100644 --- a/docs/assertions-module/3-dbtr.html +++ b/docs/assertions-module/3-dbtr.html @@ -380,7 +380,7 @@ have occurred, but if it does then the creation has worked. if ((evaluation) && (Node::is(evaluation, UNKNOWN_NT) == FALSE)) Issue a problem for trying to create any existing meaning as a new instance4.1.3.3; - Assertions::Creator::tabular_definitions(t); + Assertions::Creator::tabular_definitions(t); NounPhrases::annotate_by_articles(name_entry); ProblemBuffer::redirect_problem_sentence(current_sentence, name_entry, V->next); if (Refiner::refine_coupling(name_entry, V->next, FALSE)) @@ -393,7 +393,7 @@ have occurred, but if it does then the creation has worked. else if (<s-type-expression>(Node::get_text(name_entry))) evaluation = <<rp>>; Refiner::give_spec_to_noun(name_entry, evaluation); - Assertions::Creator::tabular_definitions(NULL); + Assertions::Creator::tabular_definitions(NULL); if (Node::get_subject(name_entry) == NULL) Issue a problem to say that the creation failed4.1.3.4; diff --git a/docs/assertions-module/3-pr.html b/docs/assertions-module/3-pr.html index bddd7fd85..626eedc0e 100644 --- a/docs/assertions-module/3-pr.html +++ b/docs/assertions-module/3-pr.html @@ -109,7 +109,7 @@ end well. wording S = Node::get_text(V->next); wording P = Node::get_text(V->next->next); Forbid plural declarations containing quoted text2.1; - if (Assertions::Creator::vet_name_for_noun(P) == FALSE) return TRUE; + if (Assertions::Creator::vet_name_for_noun(P) == FALSE) return TRUE; Pluralisation::register(S, P, DefaultLanguage::get(NULL)); return TRUE; } diff --git a/docs/assertions-module/4-ass.html b/docs/assertions-module/4-ass.html index 09b815782..b73b5d494 100644 --- a/docs/assertions-module/4-ass.html +++ b/docs/assertions-module/4-ass.html @@ -108,7 +108,7 @@ example, the subtree for "an open door". case COMMON_NOUN_NT: if ((InferenceSubjects::is_a_kind_of_object(Node::get_subject(py))) || (Kinds::eq(K_object, KindSubjects::to_kind(Node::get_subject(py))))) - Assertions::Creator::convert_instance_to_nounphrase(py, NULL); + Assertions::Creator::convert_instance_to_nounphrase(py, NULL); else StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_ThereIsVague), "'there is...' can only be used to create objects", @@ -303,7 +303,7 @@ of px and §6. Splitting into cases.

-void Assertions::make_coupling(parse_node *px, parse_node *py) {
+void Assertions::make_coupling(parse_node *px, parse_node *py) {
     LOG_INDENT;
     Assertions::make_assertion_recursive_inner(px, py);
     LOG_OUTDENT;
@@ -809,19 +809,10 @@ further sub-cases later.
         Problems::issue_problem_end();
         return;
     }
-    #ifdef IF_MODULE
-    if (Node::get_type(py) == ACTION_NT) {
-        action_pattern *ap = Node::get_action_meaning(py);
-        if (ap) {
-            parse_node *val = Rvalues::from_action_pattern(ap);
-            if (Rvalues::is_CONSTANT_of_kind(val, K_stored_action)) {
-                Refiner::give_spec_to_noun(py, val);
-                Assertions::make_coupling(px, py);
-                return;
-            }
-        }
+    if (PluginCalls::unusual_property_value(py)) {
+        Assertions::make_coupling(px, py);
+        return;
     }
-    #endif
     Problems::Using::assertion_problem(Task::syntax_tree(), _p_(PM_PeculiarProperty),
         "that is a very peculiar property value",
         "and ought to be something more definite and explicit.");
@@ -1605,7 +1596,7 @@ in general.
 
 
     if (Annotations::read_int(px, multiplicity_ANNOT) >= 1) {
-        Assertions::Creator::convert_instance_to_nounphrase(px, NULL);
+        Assertions::Creator::convert_instance_to_nounphrase(px, NULL);
         Assertions::make_coupling(py, px);
         return;
     }
@@ -1642,7 +1633,7 @@ in general.
 
 
     if (Annotations::read_int(current_sentence->down, sentence_is_existential_ANNOT)) {
-        Assertions::Creator::convert_instance_to_nounphrase(px, NULL);
+        Assertions::Creator::convert_instance_to_nounphrase(px, NULL);
         Assertions::make_coupling(py, px);
         return;
     }
@@ -1661,7 +1652,7 @@ in general.
     if ((px->down) && (Node::get_type(px->down) == EVERY_NT)) {
         if (global_pass_state.pass == 1) Assertions::Assemblies::make_generalisation(px, py);
     } else {
-        Assertions::Creator::convert_instance_to_nounphrase(py, Node::get_relationship(px));
+        Assertions::Creator::convert_instance_to_nounphrase(py, Node::get_relationship(px));
         Assertions::make_coupling(px, py);
     }
 
@@ -2536,7 +2527,7 @@ can also be used adjectivally. void Assertions::instantiate_related_common_nouns_r(parse_node *from, parse_node *at) { if (at == NULL) return; if (Node::get_type(at) == COMMON_NOUN_NT) - Assertions::Creator::convert_instance_to_nounphrase(at, + Assertions::Creator::convert_instance_to_nounphrase(at, Node::get_relationship(from)); if (Node::get_type(at) == AND_NT) { Assertions::instantiate_related_common_nouns_r(from, at->down); diff --git a/docs/assertions-module/4-ass2.html b/docs/assertions-module/4-ass2.html index b6fed7a74..f92700f6a 100644 --- a/docs/assertions-module/4-ass2.html +++ b/docs/assertions-module/4-ass2.html @@ -170,7 +170,7 @@ each inference subject:

-void Assertions::Assemblies::name_object_after(inference_subject *infs, inference_subject *after, wording W) {
+void Assertions::Assemblies::name_object_after(inference_subject *infs, inference_subject *after, wording W) {
     assemblies_data *ad = InferenceSubjects::get_assemblies_data(infs);
     ad->named_after = after;
     ad->named_after_text = W;
diff --git a/docs/assertions-module/4-pk.html b/docs/assertions-module/4-pk.html
index f4bc3f9fe..e739fbc77 100644
--- a/docs/assertions-module/4-pk.html
+++ b/docs/assertions-module/4-pk.html
@@ -102,7 +102,7 @@ either as an object, a value or a subtree — should have
     Assert::true_about(prop, owner, prevailing_mood);
 }
 
-void Assertions::PropertyKnowledge::assert_property_list(parse_node *owner_subtree,
+void Assertions::PropertyKnowledge::assert_property_list(parse_node *owner_subtree,
     parse_node *list_subtree) {
     Check that the owner subtree isn't dangerously elaborate2.2;
     inference_subject *owner = Node::get_subject(owner_subtree);
diff --git a/docs/assertions-module/4-rpt.html b/docs/assertions-module/4-rpt.html
index be7e7d9cf..8696c9cc7 100644
--- a/docs/assertions-module/4-rpt.html
+++ b/docs/assertions-module/4-rpt.html
@@ -91,12 +91,12 @@ true — "an open door", say, or "a woman in London" — these are recor
 in a creation_proposition annotation.
 
 
-void Refiner::give_subject_to_noun(parse_node *p, inference_subject *infs) {
+void Refiner::give_subject_to_noun(parse_node *p, inference_subject *infs) {
     parse_node *eval = InferenceSubjects::as_constant(infs);
     Make a common or proper noun as appropriate1.1;
 }
 
-void Refiner::give_spec_to_noun(parse_node *p, parse_node *eval) {
+void Refiner::give_spec_to_noun(parse_node *p, parse_node *eval) {
     inference_subject *infs = Specifications::to_subject(eval);
     Make a common or proper noun as appropriate1.1;
 }
@@ -431,7 +431,7 @@ is allowed to stand.
             Wordings::last_wn(Node::get_text(p->down->next)));
         if (Wordings::nonempty(W)) {
             if (<action-pattern>(W)) {
-                ActionPatterns::make_ACTION_node(p, <<rp>>);
+                ActionsNodes::convert_to_ACTION_node(p, <<rp>>);
                 Node::set_text(p, W);
             }
         }
@@ -799,7 +799,7 @@ here, given that we know we are looking for a noun.
     #ifdef IF_MODULE
     if (Node::get_article(p) == NULL) {
         if (<action-pattern>(Node::get_text(p))) {
-            ActionPatterns::make_ACTION_node(p, <<rp>>);
+            ActionsNodes::convert_to_ACTION_node(p, <<rp>>);
             return;
         }
     }
diff --git a/docs/assertions-module/4-tc.html b/docs/assertions-module/4-tc.html
index df81bc949..8d167dd87 100644
--- a/docs/assertions-module/4-tc.html
+++ b/docs/assertions-module/4-tc.html
@@ -73,7 +73,7 @@ function togglePopup(material_id) {
     
 

This is where all objects, kinds of object, named values, kinds of value and global variables are made.

-
+

§1. Creations to match unrecognised names. The model contains objects, their properties and their relationships, and this section is where all of the objects are created — not only world @@ -140,7 +140,7 @@ room."

-    Assertions::Creator::noun_creator(py, NULL, NULL);
+    Assertions::Creator::noun_creator(py, NULL, NULL);
 
  • This code is used in §1.

§1.2. More generally we need to work out what px tells us about creations in py, @@ -164,55 +164,15 @@ in py, which (i

-    Take care of two ambiguities to do with actions1.2.1;
+    PluginCalls::creation(px, py);
     parse_node *govx = NULL, *govy = NULL;
     kind *kindx = NULL, *kindy = NULL;
-    Work out the kinds of value expressed by each side, and find their governing nodes1.2.2;
-    Assertions::Creator::noun_creator(px, kindy, govy);
-    Assertions::Creator::noun_creator(py, kindx, govx);
+    Work out the kinds of value expressed by each side, and find their governing nodes1.2.1;
+    Assertions::Creator::noun_creator(px, kindy, govy);
+    Assertions::Creator::noun_creator(py, kindx, govx);
 
  • This code is used in §1.
-

§1.2.1. The first case here is to take care of a sentence like: -

- -
-

Taking something is proactive behaviour.

-
- -

Here Refiner::refine will correctly report that "proactive behaviour" is -a new term, and give it a CREATED_NT node. But we don't want it to become an -object or a value — it will become a named kind of action instead. So we -amend the node to ACTION_NT. -

- -

The second case occurs much less often — for instance, the only time it comes -up in the test suite is in the example "Chronic Hinting Syndrome": -

- -
-

Setting is a kind of value. The settings are bright and dull.

-
- -

Here the first sentence wants to create something called "setting", which -ought to have a CREATED_NT node type, but doesn't because it has been read -as an action instead. We correct the spurious ACTION_NT to a CREATED_NT. -

- -

Take care of two ambiguities to do with actions1.2.1 = -

- -
-    if ((Assertions::Creator::actionlike(px)) && (Node::get_type(py) == CREATED_NT))
-        Node::set_type(py, ACTION_NT);
-    if ((Assertions::Creator::actionlike(px)) && (Assertions::Creator::actionlike(py))) {
-        Assertions::Creator::to_action_node(px);
-        Assertions::Creator::to_action_node(py);
-    }
-    if ((Node::get_type(px) == ACTION_NT) && (Node::get_type(py) == KIND_NT))
-        Node::set_type(px, CREATED_NT);
-
-
  • This code is used in §1.2.
-

§1.2.2. There are two ways to know the kind being expressed. One is that the sentence +

§1.2.1. There are two ways to know the kind being expressed. One is that the sentence makes unambiguous use of a relation which forces the kinds on each side. For example,

@@ -242,12 +202,12 @@ kind of its second term. So we do so on its behalf.

Green is a colour.

-

Work out the kinds of value expressed by each side, and find their governing nodes1.2.2 = +

Work out the kinds of value expressed by each side, and find their governing nodes1.2.1 =

-    binary_predicate *bp = Assertions::Creator::bp_of_subtree(py);
-    if (bp == NULL) bp = Assertions::Creator::bp_of_subtree(px);
+    binary_predicate *bp = Assertions::Creator::bp_of_subtree(py);
+    if (bp == NULL) bp = Assertions::Creator::bp_of_subtree(px);
     if (bp) {
         kindx = Kinds::weaken(BinaryPredicates::term_kind(bp, 0), K_object);
         kindy = Kinds::weaken(BinaryPredicates::term_kind(bp, 1), K_object);
@@ -257,97 +217,67 @@ kind of its second term. So we do so on its behalf.
         #endif
     }
     if ((kindx == NULL) || (kindy == NULL)) {
-        kindx = Assertions::Creator::kind_of_subtree(px, &govx);
-        kindy = Assertions::Creator::kind_of_subtree(py, &govy);
+        kindx = Assertions::Creator::kind_of_subtree(px, &govx);
+        kindy = Assertions::Creator::kind_of_subtree(py, &govy);
     }
 
  • This code is used in §1.2.
-

§2.

- -
-int Assertions::Creator::actionlike(parse_node *p) {
-    #ifdef IF_MODULE
-    if (Node::get_type(p) == ACTION_NT) return TRUE;
-    if (Node::get_type(p) == PROPER_NOUN_NT) {
-        parse_node *spec = Node::get_evaluation(p);
-        if (Rvalues::is_CONSTANT_of_kind(spec, K_stored_action))
-            return TRUE;
-    }
-    #endif
-    return FALSE;
-}
-
-void Assertions::Creator::to_action_node(parse_node *p) {
-    #ifdef IF_MODULE
-    if (Node::get_type(p) == ACTION_NT) return;
-    if (Node::get_type(p) == PROPER_NOUN_NT) {
-        parse_node *spec = Node::get_evaluation(p);
-        if (Rvalues::is_CONSTANT_of_kind(spec, K_stored_action)) {
-            explicit_action *ea = Node::get_constant_explicit_action(spec);
-            ActionPatterns::make_ACTION_node(p, ea->as_described);
-            return;
-        }
-    }
-    #endif
-    internal_error("misapplied to_action_node");
-}
-
-

§3. So that just leaves the algorithms for finding the relation of a subtree: +

§2. So that just leaves the algorithms for finding the relation of a subtree:

-binary_predicate *Assertions::Creator::bp_of_subtree(parse_node *p) {
+binary_predicate *Assertions::Creator::bp_of_subtree(parse_node *p) {
     if ((p) && (Node::get_type(p) == RELATIONSHIP_NT)) return Node::get_relationship(p);
     return NULL;
 }
 
-

§4. And the kind of a subtree. +

§3. And the kind of a subtree.

-kind *Assertions::Creator::kind_of_subtree(parse_node *p, parse_node **governing) {
+kind *Assertions::Creator::kind_of_subtree(parse_node *p, parse_node **governing) {
     if (p == NULL) return NULL;
     switch (Node::get_type(p)) {
-        case AND_NT: Recurse downwards, preferring the leftmost item in a list4.1;
-        case WITH_NT: return Assertions::Creator::kind_of_subtree(p->down, governing);  the owner, not the property
-        case KIND_NT: Handle the kind of a "kind of..." clause4.2;
+        case AND_NT: Recurse downwards, preferring the leftmost item in a list3.1;
+        case WITH_NT: return Assertions::Creator::kind_of_subtree(p->down, governing);  the owner, not the property
+        case KIND_NT: Handle the kind of a "kind of..." clause3.2;
         default: {
             parse_node *spec = Node::get_evaluation(p);
-            Kinds of variable and of value produce the obvious kind as result4.3;
-            Initially values produce their own weakened kind4.4;
-            Descriptions produce the kind of whatever's described4.6;
-            Property names coinciding with kinds are considered with their kind meanings4.5;
+            Kinds of variable and of value produce the obvious kind as result3.3;
+            Initially values produce their own weakened kind3.4;
+            Descriptions produce the kind of whatever's described3.6;
+            Property names coinciding with kinds are considered with their kind meanings3.5;
         }
     }
     return NULL;
 }
 
-

§4.1. Recurse downwards, preferring the leftmost item in a list4.1 = +

§3.1. Recurse downwards, preferring the leftmost item in a list3.1 =

-    kind *left = Assertions::Creator::kind_of_subtree(p->down, governing);
-    kind *right = Assertions::Creator::kind_of_subtree(p->down->next, governing);
+    kind *left = Assertions::Creator::kind_of_subtree(p->down, governing);
+    kind *right = Assertions::Creator::kind_of_subtree(p->down->next, governing);
     if (left) return left;
     return right;
 
-
  • This code is used in §4.
-

§4.2. Refinement has already parsed a KIND subtree and left the resulting domain +

  • This code is used in §3.
+

§3.2. Refinement has already parsed a KIND subtree and left the resulting domain in the node's subject, so this case is easy.

-

Handle the kind of a "kind of..." clause4.2 = +

Handle the kind of a "kind of..." clause3.2 =

     *governing = p;
     return KindSubjects::to_kind(Node::get_subject(p));
 
-
  • This code is used in §4.
-

§4.3. Less surprisingly, "number that varies" and "number" return K_number. +

  • This code is used in §3.
+

§3.3. Less surprisingly, "number that varies" and "number" return K_number.

-

Kinds of variable and of value produce the obvious kind as result4.3 = +

Kinds of variable and of value produce the obvious kind as result3.3 =

@@ -364,8 +294,8 @@ in the node's subject, so this case is easy.
         return found;
     }
 
-
  • This code is used in §4.
-

§4.4. Initially values produce their own weakened kind4.4 = +

  • This code is used in §3.
+

§3.4. Initially values produce their own weakened kind3.4 =

@@ -377,8 +307,8 @@ in the node's subject, so this case is easy.
         }
     }
 
-
  • This code is used in §4.
-

§4.5. Property names coinciding with kinds are considered with their kind meanings4.5 = +

  • This code is used in §3.
+

§3.5. Property names coinciding with kinds are considered with their kind meanings3.5 =

@@ -389,11 +319,11 @@ in the node's subject, so this case is easy.
             return ValueProperties::kind(prn);
     }
 
-
  • This code is used in §4.
-

§4.6. And similarly "even number" returns K_number. +

  • This code is used in §3.
+

§3.6. And similarly "even number" returns K_number.

-

Descriptions produce the kind of whatever's described4.6 = +

Descriptions produce the kind of whatever's described3.6 =

@@ -402,8 +332,8 @@ in the node's subject, so this case is easy.
         return Specifications::to_kind(spec);
     }
 
-
  • This code is used in §4.
-

§5. Acting on creations. Building and refining the parse tree was a compositional process, in a linguistic +

  • This code is used in §3.
+

§4. Acting on creations. Building and refining the parse tree was a compositional process, in a linguistic sense: what you do at any given position depends only on the current phrase and its contents, or equivalently, on the current node and its children.

@@ -432,20 +362,20 @@ both of which are excised and replaced with table *allow_tabular_definitions_from = NULL; -void Assertions::Creator::tabular_definitions(table *t) { +void Assertions::Creator::tabular_definitions(table *t) { allow_tabular_definitions_from = t; } -void Assertions::Creator::noun_creator(parse_node *p, kind *create_as, parse_node *governor) { +void Assertions::Creator::noun_creator(parse_node *p, kind *create_as, parse_node *governor) { switch (Node::get_type(p)) { - case CALLED_NT: Check we are sure about this5.1; Perform creation on a CALLED node5.2; return; - case CREATED_NT: Check we are sure about this5.1; Perform creation on a CREATED node5.4; return; + case CALLED_NT: Check we are sure about this4.1; Perform creation on a CALLED node4.2; return; + case CREATED_NT: Check we are sure about this4.1; Perform creation on a CREATED node4.4; return; } parse_node *ch; - for (ch = p->down; ch; ch = ch->next) Assertions::Creator::noun_creator(ch, create_as, governor); + for (ch = p->down; ch; ch = ch->next) Assertions::Creator::noun_creator(ch, create_as, governor); }
-

§5.1. Check we are sure about this5.1 = +

§4.1. Check we are sure about this4.1 =

@@ -455,8 +385,8 @@ both of which are excised and replaced with             "not that they don't.");
     }
 
-
  • This code is used in §5 (twice), §8.
-

§5.2. CALLED nodes allow a much more generous range of names to be used — that's +

  • This code is used in §4 (twice), §7.
+

§4.2. CALLED nodes allow a much more generous range of names to be used — that's the whole point of them. Really they contain the whole language in miniature, because a "called" clause can specify not only the name but also its kind, some properties which it has, and so forth. For example: @@ -479,7 +409,7 @@ is important for sentences like: an object, but we know locally that Peter must further have the kind "man".

-

Perform creation on a CALLED node5.2 = +

Perform creation on a CALLED node4.2 =

@@ -488,25 +418,25 @@ an object, but we know locally that Peter must further have the kind "man".
 
     if ((Node::get_type(what_to_make_node) != COMMON_NOUN_NT) &&
         (Node::get_type(what_to_make_node) != WITH_NT)) {
-        Complain that nothing else can be called5.2.3; return;
+        Complain that nothing else can be called4.2.3; return;
     }
 
     parse_node *local_governor = NULL;
-    kind *local_create_as = Assertions::Creator::kind_of_subtree(what_to_make_node, &local_governor);
+    kind *local_create_as = Assertions::Creator::kind_of_subtree(what_to_make_node, &local_governor);
     if (local_create_as == NULL) { local_create_as = create_as; local_governor = governor; }
-    Assertions::Creator::noun_creator(called_name_node, local_create_as, local_governor);
+    Assertions::Creator::noun_creator(called_name_node, local_create_as, local_governor);
 
-    Replace the CALLED subtree with the new creation, mutatis mutandis5.2.1;
-    If the CALLED name used the definite article, make a note of that5.2.2;
+    Replace the CALLED subtree with the new creation, mutatis mutandis4.2.1;
+    If the CALLED name used the definite article, make a note of that4.2.2;
 
-
  • This code is used in §5.
-

§5.2.1. This is where we act on the miniature sentence implied by the CALLED +

  • This code is used in §4.
+

§4.2.1. This is where we act on the miniature sentence implied by the CALLED subtree. We replace the subtree with a single node — the result of creation on the called_name_node side — but then apply to it any kind, proposition or adjectives specified in the what_to_make_node side.

-

Replace the CALLED subtree with the new creation, mutatis mutandis5.2.1 = +

Replace the CALLED subtree with the new creation, mutatis mutandis4.2.1 =

@@ -523,8 +453,8 @@ or adjectives specified in the     if (Node::get_type(what_to_make_node) == WITH_NT)
         Assertions::PropertyKnowledge::assert_property_list(p, what_to_make_node->down->next);
 
-
  • This code is used in §5.2.
-

§5.2.2. Ordinarily the use of the definite article doesn't tell us much, but +

  • This code is used in §4.2.
+

§4.2.2. Ordinarily the use of the definite article doesn't tell us much, but consider the following two sentences:

@@ -537,7 +467,7 @@ consider the following two sentences: is why the following only applies to those.)

-

If the CALLED name used the definite article, make a note of that5.2.2 = +

If the CALLED name used the definite article, make a note of that4.2.2 =

@@ -551,12 +481,12 @@ is why the following only applies to those.)
     }
     #endif
 
-
  • This code is used in §5.2.
-

§5.2.3. Note that even in this problem case, the CALLED_NT node is removed. It +

  • This code is used in §4.2.
+

§4.2.3. Note that even in this problem case, the CALLED_NT node is removed. It disappears from the tree entirely when the creator has finished work.

-

Complain that nothing else can be called5.2.3 = +

Complain that nothing else can be called4.2.3 =

@@ -573,8 +503,8 @@ disappears from the tree entirely when the creator has finished work.
     Node::set_text(p, Node::get_text(called_name_node));
     p->down = NULL;
 
-
  • This code is used in §5.2.
-

§5.3. Names are not permitted to contain brackets, but we do allow them as an indicator +

  • This code is used in §4.2.
+

§4.3. Names are not permitted to contain brackets, but we do allow them as an indicator of grammatical gender for languages other than English.

@@ -588,14 +518,14 @@ of grammatical gender for languages other than English. f
-

§5.4. That's it for callings; on to the main case, where we have a CREATED_NT +

§4.4. That's it for callings; on to the main case, where we have a CREATED_NT node which invites us to make something of it. In every case it becomes one of COMMON_NOUN_NT (e.g., "Colour is a kind of value"); or PROPER_NOUN_NT (e.g., "Miss Bianca is an animal"). Thus every CREATED_NT node disappears from the tree.

-

Perform creation on a CREATED node5.4 = +

Perform creation on a CREATED node4.4 =

@@ -611,52 +541,52 @@ from the tree.
         (prevailing_mood != INITIALLY_CE) &&
         (prevailing_mood != CERTAIN_CE)) {
         instance *recent_creation = NULL;
-        if (Wordings::nonempty(W)) Create an object or kind of object rather than a value5.4.1;
+        if (Wordings::nonempty(W)) Create an object or kind of object rather than a value4.4.1;
         if (recent_creation) {
             Refiner::give_subject_to_noun(p, Instances::as_subject(recent_creation));
             Annotations::write_int(p, creation_site_ANNOT, TRUE);
         }
     } else {
         parse_node *val = NULL;
-        if (Wordings::nonempty(W)) Create a value rather than an object5.4.2;
+        if (Wordings::nonempty(W)) Create a value rather than an object4.4.2;
         Refiner::give_spec_to_noun(p, val);
         if (val) Annotations::write_int(p, creation_site_ANNOT, TRUE);
     }
 
-
  • This code is used in §5.
-

§6. There now follows a pretty tedious trawl through reasons to object to names. +

  • This code is used in §4.
+

§5. There now follows a pretty tedious trawl through reasons to object to names. The crash hieroglyphs exist only so that the Inform test suite can verify that it handles crashes correctly.

 <creation-problem-diagnosis> ::=
-    <article> |    ==> Issue PM_NameIsArticle problem6.1
-    (/)/(- *** |    ==> Issue PM_NameWithBrackets problem6.2
-    *** (/)/(- |    ==> Issue PM_NameWithBrackets problem6.2
-    ... (/)/(- ... |    ==> Issue PM_NameWithBrackets problem6.2
-    ni--crash--1 |    ==> Issue PM_Crash1 problem6.3
-    ni--crash--10 |    ==> Issue PM_Crash10 problem6.4
-    ni--crash--11 |    ==> Issue PM_Crash11 problem6.5
-    , ... |    ==> Issue PM_StartsWithComma problem6.6
-    ... , |    ==> Issue PM_EndsWithComma problem6.7
-    ... when/while ... |    ==> Issue PM_ObjectIncWhen problem6.8
-    *** <quoted-text> *** |    ==> Issue PM_NameWithText problem6.9
-    condition |    ==> Issue PM_NameReserved problem6.10
-    conditions |    ==> Issue PM_NameReserved problem6.10
-    storage |    ==> Issue PM_NameReserved problem6.10
-    storages |    ==> Issue PM_NameReserved problem6.10
-    variable |    ==> Issue PM_NameReserved problem6.10
-    variables |    ==> Issue PM_NameReserved problem6.10
-    property-value |    ==> Issue PM_NameReserved problem6.10
-    property-values |    ==> Issue PM_NameReserved problem6.10
-    table-reference |    ==> Issue PM_NameReserved problem6.10
-    table-references |    ==> Issue PM_NameReserved problem6.10
-    list-entry |    ==> Issue PM_NameReserved problem6.10
-    list-entries                            ==> Issue PM_NameReserved problem6.10
+    <article> |    ==> Issue PM_NameIsArticle problem5.1
+    (/)/(- *** |    ==> Issue PM_NameWithBrackets problem5.2
+    *** (/)/(- |    ==> Issue PM_NameWithBrackets problem5.2
+    ... (/)/(- ... |    ==> Issue PM_NameWithBrackets problem5.2
+    ni--crash--1 |    ==> Issue PM_Crash1 problem5.3
+    ni--crash--10 |    ==> Issue PM_Crash10 problem5.4
+    ni--crash--11 |    ==> Issue PM_Crash11 problem5.5
+    , ... |    ==> Issue PM_StartsWithComma problem5.6
+    ... , |    ==> Issue PM_EndsWithComma problem5.7
+    ... when/while ... |    ==> Issue PM_ObjectIncWhen problem5.8
+    *** <quoted-text> *** |    ==> Issue PM_NameWithText problem5.9
+    condition |    ==> Issue PM_NameReserved problem5.10
+    conditions |    ==> Issue PM_NameReserved problem5.10
+    storage |    ==> Issue PM_NameReserved problem5.10
+    storages |    ==> Issue PM_NameReserved problem5.10
+    variable |    ==> Issue PM_NameReserved problem5.10
+    variables |    ==> Issue PM_NameReserved problem5.10
+    property-value |    ==> Issue PM_NameReserved problem5.10
+    property-values |    ==> Issue PM_NameReserved problem5.10
+    table-reference |    ==> Issue PM_NameReserved problem5.10
+    table-references |    ==> Issue PM_NameReserved problem5.10
+    list-entry |    ==> Issue PM_NameReserved problem5.10
+    list-entries                            ==> Issue PM_NameReserved problem5.10
 
-

§6.1. Issue PM_NameIsArticle problem6.1 = +

§5.1. Issue PM_NameIsArticle problem5.1 =

@@ -667,8 +597,8 @@ it handles crashes correctly.
         "the player sees as just 'A', you can get this effect with: 'A-Room is "
         "a room with printed name \"A\".')");
 
-
  • This code is used in §6.
-

§6.2. Issue PM_NameWithBrackets problem6.2 = +

  • This code is used in §5.
+

§5.2. Issue PM_NameWithBrackets problem5.2 =

@@ -680,8 +610,8 @@ it handles crashes correctly.
             "effect with: 'Fillmore West is a room with printed name \"Fillmore "
             "(West)\".')");
 
-
  • This code is used in §6 (three times).
-

§6.3. Issue PM_Crash1 problem6.3 = +

  • This code is used in §5 (three times).
+

§5.3. Issue PM_Crash1 problem5.3 =

@@ -693,8 +623,8 @@ it handles crashes correctly.
         "If this is a genuine inconvenience to you, get in touch with my authors.)");
     ProblemSigils::exit(1);
 
-
  • This code is used in §6.
-

§6.4. Issue PM_Crash10 problem6.4 = +

  • This code is used in §5.
+

§5.4. Issue PM_Crash10 problem5.4 =

@@ -706,8 +636,8 @@ it handles crashes correctly.
         "If this is a genuine inconvenience to you, get in touch with my authors.)");
     ProblemSigils::exit(10);
 
-
  • This code is used in §6.
-

§6.5. Issue PM_Crash11 problem6.5 = +

  • This code is used in §5.
+

§5.5. Issue PM_Crash11 problem5.5 =

@@ -719,8 +649,8 @@ it handles crashes correctly.
         "If this is a genuine inconvenience to you, get in touch with my authors.)");
     ProblemSigils::exit(11);
 
-
  • This code is used in §6.
-

§6.6. Issue PM_StartsWithComma problem6.6 = +

  • This code is used in §5.
+

§5.6. Issue PM_StartsWithComma problem5.6 =

@@ -731,8 +661,8 @@ it handles crashes correctly.
         "Inform generally doesn't like this because it reserves commas for "
         "specific purposes such as dividing rules or 'if' phrases.");
 
-
  • This code is used in §6.
-

§6.7. Issue PM_EndsWithComma problem6.7 = +

  • This code is used in §5.
+

§5.7. Issue PM_EndsWithComma problem5.7 =

@@ -742,8 +672,8 @@ it handles crashes correctly.
         "Inform generally doesn't like this because it reserves commas for "
         "specific purposes such as dividing rules or 'if' phrases.");
 
-
  • This code is used in §6.
-

§6.8. Issue PM_ObjectIncWhen problem6.8 = +

  • This code is used in §5.
+

§5.8. Issue PM_ObjectIncWhen problem5.8 =

@@ -766,8 +696,8 @@ it handles crashes correctly.
         "try something like: 'In the box is a thing called When worlds collide.'");
     Problems::issue_problem_end();
 
-
  • This code is used in §6.
-

§6.9. Issue PM_NameWithText problem6.9 = +

  • This code is used in §5.
+

§5.9. Issue PM_NameWithText problem5.9 =

@@ -782,8 +712,8 @@ it handles crashes correctly.
         "because it finished with sentence-ending punctuation, when in "
         "fact it didn't, so that I read the next words as following on.");
 
-
  • This code is used in §6.
-

§6.10. Issue PM_NameReserved problem6.10 = +

  • This code is used in §5.
+

§5.10. Issue PM_NameReserved problem5.10 =

@@ -795,8 +725,8 @@ it handles crashes correctly.
         "whatever you were making here, you'll need to call it something "
         "else.");
 
-
  • This code is used in §6 (12 times).
-

§5.4.1. At this point we do something that might look odd: we check to see if the +

  • This code is used in §5 (12 times).
+

§4.4.1. At this point we do something that might look odd: we check to see if the text of the CREATED_NT node is the name of an object already. That seems pointless, since CREATED_NT nodes are only made when a name is meaningless. But that was a little while ago, before we started to make creations within @@ -828,7 +758,7 @@ to the same object. to abbreviated forms of object names are normally allowed.

-

Create an object or kind of object rather than a value5.4.1 = +

Create an object or kind of object rather than a value4.4.1 =

@@ -840,10 +770,10 @@ to abbreviated forms of object names are normally allowed.
             recent_creation = NULL;
     }
 
-    if (recent_creation == NULL) Actually create a fresh object5.4.1.1;
+    if (recent_creation == NULL) Actually create a fresh object4.4.1.1;
 
-
  • This code is used in §5.4.
-

§5.4.1.1. Actually create a fresh object5.4.1.1 = +

  • This code is used in §4.4.
+

§4.4.1.1. Actually create a fresh object4.4.1.1 =

@@ -887,40 +817,40 @@ to abbreviated forms of object names are normally allowed.
         Annotations::write_int(p, creation_site_ANNOT, TRUE);
     }
 
- -

§5.4.2. Something of a rag-bag, this: it's everything else that can be created. +

+

§4.4.2. Something of a rag-bag, this: it's everything else that can be created.

-

Create a value rather than an object5.4.2 = +

Create a value rather than an object4.4.2 =

     parse_node *governing_spec = Node::get_evaluation(governor);
     if ((governor) && (Node::get_type(governor) == KIND_NT))
-        Create a new kind of value5.4.2.1
+        Create a new kind of value4.4.2.1
     else if ((Specifications::is_new_variable_like(governing_spec)) ||
         (prevailing_mood == INITIALLY_CE) ||
         (prevailing_mood == CERTAIN_CE))
-        Create a new variable5.4.2.2
+        Create a new variable4.4.2.2
     else if (Kinds::get_construct(create_as) == CON_rulebook)
-        Create a new rulebook5.4.2.4
+        Create a new rulebook4.4.2.4
     else if (Kinds::get_construct(create_as) == CON_activity)
-        Create a new activity5.4.2.5
+        Create a new activity4.4.2.5
     else if ((Kinds::Behaviour::definite(create_as)) && (Kinds::Behaviour::is_quasinumerical(create_as)))
-        Issue a problem for trying to create an instance of a unit5.4.2.6
+        Issue a problem for trying to create an instance of a unit4.4.2.6
     else if ((Kinds::Behaviour::definite(create_as)) &&
         (RTKinds::defined_by_table(create_as)) &&
         (RTKinds::defined_by_table(create_as) != allow_tabular_definitions_from))
-        Issue a problem for trying to create an instance of a table-defined kind5.4.2.7
+        Issue a problem for trying to create an instance of a table-defined kind4.4.2.7
     else if ((Kinds::Behaviour::definite(create_as)) && (Kinds::Behaviour::has_named_constant_values(create_as)))
-        Create an instance of an enumerated kind5.4.2.3
+        Create an instance of an enumerated kind4.4.2.3
     else
-        Issue an unable-to-create problem message5.4.2.8;
+        Issue an unable-to-create problem message4.4.2.8;
     Index::DocReferences::position_of_symbol(&W);
     Node::set_text(p, W);
 
-
  • This code is used in §5.4.
-

§5.4.2.1. Create a new kind of value5.4.2.1 = +

  • This code is used in §4.4.
+

§4.4.2.1. Create a new kind of value4.4.2.1 =

@@ -929,8 +859,8 @@ to abbreviated forms of object names are normally allowed.
     Assert::true(prop, prevailing_mood);
     val = Specifications::from_kind(latest_base_kind_of_value);
 
- -

§5.4.2.2. Create a new variable5.4.2.2 = +

+

§4.4.2.2. Create a new variable4.4.2.2 =

@@ -940,7 +870,7 @@ to abbreviated forms of object names are normally allowed.
     if (Specifications::is_new_variable_like(governing_spec))
         domain = Specifications::kind_of_new_variable_like(governing_spec);
     if ((K_understanding) && (Kinds::contains(domain, Kinds::get_construct(K_understanding))))
-        Issue a problem for topics that vary5.4.2.2.1;
+        Issue a problem for topics that vary4.4.2.2.1;
     pcalc_prop *prop = Propositions::Abstract::to_create_something(domain, W);
     if (prevailing_mood == CERTAIN_CE)
         prop = Propositions::concatenate(prop, Propositions::Abstract::to_make_a_const());
@@ -950,8 +880,8 @@ to abbreviated forms of object names are normally allowed.
     if (NonlocalVariables::get_latest() == NULL) internal_error("failed to create");
     val = Lvalues::new_actual_NONLOCAL_VARIABLE(NonlocalVariables::get_latest());
 
- -

§5.4.2.3. Create an instance of an enumerated kind5.4.2.3 = +

+

§4.4.2.3. Create an instance of an enumerated kind4.4.2.3 =

@@ -961,14 +891,14 @@ to abbreviated forms of object names are normally allowed.
     Assert::true(prop, prevailing_mood);
     val = Rvalues::from_instance(Instances::latest());
 
- -

§5.4.2.4. Lastly: rulebooks and activities are not part of the model, because they would +

+

§4.4.2.4. Lastly: rulebooks and activities are not part of the model, because they would make it enormously larger, and because they describe only the run-time evolution of the state of play and have no effect on the initial state. So we don't create them by asserting propositions to be true; we act directly.

-

Create a new rulebook5.4.2.4 = +

Create a new rulebook4.4.2.4 =

@@ -986,8 +916,8 @@ them by asserting propositions to be true; we act directly.
     val = Rvalues::from_rulebook(rb);
     Annotations::write_int(current_sentence, clears_pronouns_ANNOT, TRUE);
 
- -

§5.4.2.5. Create a new activity5.4.2.5 = +

+

§4.4.2.5. Create a new activity4.4.2.5 =

@@ -995,11 +925,11 @@ them by asserting propositions to be true; we act directly.
     val = Rvalues::from_activity(av);
     Annotations::write_int(current_sentence, clears_pronouns_ANNOT, TRUE);
 
- -

§5.4.2.2.1. And to wind up, sundry problem messages. +

+

§4.4.2.2.1. And to wind up, sundry problem messages.

-

Issue a problem for topics that vary5.4.2.2.1 = +

Issue a problem for topics that vary4.4.2.2.1 =

@@ -1009,8 +939,8 @@ them by asserting propositions to be true; we act directly.
         "(This would cause too much ambiguity with text variables, whose values "
         "look exactly the same.)");
 
- -

§5.4.2.6. Issue a problem for trying to create an instance of a unit5.4.2.6 = +

+

§4.4.2.6. Issue a problem for trying to create an instance of a unit4.4.2.6 =

@@ -1039,8 +969,8 @@ them by asserting propositions to be true; we act directly.
         Problems::issue_problem_end();
     }
 
- -

§5.4.2.7. Issue a problem for trying to create an instance of a table-defined kind5.4.2.7 = +

+

§4.4.2.7. Issue a problem for trying to create an instance of a table-defined kind4.4.2.7 =

@@ -1057,12 +987,12 @@ them by asserting propositions to be true; we act directly.
             "of a table (%4), not in isolated sentences like this one.");
     Problems::issue_problem_end();
 
- -

§5.4.2.8. This is often a problem already reported, so we issue a fresh message only +

+

§4.4.2.8. This is often a problem already reported, so we issue a fresh message only if nothing has already been said:

-

Issue an unable-to-create problem message5.4.2.8 = +

Issue an unable-to-create problem message4.4.2.8 =

@@ -1089,17 +1019,17 @@ if nothing has already been said:
         Problems::issue_problem_end();
     }
 
- -

§7. It turns out to be useful to have the same policing rules elsewhere: +

+

§6. It turns out to be useful to have the same policing rules elsewhere:

-int Assertions::Creator::vet_name(wording W) {
+int Assertions::Creator::vet_name(wording W) {
     if (<creation-problem-diagnosis>(W)) return FALSE;
     return TRUE;
 }
 
-

§8. Creations to instantiate. The COMMON_NOUN_NT node sometimes means to talk about things in general, +

§7. Creations to instantiate. The COMMON_NOUN_NT node sometimes means to talk about things in general, sometimes things in particular; consider the two sentences

@@ -1126,8 +1056,8 @@ object.
 int name_stubs_count = 0;
 
-void Assertions::Creator::convert_instance_to_nounphrase(parse_node *p, binary_predicate *hinge_relation) {
-    Check we are sure about this5.1;
+void Assertions::Creator::convert_instance_to_nounphrase(parse_node *p, binary_predicate *hinge_relation) {
+    Check we are sure about this4.1;
     int confect_name_flag = FALSE;
     if ((hinge_relation) && (BinaryPredicates::is_the_wrong_way_round(hinge_relation)))
         hinge_relation = BinaryPredicates::get_reversal(hinge_relation);
@@ -1140,7 +1070,7 @@ object.
         Node::set_text(p, GET_RW(<text-ending-with-a-calling>, 1));  the text before the bracketed clause
         CW = GET_RW(<text-ending-with-a-calling>, 2);  the bracketed text
         if (<article>(CW)) {
-            Issue a problem for calling something an article8.2;
+            Issue a problem for calling something an article7.2;
             CW = EMPTY_WORDING;
         }
     }
@@ -1149,16 +1079,16 @@ object.
         instance_kind = Specifications::to_kind(Node::get_evaluation(p));
     if ((Kinds::Behaviour::is_object(instance_kind) == FALSE) &&
         (Kinds::Behaviour::has_named_constant_values(instance_kind) == FALSE))
-        Point out that it's impossible to create values implicitly for this kind8.1;
-    Calculate the instance count, that is, the number of duplicates to be made8.3;
+        Point out that it's impossible to create values implicitly for this kind7.1;
+    Calculate the instance count, that is, the number of duplicates to be made7.3;
     parse_node *list_subtree = Node::new(COMMON_NOUN_NT);
     parse_node *original_next = p->next;
-    Construct a list subtree containing the right number of duplicates8.4;
+    Construct a list subtree containing the right number of duplicates7.4;
     Node::copy(p, list_subtree);
     p->next = original_next;
 }
 
-

§8.1. Point out that it's impossible to create values implicitly for this kind8.1 = +

§7.1. Point out that it's impossible to create values implicitly for this kind7.1 =

@@ -1173,8 +1103,8 @@ object.
     instance_kind = K_object;
     Annotations::write_int(p, multiplicity_ANNOT, 1);
 
-
  • This code is used in §8.
-

§8.2. Issue a problem for calling something an article8.2 = +

  • This code is used in §7.
+

§7.2. Issue a problem for calling something an article7.2 =

@@ -1186,8 +1116,8 @@ object.
         "name, '%2', is just an article - this isn't allowed.");
     Problems::issue_problem_end();
 
-
  • This code is used in §8.
-

§8.3. Usually the instance count is 1, but noun phrases such as "six vehicles" +

  • This code is used in §7.
+

§7.3. Usually the instance count is 1, but noun phrases such as "six vehicles" will raise it. The problem message here is almost a bit of social engineering: we just don't think you're implementing it right if you think you need more than 100 duplicate objects in one go. (Though it is true what the problem @@ -1196,7 +1126,7 @@ message says about performance, too.)

define MAX_DUPLICATES_AT_ONCE 100  change the problem message below if this is changed
 
-

Calculate the instance count, that is, the number of duplicates to be made8.3 = +

Calculate the instance count, that is, the number of duplicates to be made7.3 =

@@ -1211,13 +1141,13 @@ message says about performance, too.)
         instance_count = MAX_DUPLICATES_AT_ONCE;
     }
 
-
  • This code is used in §8.
-

§8.4. For instance, "six vehicles" would make a binary tree here in which the +

  • This code is used in §7.
+

§7.4. For instance, "six vehicles" would make a binary tree here in which the intermediate nodes are AND_NT and the leaves PROPER_NOUN_NT, each referring to a different vehicle object.

-

Construct a list subtree containing the right number of duplicates8.4 = +

Construct a list subtree containing the right number of duplicates7.4 =

@@ -1225,7 +1155,7 @@ to a different vehicle object.
     int i;
     for (i=1; i<=instance_count; i++) {
         inference_subject *new_instance = NULL;
-        Fashion a new object matching the description in the COMMON NOUN node8.4.1;
+        Fashion a new object matching the description in the COMMON NOUN node7.4.1;
         if (i < instance_count) {
             Node::set_type_and_clear_annotations(attach_to, AND_NT);
             attach_to->down = Node::new(PROPER_NOUN_NT);
@@ -1239,17 +1169,17 @@ to a different vehicle object.
         }
     }
 
-
  • This code is used in §8.
-

§8.4.1. Fashion a new object matching the description in the COMMON NOUN node8.4.1 = +

  • This code is used in §7.
+

§7.4.1. Fashion a new object matching the description in the COMMON NOUN node7.4.1 =

     inference_subject *named_after = NULL;
     wording NW = EMPTY_WORDING, NAW = EMPTY_WORDING;
     int propriety = FALSE;
-    Confect a name for the new object, if that's the bag we're into8.4.1.1;
+    Confect a name for the new object, if that's the bag we're into7.4.1.1;
     if (Kinds::Behaviour::is_object(instance_kind) == FALSE)
-        Check that the new name is non-empty and distinct from all existing ones8.4.1.2;
+        Check that the new name is non-empty and distinct from all existing ones7.4.1.2;
     NW = Wordings::truncate(NW, 32);  truncate to the maximum length
     parse_node *pz = Node::new(PROPER_NOUN_NT);
     pcalc_prop *prop = Propositions::Abstract::to_create_something(instance_kind, NW);
@@ -1270,13 +1200,13 @@ to a different vehicle object.
     Annotations::write_int(pz, creation_site_ANNOT, TRUE);
     Assertions::make_coupling(pz, p);
 
-
  • This code is used in §8.4.
-

§8.4.1.1. The following is used only in assemblies, where the instance count is always +

  • This code is used in §7.4.
+

§7.4.1.1. The following is used only in assemblies, where the instance count is always 1, and confects a name like "Cleopatra's nose" from an owner object, "Cleopatra", and an COMMON_NOUN_NT node, "nose".

-

Confect a name for the new object, if that's the bag we're into8.4.1.1 = +

Confect a name for the new object, if that's the bag we're into7.4.1.1 =

@@ -1302,9 +1232,9 @@ and an COMMON_NOUN_NT<
             feed_t id = Feeds::begin();
             LOOP_THROUGH_WORDING(j, CW) {
                 if (<possessive-third-person>(Wordings::one_word(j)))
-                    Insert the appropriate possessive8.4.1.1.1
+                    Insert the appropriate possessive7.4.1.1.1
                 else if (<agent-pronoun>(Wordings::one_word(j)))
-                    Insert the appropriate name8.4.1.1.2
+                    Insert the appropriate name7.4.1.1.2
                 else Feeds::feed_wording(Wordings::one_word(j));
             }
             NW = Feeds::end(id);
@@ -1314,8 +1244,8 @@ and an COMMON_NOUN_NT<
         }
     }
 
- -

§8.4.1.1.1. Insert the appropriate possessive8.4.1.1.1 = +

+

§7.4.1.1.1. Insert the appropriate possessive7.4.1.1.1 =

@@ -1330,15 +1260,15 @@ and an COMMON_NOUN_NT<
     Feeds::feed_text_expanding_strings(genitive_form);
     DISCARD_TEXT(genitive_form)
 
- -

§8.4.1.1.2. Insert the appropriate name8.4.1.1.2 = +

+

§7.4.1.1.2. Insert the appropriate name7.4.1.1.2 =

     Feeds::feed_wording(OW);
 
- -

§8.4.1.2. Check that the new name is non-empty and distinct from all existing ones8.4.1.2 = +

+

§7.4.1.2. Check that the new name is non-empty and distinct from all existing ones7.4.1.2 =

@@ -1356,8 +1286,8 @@ and an COMMON_NOUN_NT<
         DISCARD_TEXT(textual_count)
     }
 
- -

§9. This is how callings are parsed, both in assertions and conditions: that is, +

+

§8. This is how callings are parsed, both in assertions and conditions: that is, names occurring in noun phrases with the shape "blah blah (called the rhubarb rhubarb)". (For tedious reasons it would be inefficient to parse the second of these using the first.) @@ -1372,7 +1302,7 @@ of these using the first.) ... ( called ... ) ***

-

§10. Many names are rejected because they clash unfortunately with other things, +

§9. Many names are rejected because they clash unfortunately with other things, or for other high-level reasons, but there are also some basic syntactic blunders. Most of the time those are caught by the Creator above, but in a few cases (declaring new figures, for instance) it's possible to get around @@ -1399,11 +1329,11 @@ For example, property names can't be unsuitable, but they can be unfortunate. <unsuitable-name>

-

§11. Which powers: +

§10. Which powers:

-int Assertions::Creator::vet_name_for_noun(wording W) {
+int Assertions::Creator::vet_name_for_noun(wording W) {
     if (<unfortunate-name>(W)) {
         StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_NameBestAvoided),
             "this is a name which is best avoided",
@@ -1416,14 +1346,14 @@ For example, property names can't be unsuitable, but they can be unfortunate.
     return TRUE;
 }
 
-

§12. The natural language kind. Inform has a kind built in called "natural language", whose values are +

§11. The natural language kind. Inform has a kind built in called "natural language", whose values are enumerated names: English language, French language, German language and so on. When the kind is created, the following routine makes these instances. We do this exactly as we would to create any other instance — we write a logical proposition claiming its existence, then assert it to be true.

-
define NOTIFY_NATURAL_LANGUAGE_KINDS_CALLBACK Assertions::Creator::stock_nl_kind
+
define NOTIFY_NATURAL_LANGUAGE_KINDS_CALLBACK Assertions::Creator::stock_nl_kind
 
 void Assertions::Creator::stock_nl_kind(kind *K) {
diff --git a/docs/assertions-module/5-tc.html b/docs/assertions-module/5-tc.html
index b5e5c29a0..217ca24eb 100644
--- a/docs/assertions-module/5-tc.html
+++ b/docs/assertions-module/5-tc.html
@@ -398,7 +398,7 @@ hasn't been created yet; but we'll catch it later.
 
 
     W = GET_RW(<table-column-heading-bare>, 1);
-    if (Assertions::Creator::vet_name(W)) tc = Tables::Columns::new_table_column(W);
+    if (Assertions::Creator::vet_name(W)) tc = Tables::Columns::new_table_column(W);
     else return NULL;
 
  • This code is used in §11.
diff --git a/docs/assertions-module/6-cu.html b/docs/assertions-module/6-cu.html index fa515b357..7e111ac3d 100644 --- a/docs/assertions-module/6-cu.html +++ b/docs/assertions-module/6-cu.html @@ -79,19 +79,19 @@ their existence.

-pcalc_prop *Propositions::Abstract::to_make_a_kind(kind *K) {
+pcalc_prop *Propositions::Abstract::to_make_a_kind(kind *K) {
     return CreationPredicates::is_a_kind_up(Terms::new_variable(0), K);
 }
 
-pcalc_prop *Propositions::Abstract::to_make_a_var(void) {
+pcalc_prop *Propositions::Abstract::to_make_a_var(void) {
     return CreationPredicates::is_a_var_up(Terms::new_variable(0));
 }
 
-pcalc_prop *Propositions::Abstract::to_make_a_const(void) {
+pcalc_prop *Propositions::Abstract::to_make_a_const(void) {
     return CreationPredicates::is_a_const_up(Terms::new_variable(0));
 }
 
-pcalc_prop *Propositions::Abstract::to_create_something(kind *K, wording W) {
+pcalc_prop *Propositions::Abstract::to_create_something(kind *K, wording W) {
     pcalc_prop *prop = Atoms::QUANTIFIER_new(exists_quantifier, 0, 0);
     if ((K) && (Kinds::eq(K, K_object) == FALSE))
         prop = Propositions::concatenate(prop,
@@ -120,7 +120,7 @@ their existence.
         Instances::as_subject(I), prevailing_mood);
 }
 
-void Propositions::Abstract::assert_kind_of_subject(inference_subject *inst,
+void Propositions::Abstract::assert_kind_of_subject(inference_subject *inst,
     inference_subject *new, pcalc_prop *subject_to) {
     kind *K = KindSubjects::to_kind(new);
     pcalc_prop *prop = KindPredicates::new_atom(K, Terms::new_variable(0));
diff --git a/docs/calculus-module/5-smp.html b/docs/calculus-module/5-smp.html
index 8c3b4904f..4c3be34b5 100644
--- a/docs/calculus-module/5-smp.html
+++ b/docs/calculus-module/5-smp.html
@@ -1142,9 +1142,9 @@ accordingly.
     TRAVERSE_PROPOSITION(pl, prop)
         if ((pl->element == PREDICATE_ATOM) && (pl->arity == 2))
             for (int i=0; i<2; i++)
-                if (Conditions::is_TEST_ACTION(pl->terms[i].constant))
+                if (AConditions::is_action_TEST_VALUE(pl->terms[i].constant))
                     pl->terms[i].constant =
-                        Conditions::action_tested(pl->terms[i].constant);
+                        AConditions::action_tested(pl->terms[i].constant);
     return prop;
 }
 #endif
diff --git a/docs/core-module/3-pc.html b/docs/core-module/3-pc.html
index 8552a73ad..cf9df2977 100644
--- a/docs/core-module/3-pc.html
+++ b/docs/core-module/3-pc.html
@@ -72,7 +72,7 @@ function togglePopup(material_id) {
     
 

The interface between the main compiler and its plugins.

-
+

§1. The following set of functions is an API for the main compiler to consult with the plugins; put another way, it is also an API for the plugins to @@ -154,7 +154,32 @@ with the sentence. PLUGINS_CALL(INTERVENE_IN_ASSERTION_PLUG, px, py); }

-

§6. Called from The Creator (in assertions) when an instance is being made in +

§6. Called from The Creator (in assertions) when a copular sentence may be +creating something. For example, the actions plugin needs this. +

+ +
enum CREATION_PLUG
+
+
+int PluginCalls::creation(parse_node *px, parse_node *py) {
+    PLUGINS_CALL(CREATION_PLUG, px, py);
+}
+
+

§7. Called from Assertions (in assertions) when an unfamiliar node type appears +where a property value might be expected. For example, the actions plugin +uses this to deal with setting a property to an ACTION_NT node. To +intervene, set the node specification using Refine Parse Tree (in assertions) +and return TRUE; or return FALSE to let nature take its course. +

+ +
enum UNUSUAL_PROPERTY_VALUE_PLUG
+
+
+int PluginCalls::unusual_property_value(parse_node *py) {
+    PLUGINS_CALL(UNUSUAL_PROPERTY_VALUE_PLUG, py);
+}
+
+

§8. Called from The Creator (in assertions) when an instance is being made in an assembly, and its name may involve a genitive. For example, if the assembly says "every person has a nose", then normally this would be called something like "Mr Rogers's nose"; but the player plugin uses the following @@ -169,7 +194,7 @@ to have "your nose" in the case of the player instance. PLUGINS_CALL(IRREGULAR_GENITIVE_IN_ASSEMBLY_PLUG, owner, genitive, propriety); }

-

§7. Called from Booting Verbs (in assertions) to give each plugin a chance to +

§9. Called from Booting Verbs (in assertions) to give each plugin a chance to create any special sentence meanings it would like to. For example, the sounds plugin defines a special form of assertion sentence this way. The plugin should always return FALSE, since otherwise it may gazump other @@ -183,7 +208,7 @@ plugins and cause them to stop working. PLUGINS_CALLV(MAKE_SPECIAL_MEANINGS_PLUG); }

-

§8. Called from Assertions (in assertions) when it seems that the author wants +

§10. Called from Assertions (in assertions) when it seems that the author wants to create a property of something with a sentence like "A container has a number called security rating." A plugin can intervene and act on that, returning TRUE to stop the usual machinery. For example, the actions @@ -198,7 +223,7 @@ can be intercepted to create an action variable, not a property. PLUGINS_CALL(OFFERED_PROPERTY_PLUG, K, owner, what); } -

§9. Called from Assertions (in assertions) when the specification pseudo-variable +

§11. Called from Assertions (in assertions) when the specification pseudo-variable is about to be set for something; the plugin can then intercept this.

@@ -209,7 +234,7 @@ is about to be set for something; the plugin can then intercept this. PLUGINS_CALL(OFFERED_SPECIFICATION_PLUG, owner, W); } -

§10. Called from Refine Parse Tree (in assertions) to ask plugins if a noun phrase +

§12. Called from Refine Parse Tree (in assertions) to ask plugins if a noun phrase has a noun implicit within it, even though none is explicitly given. For example, the player plugin uses this to say that "initially carried" means "...by the player", and sets the subject of the node to be the player character @@ -223,7 +248,7 @@ instance. PLUGINS_CALL(REFINE_IMPLICIT_NOUN_PLUG, p); } -

§11. Called from Classifying Sentences (in assertions) to give plugins the chance +

§13. Called from Classifying Sentences (in assertions) to give plugins the chance of an early look at a newly-read assertion. For example, the map plugin uses this to spot that a sentence will create a new direction.

@@ -235,7 +260,7 @@ this to spot that a sentence will create a new direction. PLUGINS_CALL(NEW_ASSERTION_NOTIFY_PLUG, p); } -

§12. Called from The Equality Relation Revisited (in assertions) when we have +

§14. Called from The Equality Relation Revisited (in assertions) when we have to decide if it's valid to ask or declare that two things are the same. Returning TRUE says that it is always valid; returning FALSE leaves it to the regular machinery. This plug can therefore only be used to permit @@ -249,7 +274,7 @@ additional usages, not to restrict existing ones. PLUGINS_CALL(TYPECHECK_EQUALITY_PLUG, K1, K2); } -

§13. Called from Assertions (in assertions) to warn plugins that a variable +

§15. Called from Assertions (in assertions) to warn plugins that a variable is now being assigned a value by an explicit assertion sentence.

@@ -260,7 +285,21 @@ is now being assigned a value by an explicit assertion sentence. PLUGINS_CALL(VARIABLE_VALUE_NOTIFY_PLUG, q, val); } -

§14. Influencing values. Called from Rvalues (in values) to allow plugins to compile rvalues in +

§16. Influencing values. Called from Rvalues (in values) to allow plugins to help decide whether values +of the same kind would be equal if evaluated at runtime. For example, the +"scenes" plugin uses this to determine if two K_scene constants are equal. +To make a decision, set rv to either TRUE or FALSE and return TRUE. +To make no decision, return FALSE. +

+ +
enum COMPARE_CONSTANT_PLUG
+
+
+int PluginCalls::compare_constant(parse_node *c1, parse_node *c2, int *rv) {
+    PLUGINS_CALL(COMPARE_CONSTANT_PLUG, c1, c2, rv);
+}
+
+

§17. Called from Rvalues (in values) to allow plugins to compile rvalues in eccentric ways of their own: not in fact just for the whimsy of it, but to make it possible for plugins to support base kinds of their own. For example, the "actions" plugin needs this to deal with the "stored action" kind. @@ -273,7 +312,7 @@ the "actions" plugin needs this to deal with the "stored action" kind. PLUGINS_CALL(COMPILE_CONSTANT_PLUG, VH, K, spec); } -

§15. Called from Specifications (in values) to ask if there is some reason why +

§18. Called from Specifications (in values) to ask if there is some reason why a rule about I1 should be thought broader in scope than one about I2. This is used by the regions plugin when one is a sub-region of the other. This is expected to behave as a strcmp-like sorting function, with a positive @@ -287,7 +326,7 @@ return value saying I1 PLUGINS_CALL(MORE_SPECIFIC_PLUG, I1, I2); } -

§16. Called from Constants and Descriptions (in values) to give plugins a chance +

§19. Called from Constants and Descriptions (in values) to give plugins a chance to parse text which might otherwise be meaningless (or mean something different) and make it a "composite noun-quantifier" such as "everywhere" or "nothing". The main compiler does not recognise "everywhere" because it has no concept @@ -302,7 +341,7 @@ of space, but the spatial plugin does, and this is how. PLUGINS_CALL(PARSE_COMPOSITE_NQS_PLUG, W, DW, quantifier_used, some_kind); } -

§17. Influencing knowledge. Called from The Model World (in knowledge) to invite the plugin to participate +

§20. Influencing knowledge. Called from The Model World (in knowledge) to invite the plugin to participate in stages I to V of the completion process. This may involve using contextual reasoning to draw further inferences.

@@ -314,7 +353,7 @@ reasoning to draw further inferences. PLUGINS_CALL(COMPLETE_MODEL_PLUG, stage); } -

§18. Called from Inference Subjects (in knowledge) to invite the plugin to +

§21. Called from Inference Subjects (in knowledge) to invite the plugin to create any additional inference subjects it might want to reason about. In practice, this tends to be used to create preliminary subjects to stand in for significant kinds before those kinds are ready to be created. @@ -327,7 +366,7 @@ for significant kinds before those kinds are ready to be created. PLUGINS_CALLV(CREATE_INFERENCE_SUBJECTS_PLUG); } -

§19. Called from Indefinite Appearance (in knowledge) to ask the plugins what +

§22. Called from Indefinite Appearance (in knowledge) to ask the plugins what inferences, if any, to draw from a double-quoted text standing as an entire sentence. The infs is the subject which was being talked about at the time the text was quoted, and therefore presumably is what the text should describe. @@ -340,7 +379,7 @@ the text was quoted, and therefore presumably is what the text should describe. PLUGINS_CALL(DEFAULT_APPEARANCE_PLUG, infs, txt); } -

§20. Called from Inferences (in knowledge) when an inference is drawn about +

§23. Called from Inferences (in knowledge) when an inference is drawn about something. This does not, of course, necessarily mean that this will actually be the property of something: the inference might turn out to be mistaken. The mapping plugin uses this to infer further that if something is said to be a @@ -354,7 +393,7 @@ map connection to somewhere else, then it is probably a room. PLUGINS_CALL(INFERENCE_DRAWN_NOTIFY_PLUG, I, subj); } -

§21. Called from Kind Subjects (in knowledge). Early in the run, before some kinds +

§24. Called from Kind Subjects (in knowledge). Early in the run, before some kinds are created, placeholder inference subjects are created to stand in for them; this call enables plugins to recognise certain texts as referring to those.

@@ -366,7 +405,7 @@ this call enables plugins to recognise certain texts as referring to those. PLUGINS_CALL(NAME_TO_EARLY_INFS_PLUG, W, infs); } -

§22. Called from Kind Subjects (in knowledge) to warn plugins about a new kind, +

§25. Called from Kind Subjects (in knowledge) to warn plugins about a new kind, which in practice enables them to spot from the name that it is actually a kind they want to provide built-in support for: thus the actions plugin reacts to the name "stored action", for example. K is the newcomer, super its super-kind, @@ -382,7 +421,7 @@ source text (such as "container"). PLUGINS_CALL(NEW_BASE_KIND_NOTIFY_PLUG, K, d, W); } -

§23. Called from Instances (in knowledge) to warn plugins that a new instance has +

§26. Called from Instances (in knowledge) to warn plugins that a new instance has been created. For example, the figures plugin needs to know this so that it can see when a new illustration has been created.

@@ -399,7 +438,7 @@ sure you're not dealing with an object. PLUGINS_CALL(NEW_INSTANCE_NOTIFY_PLUG, nc); } -

§24. Called from Property Permissions (in knowledge) to warn plugins that a subject +

§27. Called from Property Permissions (in knowledge) to warn plugins that a subject has been given permission to hold a property; the parsing plugin, for example, uses this to attach a visibility flag.

@@ -411,7 +450,7 @@ uses this to attach a visibility flag. PLUGINS_CALL(NEW_PERMISSION_NOTIFY_PLUG, pp); } -

§25. Called from Properties (in knowledge) to warn plugins that a property has +

§28. Called from Properties (in knowledge) to warn plugins that a property has been created, which they can use to spot properties with special significance to them.

@@ -423,7 +462,7 @@ to them. PLUGINS_CALL(NEW_PROPERTY_NOTIFY_PLUG, prn); } -

§26. Called from Inference Subjects (in knowledge) to warn plugins that a subject +

§29. Called from Inference Subjects (in knowledge) to warn plugins that a subject has been created, which they can use to spot subjects with special significance to them.

@@ -435,7 +474,7 @@ to them. PLUGINS_CALL(NEW_SUBJECT_NOTIFY_PLUG, subj); } -

§27. Called from Nonlocal Variables (in knowledge) to warn plugins that a new +

§30. Called from Nonlocal Variables (in knowledge) to warn plugins that a new variable has been created, which they can use to spot variables with special significance to them.

@@ -447,7 +486,7 @@ significance to them. PLUGINS_CALL(NEW_VARIABLE_NOTIFY_PLUG, q); } -

§28. Called from Instances (in knowledge) to warn plugins that the kind of an +

§31. Called from Instances (in knowledge) to warn plugins that the kind of an instance is about to be set. This happens most often when the instance is created, but can also happen again, refining the kind to a subkind, when the instance is an object. @@ -460,7 +499,7 @@ the instance is an object. PLUGINS_CALL(SET_KIND_NOTIFY_PLUG, I, k); } -

§29. Called from Kind Subjects (in knowledge) when one kind of object is made a +

§32. Called from Kind Subjects (in knowledge) when one kind of object is made a subkind of another, as for example when "container" is a made a subkind of "thing". The plugin should return TRUE if it wishes to forbid this, and if so, it had better throw a problem message, or the user will be @@ -478,7 +517,7 @@ regions plugin does with the "region" kind. PLUGINS_CALL(SET_SUBKIND_NOTIFY_PLUG, sub, super); } -

§30. Influencing index. Called from Index Physical World (in index) to add something (if it wishes) +

§33. Influencing index. Called from Index Physical World (in index) to add something (if it wishes) to the index description of an instance in the spatial model. For example, the regions plugin uses this to put colour chips next to names of regions.

@@ -490,7 +529,7 @@ the regions plugin uses this to put colour chips next to names of regions. PLUGINS_CALL(ADD_TO_WORLD_INDEX_PLUG, OUT, O); } -

§31. Called from Index Physical World (in index) to add something (if it wishes) +

§34. Called from Index Physical World (in index) to add something (if it wishes) to the textual description of an instance in the spatial model. For example, the mapping plugin uses this to say where a door leads.

diff --git a/docs/if-module/3-scn.html b/docs/if-module/3-scn.html index 8a0648de4..064f7b6e5 100644 --- a/docs/if-module/3-scn.html +++ b/docs/if-module/3-scn.html @@ -89,6 +89,7 @@ to non-trivial functions as well as tables of data. PluginManager::plug(NEW_PROPERTY_NOTIFY_PLUG, Scenes::new_property_notify); PluginManager::plug(NEW_INSTANCE_NOTIFY_PLUG, Scenes::new_named_instance_notify); PluginManager::plug(NEW_BASE_KIND_NOTIFY_PLUG, Scenes::new_base_kind_notify); + PluginManager::plug(COMPARE_CONSTANT_PLUG, Scenes::compare_CONSTANT); PluginManager::plug(MAKE_SPECIAL_MEANINGS_PLUG, Scenes::make_special_meanings); } @@ -140,13 +141,25 @@ Inter identifier SCENE_TY } return FALSE; } + +int Scenes::compare_CONSTANT(parse_node *spec1, parse_node *spec2, int *rv) { + kind *K = Node::get_kind_of_value(spec1); + if (Kinds::eq(K, K_scene)) { + if (ARvalues::to_scene(spec1) == ARvalues::to_scene(spec2)) { + *rv = TRUE; + } + *rv = FALSE; + return TRUE; + } + return FALSE; +}

§6. scene structures are automatically created whenever a new instance of the kind "scene" is created, and this is where that happens.

-int Scenes::new_named_instance_notify(instance *I) {
+int Scenes::new_named_instance_notify(instance *I) {
     if ((K_scene) && (Kinds::eq(Instances::to_kind(I), K_scene))) {
         Scenes::new_scene(I);
         return TRUE;
@@ -173,7 +186,7 @@ Standard Rules. (So there is no need to translate this to other languages.)
 

§9.

-int Scenes::new_property_notify(property *prn) {
+int Scenes::new_property_notify(property *prn) {
     if (<notable-scene-properties>(prn->name)) {
         switch (<<r>>) {
             case 0: P_recurring = prn; break;
@@ -227,7 +240,7 @@ scenes — to express which, the 
     return Instances::get_name(sc->as_instance, FALSE);
 }
 
-
  • The structure scene is private to this section.
  • The structure scene_end is private to this section.
  • The structure scene_connector is accessed in 2/ri, 3/tm, 3/ts, 4/ap, 4/av, 4/ap2, 4/apc, 5/tfg, 5/gl and here.
+
  • The structure scene is private to this section.
  • The structure scene_end is private to this section.
  • The structure scene_connector is accessed in 2/ri, 3/tm, 3/ts, 4/ap, 4/av, 4/ap2, 4/ea, 4/apc, 5/tfg, 5/gl and here.

§11. A plugin called xyzzy generally has a hunk of subject data called xyzzy_data, so we would normally have a structure called scenes_data, but in fact that structure is just going to be scene. So: @@ -241,7 +254,7 @@ is created:

-void Scenes::new_scene(instance *I) {
+void Scenes::new_scene(instance *I) {
     scene *sc = CREATE(scene);
     Connect the scene structure to the instance12.3;
     Initialise the scene structure12.1;
@@ -289,7 +302,7 @@ to translate this to other languages.)
 

-scene *Scenes::from_named_constant(instance *I) {
+scene *Scenes::from_named_constant(instance *I) {
     if (K_scene == NULL) return NULL;
     kind *K = Instances::to_kind(I);
     if (Kinds::eq(K, K_scene)) return PLUGIN_DATA_ON_SUBJECT(scenes, I->as_subject);
@@ -299,7 +312,7 @@ to translate this to other languages.)
 

§14. Creating and parsing ends.

-int Scenes::parse_scene_end_name(scene *sc, wording EW, int create) {
+int Scenes::parse_scene_end_name(scene *sc, wording EW, int create) {
     for (int i=2; i<sc->no_ends; i++)
         if (Wordings::match(EW, sc->ends[i].end_names))
             return i;
@@ -333,7 +346,7 @@ to translate this to other languages.)
 

§15. Scene end rulebooks.

-void Scenes::new_scene_rulebook(scene *sc, int end) {
+void Scenes::new_scene_rulebook(scene *sc, int end) {
     wording RW = EMPTY_WORDING, AW = EMPTY_WORDING;
     Compose a name and alternate name for the new scene end rulebook15.1;
 
@@ -415,7 +428,7 @@ assertion sentences to create them:
 

-int Scenes::make_special_meanings(void) {
+int Scenes::make_special_meanings(void) {
     SpecialMeanings::declare(Scenes::begins_when_SMF, I"scene-begins-when", 1);
     SpecialMeanings::declare(Scenes::ends_when_SMF, I"scene-ends-when", 1);
     return FALSE;
@@ -425,7 +438,7 @@ assertion sentences to create them:
 

-int Scenes::begins_when_SMF(int task, parse_node *V, wording *NPs) {
+int Scenes::begins_when_SMF(int task, parse_node *V, wording *NPs) {
     wording SW = (NPs)?(NPs[0]):EMPTY_WORDING;
     wording OW = (NPs)?(NPs[1]):EMPTY_WORDING;
     switch (task) {  "The Ballroom Scene begins when..."
@@ -451,7 +464,7 @@ two noun phrases and sometimes three.
 

-int Scenes::ends_when_SMF(int task, parse_node *V, wording *NPs) {
+int Scenes::ends_when_SMF(int task, parse_node *V, wording *NPs) {
     wording SW = (NPs)?(NPs[0]):EMPTY_WORDING;
     wording OW = (NPs)?(NPs[1]):EMPTY_WORDING;
     wording O2W = (NPs)?(NPs[2]):EMPTY_WORDING;
@@ -641,7 +654,7 @@ ends" the other end.
 

-void Scenes::new_scene_anchor(parse_node *p, int phase, int given_end) {
+void Scenes::new_scene_anchor(parse_node *p, int phase, int given_end) {
     scene *this_scene = NULL;  scene whose end is being caused: must be set
     int end = -1;  end which is being anchored: must be set
 
diff --git a/docs/if-module/4-ac.html b/docs/if-module/4-ac.html
new file mode 100644
index 000000000..6643d72b9
--- /dev/null
+++ b/docs/if-module/4-ac.html
@@ -0,0 +1,106 @@
+
+
+	
+		Action Conditions
+
+		
+		
+		
+
+
+
+
+
+
+
+
+
+
+		
+	
+	
+		
+		
+ + +

A special condition for testing against action patterns.

+ +

§1.

+ +
+parse_node *AConditions::new_action_TEST_VALUE(action_pattern *ap, wording W) {
+    if (ap == NULL) internal_error("null action pattern");
+    parse_node *spec = Node::new_with_words(TEST_VALUE_NT, W);
+    spec->down = ARvalues::from_action_pattern(ap);
+    Node::set_text(spec->down, W);
+    return spec;
+}
+
+int AConditions::is_action_TEST_VALUE(parse_node *spec) {
+    if ((Node::is(spec, TEST_VALUE_NT)) &&
+        ((ARvalues::to_action_pattern(spec->down)) ||
+        (ARvalues::to_explicit_action(spec->down)))) return TRUE;
+    return FALSE;
+}
+
+parse_node *AConditions::action_tested(parse_node *spec) {
+    if (AConditions::is_action_TEST_VALUE(spec) == FALSE)
+        internal_error("action improperly extracted");
+    return spec->down;
+}
+
+ + +
+ + + diff --git a/docs/if-module/4-act.html b/docs/if-module/4-act.html index 61ec5a5d5..736e75176 100644 --- a/docs/if-module/4-act.html +++ b/docs/if-module/4-act.html @@ -113,7 +113,7 @@ which had not actually been done since around 2008.

-action_name *PL::Actions::act_new(wording W) {
+action_name *PL::Actions::act_new(wording W) {
     action_name *an = CREATE(action_name);
     Kinds::Behaviour::new_enumerated_value(K_action_name);
 
@@ -214,7 +214,7 @@ have to correspond to names referenced in }
 
diff --git a/docs/if-module/4-ak.html b/docs/if-module/4-ak.html new file mode 100644 index 000000000..463efd180 --- /dev/null +++ b/docs/if-module/4-ak.html @@ -0,0 +1,206 @@ + + + + Action Kinds + + + + + + + + + + + + + + + + + + +
+ + +

Three action-related kinds of value.

+ +

§1. The following represent action names, stored actions and descriptions of +actions respectively: see Actions Plugin for what these terms mean. +

+ +
+kind *K_action_name = NULL;
+kind *K_stored_action = NULL;
+kind *K_description_of_action = NULL;
+
+

§2. These are created by a Neptune file inside WorldModelKit, and are +recognised by their Inter identifiers: +

+ +

§3.

+ +
+int ARvalues::new_base_kind_notify(kind *new_base, text_stream *name, wording W) {
+    if (Str::eq_wide_string(name, L"ACTION_NAME_TY")) {
+        K_action_name = new_base; return TRUE;
+    }
+    if (Str::eq_wide_string(name, L"DESCRIPTION_OF_ACTION_TY")) {
+        K_description_of_action = new_base; return TRUE;
+    }
+    if (Str::eq_wide_string(name, L"STORED_ACTION_TY")) {
+        K_stored_action = new_base; return TRUE;
+    }
+    return FALSE;
+}
+
+

§4. A stored action can always be compared to a gerund: for instance, +

+ +
+

if the current action is taking something...

+
+ +
+int ARvalues::actions_typecheck_equality(kind *K1, kind *K2) {
+    if ((Kinds::eq(K1, K_stored_action)) && (Kinds::eq(K2, K_description_of_action)))
+        return TRUE;
+    return FALSE;
+}
+
+

§5. All three of these kinds can have constant values. For an action name, these +correspond simply to action_name objects: +

+ +
+parse_node *ARvalues::from_action_name(action_name *val) {
+        CONV_FROM(action_name, K_action_name) }
+action_name *ARvalues::to_action_name(parse_node *spec) {
+        CONV_TO(action_name) }
+
+

§6. When text is parsed to an action pattern, the result can be stored as a +constant in two ways. If the pattern unambiguously describes a single explicit +action, the result has the kind "stored action" and corresponds to an +explicit_action object; if the pattern is looser than that, the result +is a "description of action" and correspond to an action_pattern. +

+ +

For example, "taking the golden telephone" might be a K_stored_action +constant, but "doing something to the golden telephone" or "taking something" +or "taking the golden telephone in the presence of Mr Wu" would all be +K_description_of_action. +

+ +
+parse_node *ARvalues::from_action_pattern(action_pattern *val) {
+    int failure_code = 0;
+    explicit_action *ea = ExplicitActions::from_action_pattern(val, &failure_code);
+    if (ea) {
+        parse_node *spec = Node::new(CONSTANT_NT);
+        Node::set_kind_of_value(spec, K_stored_action);
+        Node::set_constant_explicit_action(spec, ea);
+        return spec;
+    } else {
+        CONV_FROM(action_pattern, K_description_of_action);
+    }
+}
+action_pattern *ARvalues::to_action_pattern(parse_node *spec) {
+        CONV_TO(action_pattern) }
+explicit_action *ARvalues::to_explicit_action(parse_node *spec) {
+        CONV_TO(explicit_action) }
+
+

§7. Finally, for a named action pattern, constant values correspond to +named_action_pattern objects. These are actually never used at run-time +and do not appear as rvalues in any permanent way inside the compiler, so +the kind K_description_of_action is given to them only on principle. If +they were used as values, this is the kind we would probably give them. +

+ +
+parse_node *ARvalues::from_named_action_pattern(named_action_pattern *val) {
+        CONV_FROM(named_action_pattern, K_description_of_action ) }
+named_action_pattern *ARvalues::to_named_action_pattern(parse_node *spec) {
+        CONV_TO(named_action_pattern) }
+
+parse_node *ARvalues::from_grammar_verb(grammar_verb *val) {
+        CONV_FROM(grammar_verb, K_understanding) }
+grammar_verb *ARvalues::to_grammar_verb(parse_node *spec) {
+        CONV_TO(grammar_verb) }
+parse_node *ARvalues::from_scene(scene *val) {
+        CONV_FROM(scene, K_scene) }
+scene *ARvalues::to_scene(parse_node *spec) {
+        CONV_TO(scene) }
+
+

§8. It's not useful to be able to compare description of action constants for +equality in this sense. There would be a case for doing so with stored actions, +but in practice there seems little need, so for the moment we do not. +

+ +
+int ARvalues::compare_CONSTANT(parse_node *spec1, parse_node *spec2, int *rv) {
+    kind *K = Node::get_kind_of_value(spec1);
+    if (Kinds::eq(K, K_action_name)) {
+        if (ARvalues::to_action_name(spec1) == ARvalues::to_action_name(spec2)) {
+            *rv = TRUE;
+        }
+        *rv = FALSE;
+        return TRUE;
+    }
+    return FALSE;
+}
+
+ + +
+ + + diff --git a/docs/if-module/4-anaa.html b/docs/if-module/4-anaa.html index 547bb0aad..75f2494c1 100644 --- a/docs/if-module/4-anaa.html +++ b/docs/if-module/4-anaa.html @@ -103,15 +103,15 @@ function togglePopup(material_id) { NodeType::new(ACTION_NT, I"ACTION_NT", 0, INFTY, L3_NCAT, ASSERT_NFLAG); Annotations::declare_type(action_meaning_ANNOT, - ActionsNodes::write_action_meaning_ANNOT); + ActionsNodes::write_action_meaning_ANNOT); Annotations::declare_type(constant_action_name_ANNOT, - ActionsNodes::write_constant_action_name_ANNOT); + ActionsNodes::write_constant_action_name_ANNOT); Annotations::declare_type(constant_action_pattern_ANNOT, - ActionsNodes::write_constant_action_pattern_ANNOT); + ActionsNodes::write_constant_action_pattern_ANNOT); Annotations::declare_type(constant_explicit_action_ANNOT, - ActionsNodes::write_constant_explicit_action_ANNOT); + ActionsNodes::write_constant_explicit_action_ANNOT); Annotations::declare_type(constant_named_action_pattern_ANNOT, - ActionsNodes::write_constant_named_action_pattern_ANNOT); + ActionsNodes::write_constant_named_action_pattern_ANNOT); Annotations::allow(ACTION_NT, action_meaning_ANNOT); Annotations::allow(COMMON_NOUN_NT, action_meaning_ANNOT); @@ -121,36 +121,119 @@ function togglePopup(material_id) { Annotations::allow(CONSTANT_NT, constant_explicit_action_ANNOT); }
-

§3. And for the debugging log: +

§3. ACTION nodes are converted from existing ones, not born:

-void ActionsNodes::write_action_meaning_ANNOT(text_stream *OUT, parse_node *p) {
+void ActionsNodes::convert_to_ACTION_node(parse_node *p, action_pattern *ap) {
+    Node::set_type(p, ACTION_NT);
+    Node::set_action_meaning(p, ap);
+    p->down = NULL;
+}
+
+int ActionsNodes::is_actionlike(parse_node *p) {
+    if (Node::get_type(p) == ACTION_NT) return TRUE;
+    if ((K_stored_action) && (Node::get_type(p) == PROPER_NOUN_NT)) {
+        parse_node *spec = Node::get_evaluation(p);
+        if (Rvalues::is_CONSTANT_of_kind(spec, K_stored_action)) return TRUE;
+    }
+    return FALSE;
+}
+
+void ActionsNodes::convert_stored_action_constant(parse_node *p) {
+    if (Node::get_type(p) == PROPER_NOUN_NT) {
+        parse_node *spec = Node::get_evaluation(p);
+        if (Rvalues::is_CONSTANT_of_kind(spec, K_stored_action)) {
+            explicit_action *ea = Node::get_constant_explicit_action(spec);
+            ActionsNodes::convert_to_ACTION_node(p, ea->as_described);
+            return;
+        }
+    }
+}
+
+

§4. The first case here is to take care of a sentence like: +

+ +
+

Taking something is proactive behaviour.

+
+ +

Here Refiner::refine will correctly report that "proactive behaviour" is +a new term, and give it a CREATED_NT node. But we don't want it to become an +object or a value — it will become a named kind of action instead. So we +amend the node to ACTION_NT. +

+ +

The second case occurs much less often — for instance, the only time it comes +up in the test suite is in the example "Chronic Hinting Syndrome": +

+ +
+

Setting is a kind of value. The settings are bright and dull.

+
+ +

Here the first sentence wants to create something called "setting", which +ought to have a CREATED_NT node type, but doesn't because it has been read +as an action instead. We correct the spurious ACTION_NT to a CREATED_NT. +

+ +
+int ActionsNodes::creation(parse_node *px, parse_node *py) {
+    if ((ActionsNodes::is_actionlike(px)) && (Node::get_type(py) == CREATED_NT))
+        Node::set_type(py, ACTION_NT);
+    if ((ActionsNodes::is_actionlike(px)) && (ActionsNodes::is_actionlike(py))) {
+        ActionsNodes::convert_stored_action_constant(px);
+        ActionsNodes::convert_stored_action_constant(py);
+    }
+    if ((Node::get_type(px) == ACTION_NT) && (Node::get_type(py) == KIND_NT))
+        Node::set_type(px, CREATED_NT);
+    return FALSE;
+}
+
+int ActionsNodes::unusual_property_value_node(parse_node *py) {
+    if (Node::get_type(py) == ACTION_NT) {
+        action_pattern *ap = Node::get_action_meaning(py);
+        if (ap) {
+            parse_node *val = ARvalues::from_action_pattern(ap);
+            if (Rvalues::is_CONSTANT_of_kind(val, K_stored_action)) {
+                Refiner::give_spec_to_noun(py, val);
+                return TRUE;
+            }
+        }
+    }
+    return FALSE;
+}
+
+

§5. And for the debugging log: +

+ +
+void ActionsNodes::write_action_meaning_ANNOT(text_stream *OUT, parse_node *p) {
     if (Node::get_action_meaning(p)) {
         WRITE(" {action meaning: ");
         ActionPatterns::write(OUT, Node::get_action_meaning(p));
         WRITE("}");
     }
 }
-void ActionsNodes::write_constant_action_name_ANNOT(text_stream *OUT, parse_node *p) {
+void ActionsNodes::write_constant_action_name_ANNOT(text_stream *OUT, parse_node *p) {
     if (Node::get_constant_action_name(p))
         WRITE(" {action name: %W}", ActionNameNames::tensed(Node::get_constant_action_name(p), IS_TENSE));
 }
-void ActionsNodes::write_constant_action_pattern_ANNOT(text_stream *OUT, parse_node *p) {
+void ActionsNodes::write_constant_action_pattern_ANNOT(text_stream *OUT, parse_node *p) {
     if (Node::get_constant_action_pattern(p)) {
         WRITE(" {action pattern: ");
         ActionPatterns::write(OUT, Node::get_constant_action_pattern(p));
         WRITE("}");
     }
 }
-void ActionsNodes::write_constant_explicit_action_ANNOT(text_stream *OUT, parse_node *p) {
+void ActionsNodes::write_constant_explicit_action_ANNOT(text_stream *OUT, parse_node *p) {
     if (Node::get_constant_explicit_action(p)) {
         WRITE(" {explicit action: ");
         ActionPatterns::write(OUT, Node::get_constant_explicit_action(p)->as_described);
         WRITE("}");
     }
 }
-void ActionsNodes::write_constant_named_action_pattern_ANNOT(text_stream *OUT,
+void ActionsNodes::write_constant_named_action_pattern_ANNOT(text_stream *OUT,
     parse_node *p) {
     if (Node::get_constant_named_action_pattern(p)) {
         WRITE(" {named action pattern: ");
@@ -160,7 +243,7 @@ function togglePopup(material_id) {
 }
 
diff --git a/docs/if-module/4-anl.html b/docs/if-module/4-anl.html index 9d9191e19..9b7efe69c 100644 --- a/docs/if-module/4-anl.html +++ b/docs/if-module/4-anl.html @@ -183,12 +183,12 @@ is removed.

-void ActionNameLists::mark_for_deletion(anl_entry *X) {
+void ActionNameLists::mark_for_deletion(anl_entry *X) {
     if (X) X->marked_for_deletion = TRUE;
     else internal_error("tried to mark null entry for deletion");
 }
 
-int ActionNameLists::marked_for_deletion(anl_entry *X) {
+int ActionNameLists::marked_for_deletion(anl_entry *X) {
     if (X) return X->marked_for_deletion;
     return FALSE;
 }
@@ -198,7 +198,7 @@ entries which fail to change the word position.
 

-void ActionNameLists::remove_entries_marked_for_deletion(action_name_list *list) {
+void ActionNameLists::remove_entries_marked_for_deletion(action_name_list *list) {
     if (list) {
         int pos = -1;
         for (anl_entry *entry = list->entries, *prev = NULL; entry; entry = entry->next_entry) {
@@ -325,7 +325,7 @@ anything" — a completely unrestricted action.
     entry->item.nap_listed = NULL;
 }
 
-anl_item *ActionNameLists::first_item(action_name_list *list) {
+anl_item *ActionNameLists::first_item(action_name_list *list) {
     if ((list) && (list->entries)) return &(list->entries->item);
     return NULL;
 }
@@ -361,12 +361,12 @@ used in sorting algorithms.
     return k;
 }
 
-named_action_pattern *ActionNameLists::nap(anl_entry *entry) {
+named_action_pattern *ActionNameLists::nap(anl_entry *entry) {
     if (entry) return entry->item.nap_listed;
     return NULL;
 }
 
-action_name *ActionNameLists::action(anl_entry *entry) {
+action_name *ActionNameLists::action(anl_entry *entry) {
     if (entry) return entry->item.action_listed;
     return NULL;
 }
@@ -424,17 +424,17 @@ the text leading to a list:
     entry->parsing_data.abbreviation_level = 0;
 }
 
-int ActionNameLists::parc(anl_entry *entry) {
+int ActionNameLists::parc(anl_entry *entry) {
     if (entry) return entry->parsing_data.parc;
     return 0;
 }
 
-wording ActionNameLists::par(anl_entry *entry, int i) {
+wording ActionNameLists::par(anl_entry *entry, int i) {
     if ((entry) && (entry->parsing_data.parc > i)) return entry->parsing_data.parameter[i];
     return EMPTY_WORDING;
 }
 
-wording ActionNameLists::in_clause(anl_entry *entry) {
+wording ActionNameLists::in_clause(anl_entry *entry) {
     if (entry) return entry->parsing_data.in_clause;
     return EMPTY_WORDING;
 }
@@ -453,17 +453,17 @@ the text leading to a list:
     return entry;
 }
 
-int ActionNameLists::first_position(action_name_list *list) {
+int ActionNameLists::first_position(action_name_list *list) {
     if (list) return ActionNameLists::word_position(list->entries);
     return -1;
 }
 
-int ActionNameLists::word_position(anl_entry *entry) {
+int ActionNameLists::word_position(anl_entry *entry) {
     if (entry) return entry->parsing_data.word_position;
     return -1;
 }
 
-int ActionNameLists::same_word_position(anl_entry *entry, anl_entry *Y) {
+int ActionNameLists::same_word_position(anl_entry *entry, anl_entry *Y) {
     if ((entry) && (Y) && (entry->parsing_data.word_position == Y->parsing_data.word_position))
         return TRUE;
     return FALSE;
@@ -487,7 +487,7 @@ not a NAP.
 

-action_name *ActionNameLists::get_the_one_true_action(action_name_list *list) {
+action_name *ActionNameLists::get_the_one_true_action(action_name_list *list) {
     action_name *an = ActionNameLists::single_positive_action(list);
     if (an == NULL) internal_error("Singleton ANL points to null AN");
     return an;
@@ -505,7 +505,7 @@ is no best action. (For example, in "throwing or removing something".)
 

-action_name *ActionNameLists::get_best_action(action_name_list *list) {
+action_name *ActionNameLists::get_best_action(action_name_list *list) {
     int posn = -1, best_score = -1;
     action_name *best = NULL;
     if (ActionNameLists::positive(list) == FALSE) return NULL;
@@ -616,7 +616,7 @@ something other than something — or 
 int anl_parsing_tense = IS_TENSE;
-action_name_list *ActionNameLists::parse(wording W, int tense, int *sense) {
+action_name_list *ActionNameLists::parse(wording W, int tense, int *sense) {
     if (Wordings::mismatched_brackets(W)) return NULL;
     int t = anl_parsing_tense;
     anl_parsing_tense = tense;
@@ -905,7 +905,7 @@ the trial entry for future trials.
 
  • This code is used in §24.1.3 (three times).
diff --git a/docs/if-module/4-ann.html b/docs/if-module/4-ann.html index 869f68390..3b275c76c 100644 --- a/docs/if-module/4-ann.html +++ b/docs/if-module/4-ann.html @@ -111,7 +111,7 @@ action". WordAssemblages::from_wording(W)); wording AW = WordAssemblages::to_wording(&wa); an->naming_data.as_noun = Nouns::new_proper_noun(AW, NEUTER_GENDER, ADD_TO_LEXICON_NTOPT, - MISCELLANEOUS_MC, Rvalues::from_action_name(an), Task::language_of_syntax()); + MISCELLANEOUS_MC, ARvalues::from_action_name(an), Task::language_of_syntax()); Vocabulary::set_flags(Lexer::word(Wordings::first_wn(W)), ACTION_PARTICIPLE_MC); action_name *an2; LOOP_OVER(an2, action_name) @@ -120,7 +120,7 @@ action". an->naming_data.it_optional = FALSE; an2->naming_data.it_optional = FALSE; } - ActionsPlugin::notice_new_action_name(an); + ActionsPlugin::notice_new_action_name(an); }

§4. In the early days of Inform, past participles had to be set explicitly, and @@ -129,7 +129,7 @@ enough that this is almost never used.

-void ActionNameNames::set_irregular_past(action_name *an, wording C) {
+void ActionNameNames::set_irregular_past(action_name *an, wording C) {
     if (Wordings::length(C) != 1)
         StandardProblems::sentence_problem(Task::syntax_tree(),
             _p_(PM_MultiwordPastParticiple),
@@ -148,7 +148,7 @@ enough that this is almost never used.
 

-wording ActionNameNames::tensed(action_name *an, int tense) {
+wording ActionNameNames::tensed(action_name *an, int tense) {
     if (tense == IS_TENSE) return an->naming_data.present_name;
     if (tense == HASBEEN_TENSE) return an->naming_data.past_name;
     internal_error("action tense unsupported");
@@ -215,7 +215,7 @@ preposition can be abbreviated is under the author's control:
     return an->naming_data.it_optional;
 }
 
-void ActionNameNames::make_abbreviable(action_name *an) {
+void ActionNameNames::make_abbreviable(action_name *an) {
     an->naming_data.abbreviable = TRUE;
 }
 
@@ -304,7 +304,7 @@ number of words.
 

-action_name *ActionNameNames::longest_nounless(wording W, int tense, int *posn) {
+action_name *ActionNameNames::longest_nounless(wording W, int tense, int *posn) {
     action_name *an;
     LOOP_OVER(an, action_name)
         if (ActionSemantics::can_have_noun(an) == FALSE) {
@@ -318,7 +318,7 @@ number of words.
 }
 
diff --git a/docs/if-module/4-ap.html b/docs/if-module/4-ap.html index 2eeddd47f..34842158b 100644 --- a/docs/if-module/4-ap.html +++ b/docs/if-module/4-ap.html @@ -77,16 +77,42 @@ function togglePopup(material_id) { entire chapter. The test group :actions may be helpful in trouble-shooting here.

+

It may be helpful to distinguish these ideas right from the outset: +

+ +
  • ● An "action" (or "explicit action", for the sake of clarity) is a specific +impulse by a person in the model world to effect some change within it: for +example, "Henry taking the brick". Here Henry is the "actor", and the brick is +"the noun". Actions can be "stored" so that they are values in their own +right; thus, a variable could be set to the value "Henry taking the brick", +and this would have kind K_stored_action. Inside the compiler they are +represented by explicit_action objects. +
  • ● An "action name" — not an ideal thing to call it, but traditional — is the +type of action involved, taken in isolation: for example, "taking". These can +also be values at run-time, they have kind K_action_name, and they are +represented in the comoiler by action_name objections. +
  • ● An "action pattern" is a textual description which matches some actions but +not others, and can be vague or specific: for example, "wearing or examining +something". Action patterns become values of the kind K_description_of_action. +They can also be aggregated into "named action patterns", which characterise +behaviour; see action_pattern and named_action_pattern. +
  • ● A "past action pattern", which can never in any way be a value, is a +description of an action which have happened in the past: for example, "dropped +the hat". These are just a special case of action patterns. +
 void ActionsPlugin::start(void) {
     ActionsNodes::nodes_and_annotations();
 
-    PluginManager::plug(MAKE_SPECIAL_MEANINGS_PLUG, ActionsPlugin::make_special_meanings);
-    PluginManager::plug(NEW_BASE_KIND_NOTIFY_PLUG, ActionsPlugin::new_base_kind_notify);
+    PluginManager::plug(MAKE_SPECIAL_MEANINGS_PLUG, ActionsPlugin::make_special_meanings);
+    PluginManager::plug(NEW_BASE_KIND_NOTIFY_PLUG, ARvalues::new_base_kind_notify);
+    PluginManager::plug(COMPARE_CONSTANT_PLUG, ARvalues::compare_CONSTANT);
     PluginManager::plug(COMPILE_CONSTANT_PLUG, RTActions::actions_compile_constant);
+    PluginManager::plug(CREATION_PLUG, ActionsNodes::creation);
+    PluginManager::plug(UNUSUAL_PROPERTY_VALUE_PLUG, ActionsNodes::unusual_property_value_node);
     PluginManager::plug(OFFERED_PROPERTY_PLUG, ActionVariables::actions_offered_property);
-    PluginManager::plug(OFFERED_SPECIFICATION_PLUG, ActionsPlugin::actions_offered_specification);
-    PluginManager::plug(TYPECHECK_EQUALITY_PLUG, ActionsPlugin::actions_typecheck_equality);
+    PluginManager::plug(OFFERED_SPECIFICATION_PLUG, ActionsPlugin::actions_offered_specification);
+    PluginManager::plug(TYPECHECK_EQUALITY_PLUG, ARvalues::actions_typecheck_equality);
     PluginManager::plug(PRODUCTION_LINE_PLUG, ActionsPlugin::production_line);
 
     Vocabulary::set_flags(Vocabulary::entry_for_text(L"doing"), ACTION_PARTICIPLE_MC);
@@ -104,67 +130,7 @@ entire chapter. The test group     return FALSE;
 }
 
-

§2. It may be useful to distinguish three ideas right from the outset: -

- -
  • ● An "action" is a specific impulse by a person in the model world to effect -some change within it: for example, "Henry taking the brick". Here Henry is the -"actor", and the brick is "the noun". Actions can be "stored" so that they -are values in their own right; thus, a variable could be set to the value -"Henry taking the brick", and this would have kind K_stored_action. -
  • ● An "action name" — not an ideal thing to call it, but traditional — is the -type of action involved, taken in isolation: for example, "taking". These can -also be values at run-time, and have kind K_action_name. -
  • ● An "action pattern" is a textual description which matches some actions but -not others, and can be vague or specific: for example, "wearing or examining -something". Action patterns are in general not values, but names can be given -to them so that they are — see Named Action Patterns — and then they -have the kind K_description_of_action. -
  • ● A "past action pattern", which can never in any way be a value, is a -description of an action which have happened in the past: for example, "dropped -the hat". -
-
-kind *K_action_name = NULL;
-kind *K_stored_action = NULL;
-kind *K_description_of_action = NULL;
-
-

§3. These are created by a Neptune file inside WorldModelKit, and are -recognised by their Inter identifiers: -

- -

§4.

- -
-int ActionsPlugin::new_base_kind_notify(kind *new_base, text_stream *name, wording W) {
-    if (Str::eq_wide_string(name, L"ACTION_NAME_TY")) {
-        K_action_name = new_base; return TRUE;
-    }
-    if (Str::eq_wide_string(name, L"DESCRIPTION_OF_ACTION_TY")) {
-        K_description_of_action = new_base; return TRUE;
-    }
-    if (Str::eq_wide_string(name, L"STORED_ACTION_TY")) {
-        K_stored_action = new_base; return TRUE;
-    }
-    return FALSE;
-}
-
-

§5. A stored action can always be compared to a gerund: for instance, -

- -
-

if the current action is taking something...

-
- -
-int ActionsPlugin::actions_typecheck_equality(kind *K1, kind *K2) {
-    if ((Kinds::eq(K1, K_stored_action)) &&
-        (Kinds::eq(K2, K_description_of_action)))
-        return TRUE;
-    return FALSE;
-}
-
-

§6. Though K_action_name is very like an enumeration kind, its possible values, +

§2. Though K_action_name is very like an enumeration kind, its possible values, which correspond to action_name objects, are not strictly speaking instances in the Inform world model. (Because they do not have properties: see Action Variables for what they have instead.) @@ -177,7 +143,7 @@ for what they have instead.)

 action_name *waiting_action = NULL;
 
-

§7. These are recognised by their English names when defined by the Standard Rules. +

§3. These are recognised by their English names when defined by the Standard Rules. (So there is no need to translate this to other languages.)

@@ -186,13 +152,13 @@ for what they have instead.) waiting
-

§8. Because action_name values are not instances, we cannot recognise them +

§4. Because action_name values are not instances, we cannot recognise them when instances are created, and instead have to do it directly when this is called by the function creating them:

-void ActionsPlugin::notice_new_action_name(action_name *an) {
+void ActionsPlugin::notice_new_action_name(action_name *an) {
     if (<waiting-action>(ActionNameNames::tensed(an, IS_TENSE))) {
         if (waiting_action == NULL) waiting_action = an;
     }
@@ -204,21 +170,21 @@ called by the function creating them:
     return waiting_action;
 }
 
-

§9. And because K_action_name values have no properties, they cannot store +

§5. And because K_action_name values have no properties, they cannot store a "specification" text as one, and have to make their own arrangements:

-int ActionsPlugin::actions_offered_specification(parse_node *owner, wording W) {
+int ActionsPlugin::actions_offered_specification(parse_node *owner, wording W) {
     if (Rvalues::is_CONSTANT_of_kind(owner, K_action_name)) {
         IXActions::actions_set_specification_text(
-            Rvalues::to_action_name(owner), Wordings::first_wn(W));
+            ARvalues::to_action_name(owner), Wordings::first_wn(W));
         return TRUE;
     }
     return FALSE;
 }
 
-

§10. The rest of this section is given over to the Preform grammar for dealing +

§6. The rest of this section is given over to the Preform grammar for dealing with the special meaning "X is an action...", which creates new action names. These can be quite complicated:

@@ -232,8 +198,8 @@ These can be quite complicated:
-int ActionsPlugin::make_special_meanings(void) {
-    SpecialMeanings::declare(ActionsPlugin::new_action_SMF, I"new-action", 2);
+int ActionsPlugin::make_special_meanings(void) {
+    SpecialMeanings::declare(ActionsPlugin::new_action_SMF, I"new-action", 2);
     return FALSE;
 }
 
@@ -242,13 +208,13 @@ These can be quite complicated:
     wording SW = (NPs)?(NPs[0]):EMPTY_WORDING;
     wording OW = (NPs)?(NPs[1]):EMPTY_WORDING;
     switch (task) {  "Taking something is an action."
-        case ACCEPT_SMFT: Check that this validly declares an action10.1; break;
-        case PASS_1_SMFT: Parse the subject and object phrases10.2; break;
+        case ACCEPT_SMFT: Check that this validly declares an action6.1; break;
+        case PASS_1_SMFT: Parse the subject and object phrases6.2; break;
     }
     return FALSE;
 }
 
-

§10.1. Check that this validly declares an action10.1 = +

§6.1. Check that this validly declares an action6.1 =

@@ -261,8 +227,8 @@ These can be quite complicated:
         return TRUE;
     }
 
-
  • This code is used in §10.
-

§11. <nounphrase-actionable> here is an awkward necessity, designed to prevent the +

  • This code is used in §6.
+

§7. <nounphrase-actionable> here is an awkward necessity, designed to prevent the regular sentence "The impulse is an action name that varies" from being parsed as an instance of "... is an action ...", creating a new action.

@@ -274,7 +240,7 @@ as an instance of "... is an action ...", creating a new action. <new-action-sentence-object-unarticled> ::= action <nounphrase-actionable> | ==> { TRUE, RP[1] } - action ==> Issue PM_BadActionDeclaration problem11.1 + action ==> Issue PM_BadActionDeclaration problem7.1 <nounphrase-actionable> ::= ^<variable-creation-tail> ==> { 0, Diagrams::new_UNPARSED_NOUN(W) } @@ -284,7 +250,7 @@ as an instance of "... is an action ...", creating a new action. *** variable
-

§11.1. Issue PM_BadActionDeclaration problem11.1 = +

§7.1. Issue PM_BadActionDeclaration problem7.1 =

@@ -294,12 +260,12 @@ as an instance of "... is an action ...", creating a new action.
         "is an action applying to one thing.'");
     ==> { FALSE, NULL };
 
-
  • This code is used in §11.
-

§10.2. Supposing that all that worked, the SP of the sentence is the name for the +

  • This code is used in §7.
+

§6.2. Supposing that all that worked, the SP of the sentence is the name for the new action, and the OP can include a wide range of details about it.

-

Parse the subject and object phrases10.2 = +

Parse the subject and object phrases6.2 =

@@ -307,23 +273,23 @@ new action, and the OP can include a wide range of details about it.
         if (<action-sentence-subject>(Node::get_text(V->next))) {
             an_being_parsed = <<rp>>;
             an_being_parsed->indexing_data.designers_specification = V->next->next;
-            ActionsPlugin::clear_clauses();
+            ActionsPlugin::clear_clauses();
             <action-sentence-object>(Node::get_text(V->next->next));
         }
 
-
  • This code is used in §10.
-

§12. The subject noun phrase needs little further parsing — it's the name of the +

  • This code is used in §6.
+

§8. The subject noun phrase needs little further parsing — it's the name of the action-to-be. A successful match here causes the new action_name structure to be created.

 <action-sentence-subject> ::=
-    <action-name> |  ==> Issue PM_ActionAlreadyExists problem12.1
+    <action-name> |  ==> Issue PM_ActionAlreadyExists problem8.1
     ...              ==> { 0, PL::Actions::act_new(W) }
 
-

§12.1. Issue PM_ActionAlreadyExists problem12.1 = +

§8.1. Issue PM_ActionAlreadyExists problem8.1 =

@@ -338,8 +304,8 @@ to be created.
         "('Understand \"unlock [something]\" as keyless unlocking.').");
     ==> { fail nonterminal };
 
-
  • This code is used in §12.
-

§13. The object NP is a sequence of "action clauses" which can occur in any order, +

  • This code is used in §8.
+

§9. The object NP is a sequence of "action clauses" which can occur in any order, which are allowed but not required to be delimited as a list, and which can inconveniently contain the word "and"; not only that, but note that in

@@ -354,7 +320,7 @@ inconveniently contain the word "and"; not only that, but note that in
 <action-sentence-object> ::=
     <action-clauses> |                   ==> { 0, - }
-    ...                                  ==> Issue PM_ActionClauseUnknown problem13.9
+    ...                                  ==> Issue PM_ActionClauseUnknown problem9.9
 
 <action-clauses> ::=
     ... |                                         ==> { lookahead }
@@ -368,26 +334,26 @@ inconveniently contain the word "and"; not only that, but note that in
     <action-clause>                      ==> { pass 1 }
 
 <action-clause> ::=
-    out of world |                       ==> { OOW_ACT_CLAUSE, - }; Make out of world13.1
-    abbreviable |                        ==> { ABBREV_ACT_CLAUSE, - }; Make abbreviable13.2
-    with past participle ... |           ==> { PP_ACT_CLAUSE, - }; Give irregular participle13.3
+    out of world |                       ==> { OOW_ACT_CLAUSE, - }; Make out of world9.1
+    abbreviable |                        ==> { ABBREV_ACT_CLAUSE, - }; Make abbreviable9.2
+    with past participle ... |           ==> { PP_ACT_CLAUSE, - }; Give irregular participle9.3
     applying to <action-applications> |  ==> { APPLYING_ACT_CLAUSE, - }
-    requiring light                      ==> { LIGHT_ACT_CLAUSE, - }; Require light13.4
+    requiring light                      ==> { LIGHT_ACT_CLAUSE, - }; Require light9.4
 
 <action-applications> ::=
     nothing |
-    one <act-req> and one <act-req> |    ==> Set kind and access for two13.7
-    one <act-req> and <act-req> |        ==> Set kind and access for two13.7
-    <act-req> and one <act-req> |        ==> Set kind and access for two13.7
-    <act-req> and <act-req> |            ==> Set kind and access for two13.7
-    nothing or one <act-req> |           ==> Set kind and access for an optional one13.5
-    one <act-req> |                      ==> Set kind and access for one13.6
-    two <act-req>   |                    ==> Set kind and access for one, doubling up13.8
-    <act-req> |                          ==> Set kind and access for one13.6
-    ...                                  ==> Issue PM_ActionMisapplied problem13.10;
+    one <act-req> and one <act-req> |    ==> Set kind and access for two9.7
+    one <act-req> and <act-req> |        ==> Set kind and access for two9.7
+    <act-req> and one <act-req> |        ==> Set kind and access for two9.7
+    <act-req> and <act-req> |            ==> Set kind and access for two9.7
+    nothing or one <act-req> |           ==> Set kind and access for an optional one9.5
+    one <act-req> |                      ==> Set kind and access for one9.6
+    two <act-req>   |                    ==> Set kind and access for one, doubling up9.8
+    <act-req> |                          ==> Set kind and access for one9.6
+    ...                                  ==> Issue PM_ActionMisapplied problem9.10;
 
 <act-req> ::=
-    <act-req-inner>                      ==> Check action kind13.11;
+    <act-req-inner>                      ==> Check action kind9.11;
 
 <act-req-inner> ::=
     <action-access> <k-kind> |           ==> { R[1], RP[2] }
@@ -399,63 +365,63 @@ inconveniently contain the word "and"; not only that, but note that in
     carried                              ==> { REQUIRES_POSSESSION, - }
 
-

§13.1. Make out of world13.1 = +

§9.1. Make out of world9.1 =

     ActionSemantics::make_action_out_of_world(an_being_parsed);
 
-
  • This code is used in §13.
-

§13.2. Make abbreviable13.2 = +

  • This code is used in §9.
+

§9.2. Make abbreviable9.2 =

     ActionNameNames::make_abbreviable(an_being_parsed);
 
-
  • This code is used in §13.
-

§13.3. Give irregular participle13.3 = +

  • This code is used in §9.
+

§9.3. Give irregular participle9.3 =

     ActionNameNames::set_irregular_past(an_being_parsed, GET_RW(<action-clause>, 1));
 
-
  • This code is used in §13.
-

§13.4. Require light13.4 = +

  • This code is used in §9.
+

§9.4. Require light9.4 =

     ActionSemantics::make_action_require_light(an_being_parsed);
 
-
  • This code is used in §13.
-

§13.5. Set kind and access for an optional one13.5 = +

  • This code is used in §9.
+

§9.5. Set kind and access for an optional one9.5 =

     ActionSemantics::give_action_an_optional_noun(an_being_parsed, R[1], RP[1]);
 
-
  • This code is used in §13.
-

§13.6. Set kind and access for one13.6 = +

  • This code is used in §9.
+

§9.6. Set kind and access for one9.6 =

     ActionSemantics::give_action_one_noun(an_being_parsed, R[1], RP[1]);
 
-
  • This code is used in §13 (twice).
-

§13.7. Set kind and access for two13.7 = +

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

§9.7. Set kind and access for two9.7 =

     ActionSemantics::give_action_two_nouns(an_being_parsed, R[1], RP[1], R[2], RP[2]);
 
-
  • This code is used in §13 (four times).
-

§13.8. Set kind and access for one, doubling up13.8 = +

  • This code is used in §9 (four times).
+

§9.8. Set kind and access for one, doubling up9.8 =

     ActionSemantics::give_action_two_nouns(an_being_parsed, R[1], RP[1], R[1], RP[1]);
 
-
  • This code is used in §13.
-

§13.9. Issue PM_ActionClauseUnknown problem13.9 = +

  • This code is used in §9.
+

§9.9. Issue PM_ActionClauseUnknown problem9.9 =

@@ -464,8 +430,8 @@ inconveniently contain the word "and"; not only that, but note that in
         "the action definition contained text I couldn't follow",
         "and may be too complicated.");
 
-
  • This code is used in §13.
-

§13.10. Issue PM_ActionMisapplied problem13.10 = +

  • This code is used in §9.
+

§9.10. Issue PM_ActionMisapplied problem9.10 =

@@ -476,8 +442,8 @@ inconveniently contain the word "and"; not only that, but note that in
         "one visible thing'.");
     ==> { REQUIRES_ACCESS, K_thing };
 
- -

§13.11. Check action kind13.11 = +

+

§9.11. Check action kind9.11 =

@@ -486,15 +452,15 @@ inconveniently contain the word "and"; not only that, but note that in
         if (A == UNRESTRICTED_ACCESS) A = REQUIRES_ACCESS;
         ==> { A, K_object };
     } else if (Kinds::Behaviour::is_subkind_of_object(K)) {
-        Issue PM_ActionMisapplied problem13.10;
+        Issue PM_ActionMisapplied problem9.10;
     } else if (A != UNRESTRICTED_ACCESS) {
-        Issue PM_ActionMisapplied problem13.10;
+        Issue PM_ActionMisapplied problem9.10;
     } else {
         ==> { A, K };
     }
 
-
  • This code is used in §13.
-

§14. For years this was not erroneous, but you now can't write, say, "X is an +

  • This code is used in §9.
+

§10. For years this was not erroneous, but you now can't write, say, "X is an action applying to nothing, applying to nothing, requiring light and applying to nothing".

@@ -507,10 +473,10 @@ to nothing".
 int an_clauses_filled[6];
-void ActionsPlugin::clear_clauses(void) {
+void ActionsPlugin::clear_clauses(void) {
     for (int i=1; i<=5; i++) an_clauses_filled[i] = FALSE;
 }
-void ActionsPlugin::clause(int N) {
+void ActionsPlugin::clause(int N) {
     if (an_clauses_filled[N])
         StandardProblems::sentence_problem(Task::syntax_tree(),
             _p_(PM_ActionClauseRepeated),
@@ -520,7 +486,7 @@ to nothing".
 }
 
diff --git a/docs/if-module/4-ap2.html b/docs/if-module/4-ap2.html index effe565ac..9d37734ff 100644 --- a/docs/if-module/4-ap2.html +++ b/docs/if-module/4-ap2.html @@ -101,11 +101,11 @@ object instead of an action — "reaching inside the cabinet". int valid; recording success or failure in parsing to an AP } action_pattern;
-
  • The structure action_pattern is accessed in 4/apc, 4/pap and here.
+
  • The structure action_pattern is accessed in 4/ea, 4/apc, 4/pap and here.

§2.

-action_pattern ActionPatterns::new(void) {
+action_pattern ActionPatterns::new(void) {
     action_pattern ap;
     ap.ap_clauses = NULL;
     ap.text_of_pattern = EMPTY_WORDING;
@@ -119,21 +119,11 @@ object instead of an action — "reaching inside the cabinet".
 

§3.

-typedef struct explicit_action {
-    int request;
-    struct action_name *action;
-    struct parse_node *actor;
-    struct parse_node *first_noun;
-    struct parse_node *second_noun;
-    struct action_pattern *as_described;
-} explicit_action;
-
-
 void ActionPatterns::log(action_pattern *ap) {
     ActionPatterns::write(DL, ap);
 }
 
-void ActionPatterns::write(OUTPUT_STREAM, action_pattern *ap) {
+void ActionPatterns::write(OUTPUT_STREAM, action_pattern *ap) {
     if (ap == NULL) WRITE("<null-ap>");
     else if (ap->valid != TRUE) WRITE("<invalid>");
     else {
@@ -146,7 +136,7 @@ object instead of an action — "reaching inside the cabinet".
     }
 }
 
-action_pattern *ActionPatterns::ap_store(action_pattern ap) {
+action_pattern *ActionPatterns::ap_store(action_pattern ap) {
     action_pattern *sap = CREATE(action_pattern);
     *sap = ap;
     return sap;
@@ -160,7 +150,7 @@ object instead of an action — "reaching inside the cabinet".
     return FALSE;
 }
 
-int ActionPatterns::is_valid(action_pattern *ap) {
+int ActionPatterns::is_valid(action_pattern *ap) {
     if (ap == NULL) return FALSE;
     return ap->valid;
 }
@@ -170,12 +160,12 @@ object instead of an action — "reaching inside the cabinet".
     return ActionNameLists::covers_action(ap->action_list, an);
 }
 
-action_name_list *ActionPatterns::list(action_pattern *ap) {
+action_name_list *ActionPatterns::list(action_pattern *ap) {
     if (ap == NULL) return NULL;
     return ap->action_list;
 }
 
-action_name *ActionPatterns::required_action(action_pattern *ap) {
+action_name *ActionPatterns::required_action(action_pattern *ap) {
     if (ap) return ActionNameLists::single_positive_action(ap->action_list);
     return NULL;
 }
@@ -185,54 +175,6 @@ object instead of an action — "reaching inside the cabinet".
     return FALSE;
 }
 
-explicit_action *ActionPatterns::to_explicit_action(action_pattern *ap, int *reason) {
-    if (ActionPatterns::is_unspecific(ap)) { *reason = 1; return NULL; }
-    if (ActionPatterns::is_overspecific(ap)) { *reason = 2; return NULL; }
-    *reason = 0;
-    explicit_action *ea = CREATE(explicit_action);
-    ea->action = ActionNameLists::get_the_one_true_action(ap->action_list);
-    ea->request = APClauses::is_request(ap);
-    ea->actor = APClauses::get_val(ap, ACTOR_AP_CLAUSE);
-    ea->first_noun = APClauses::get_val(ap, NOUN_AP_CLAUSE);
-    ea->second_noun = APClauses::get_val(ap, SECOND_AP_CLAUSE);
-    ea->as_described = ap;
-    return ea;
-}
-
-void ActionPatterns::make_ACTION_node(parse_node *p, action_pattern *ap) {
-    Node::set_type(p, ACTION_NT);
-    Node::set_action_meaning(p, ap);
-    p->down = NULL;
-}
-
-int ActionPatterns::is_unspecific(action_pattern *ap) {
-    action_name *an = ActionPatterns::required_action(ap);
-    if (an == NULL) return TRUE;
-    if ((ActionSemantics::must_have_noun(an)) && (APClauses::get_val(ap, NOUN_AP_CLAUSE) == NULL)) return TRUE;
-    if ((ActionSemantics::must_have_second(an)) && (APClauses::get_val(ap, SECOND_AP_CLAUSE) == NULL)) return TRUE;
-    if ((ActionSemantics::can_have_noun(an)) &&
-        (ActionPatterns::ap_clause_is_unspecific(APClauses::get_val(ap, NOUN_AP_CLAUSE)))) return TRUE;
-    if ((ActionSemantics::can_have_second(an)) &&
-        (ActionPatterns::ap_clause_is_unspecific(APClauses::get_val(ap, SECOND_AP_CLAUSE)))) return TRUE;
-    if (ActionPatterns::ap_clause_is_unspecific(APClauses::get_val(ap, ACTOR_AP_CLAUSE))) return TRUE;
-    return FALSE;
-}
-
-int ActionPatterns::ap_clause_is_unspecific(parse_node *spec) {
-    if (spec == NULL) return FALSE;
-    if (Specifications::is_description(spec) == FALSE) return FALSE;
-    return TRUE;
-}
-
-int ActionPatterns::is_overspecific(action_pattern *ap) {
-    for (ap_clause *apoc = (ap)?(ap->ap_clauses):NULL; apoc; apoc = apoc->next)
-        if ((APClauses::aspect(apoc) != PRIMARY_APCA) && (apoc->clause_spec))
-            return TRUE;
-    if (APClauses::has_any_actor(ap)) return TRUE;
-    if (ap->duration) return TRUE;
-    return FALSE;
-}
-
 void ActionPatterns::suppress_action_testing(action_pattern *ap) {
     if ((ap->duration == NULL) && (ap->action_list))
         ActionNameLists::suppress_action_testing(ap->action_list);
@@ -244,7 +186,6 @@ object instead of an action — "reaching inside the cabinet".
     return spec;
 }
 
-
  • The structure explicit_action is accessed in 4/anaa and here.

§4.

@@ -264,6 +205,19 @@ object instead of an action — "reaching inside the cabinet".
     return FALSE;
 }
 
+action_pattern *ActionPatterns::action_from_TEST(parse_node *spec) {
+    if (AConditions::is_action_TEST_VALUE(spec)) {
+        action_pattern *ap = ARvalues::to_action_pattern(
+            AConditions::action_tested(spec));
+        if (ap == NULL) {
+            explicit_action *ea = Node::get_constant_explicit_action(AConditions::action_tested(spec));
+            if (ea) ap = ea->as_described;
+        }
+        return ap;
+    }
+    return NULL;
+}
+
 int ActionPatterns::compare_specificity(action_pattern *ap1, action_pattern *ap2) {
     if ((ap1 == NULL) && (ap2)) return -1;
     if ((ap1) && (ap2 == NULL)) return 1;
@@ -304,7 +258,7 @@ object instead of an action — "reaching inside the cabinet".
 }
 
diff --git a/docs/if-module/4-apc.html b/docs/if-module/4-apc.html index caca92aa7..52302ec2a 100644 --- a/docs/if-module/4-apc.html +++ b/docs/if-module/4-apc.html @@ -108,7 +108,7 @@ MathJax = { CLASS_DEFINITION } ap_clause;
-
  • The structure ap_clause is accessed in 2/ri, 3/tm, 3/scn, 3/ts, 4/ap, 4/av, 4/ap2, 4/gng, 5/tfg, 5/gl and here.
+
  • The structure ap_clause is accessed in 2/ri, 3/tm, 3/scn, 3/ts, 4/ap, 4/av, 4/ap2, 4/ea, 4/gng, 5/tfg, 5/gl and here.

§2. The clause options are a bitmap. Some are meaningful only for one or two clauses.

@@ -127,49 +127,49 @@ clauses. return FALSE; } -void APClauses::set_opt(ap_clause *apoc, int opt) { +void APClauses::set_opt(ap_clause *apoc, int opt) { if (apoc == NULL) internal_error("no such apoc"); if ((apoc->clause_options & opt) == 0) apoc->clause_options += opt; } -void APClauses::clear_opt(ap_clause *apoc, int opt) { +void APClauses::clear_opt(ap_clause *apoc, int opt) { if (apoc == NULL) internal_error("no such apoc"); if (apoc->clause_options & opt) apoc->clause_options -= opt; } -void APClauses::any_actor(action_pattern *ap) { +void APClauses::any_actor(action_pattern *ap) { ap_clause *apoc = APClauses::ensure_clause(ap, ACTOR_AP_CLAUSE); APClauses::set_opt(apoc, ACTOR_IS_NOT_PLAYER_APCOPT); } -int APClauses::has_any_actor(action_pattern *ap) { +int APClauses::has_any_actor(action_pattern *ap) { ap_clause *apoc = APClauses::clause(ap, ACTOR_AP_CLAUSE); if (APClauses::opt(apoc, ACTOR_IS_NOT_PLAYER_APCOPT)) return TRUE; return FALSE; } -void APClauses::set_request(action_pattern *ap) { +void APClauses::set_request(action_pattern *ap) { ap_clause *apoc = APClauses::ensure_clause(ap, ACTOR_AP_CLAUSE); APClauses::set_opt(apoc, REQUEST_APCOPT); } -void APClauses::clear_request(action_pattern *ap) { +void APClauses::clear_request(action_pattern *ap) { ap_clause *apoc = APClauses::ensure_clause(ap, ACTOR_AP_CLAUSE); APClauses::clear_opt(apoc, REQUEST_APCOPT); } -int APClauses::is_request(action_pattern *ap) { +int APClauses::is_request(action_pattern *ap) { ap_clause *apoc = APClauses::clause(ap, ACTOR_AP_CLAUSE); if (APClauses::opt(apoc, REQUEST_APCOPT)) return TRUE; return FALSE; } -parse_node *APClauses::get_val(action_pattern *ap, int C) { +parse_node *APClauses::get_val(action_pattern *ap, int C) { ap_clause *apoc = APClauses::clause(ap, C); return (apoc)?(apoc->clause_spec):NULL; } -void APClauses::set_val(action_pattern *ap, int C, parse_node *val) { +void APClauses::set_val(action_pattern *ap, int C, parse_node *val) { if (val == NULL) { ap_clause *apoc = APClauses::clause(ap, C); if (apoc) apoc->clause_spec = val; @@ -179,12 +179,12 @@ clauses. } } -void APClauses::nullify_nonspecific(action_pattern *ap, int C) { +void APClauses::nullify_nonspecific(action_pattern *ap, int C) { ap_clause *apoc = APClauses::clause(ap, C); if (apoc) apoc->clause_spec = ActionPatterns::nullify_nonspecific_references(apoc->clause_spec); } -ap_clause *APClauses::clause(action_pattern *ap, int C) { +ap_clause *APClauses::clause(action_pattern *ap, int C) { return APClauses::find_clause(ap, C, FALSE); } @@ -230,10 +230,10 @@ clauses.

§4.

-void APClauses::ap_add_optional_clause(action_pattern *ap, stacked_variable *stv,
+void APClauses::ap_add_optional_clause(action_pattern *ap, stacked_variable *stv,
     wording W) {
     if (stv == NULL) internal_error("no stacked variable for apoc");
-    parse_node *spec = ParseActionPatterns::verified_action_parameter(W);
+    parse_node *spec = ParseActionPatterns::verified_action_parameter(W);
     int oid = StackedVariables::get_owner_id(stv);
     int off = StackedVariables::get_offset(stv);
 
@@ -289,7 +289,7 @@ clauses.
     return apoc;
 }
 
-int APClauses::validate(ap_clause *apoc, kind *K) {
+int APClauses::validate(ap_clause *apoc, kind *K) {
     if ((apoc) &&
         (APClauses::opt(apoc, DO_NOT_VALIDATE_APCOPT) == FALSE) &&
         (Dash::validate_parameter(apoc->clause_spec, K) == FALSE))
@@ -338,7 +338,7 @@ used in sorting algorithms.
 enum MISC_APCA
 
-int APClauses::aspect(ap_clause *apoc) {
+int APClauses::aspect(ap_clause *apoc) {
     switch (apoc->clause_ID) {
         case PARAMETRIC_AP_CLAUSE:         return PARAMETRIC_APCA;
         case ACTOR_AP_CLAUSE:              return PRIMARY_APCA;
@@ -416,7 +416,7 @@ used in sorting algorithms.
 }
 
 int APClauses::viable_in_past_tense(action_pattern *ap) {
-    if (ActionPatterns::is_overspecific(ap)) return FALSE;
+    if (ExplicitActions::ap_overspecific(ap)) return FALSE;
     if (APClauses::pta_acceptable(APClauses::get_val(ap, ACTOR_AP_CLAUSE)) == FALSE) return FALSE;
     if (APClauses::pta_acceptable(APClauses::get_val(ap, NOUN_AP_CLAUSE)) == FALSE) return FALSE;
     if (APClauses::pta_acceptable(APClauses::get_val(ap, SECOND_AP_CLAUSE)) == FALSE) return FALSE;
@@ -432,7 +432,7 @@ used in sorting algorithms.
 }
 
diff --git a/docs/if-module/4-as.html b/docs/if-module/4-as.html index 38ff23f94..9b78e8354 100644 --- a/docs/if-module/4-as.html +++ b/docs/if-module/4-as.html @@ -143,19 +143,19 @@ preferred way to do that is to use activities for selecting missing parameters.

-void ActionSemantics::give_action_an_optional_noun(action_name *an, int acc, kind *K) {
+void ActionSemantics::give_action_an_optional_noun(action_name *an, int acc, kind *K) {
     an->semantics.min_parameters = 0;
     an->semantics.max_parameters = 1;
     an->semantics.noun_access = acc;
     an->semantics.noun_kind = K;
 }
-void ActionSemantics::give_action_one_noun(action_name *an, int acc, kind *K) {
+void ActionSemantics::give_action_one_noun(action_name *an, int acc, kind *K) {
     an->semantics.min_parameters = 1;
     an->semantics.max_parameters = 1;
     an->semantics.noun_access = acc;
     an->semantics.noun_kind = K;
 }
-void ActionSemantics::give_action_two_nouns(action_name *an, int acc1, kind *K1,
+void ActionSemantics::give_action_two_nouns(action_name *an, int acc1, kind *K1,
     int acc2, kind *K2) {
     an->semantics.min_parameters = 2;
     an->semantics.max_parameters = 2;
@@ -174,10 +174,10 @@ preferred way to do that is to use activities for selecting missing parameters.
             "value, but not to two values. Sorry about that.");
 }
 
-void ActionSemantics::make_action_out_of_world(action_name *an) {
+void ActionSemantics::make_action_out_of_world(action_name *an) {
     an->semantics.out_of_world = TRUE;
 }
-void ActionSemantics::make_action_require_light(action_name *an) {
+void ActionSemantics::make_action_require_light(action_name *an) {
     an->semantics.requires_light = TRUE;
 }
 
@@ -185,22 +185,22 @@ preferred way to do that is to use activities for selecting missing parameters.

-int ActionSemantics::can_have_noun(action_name *an) {
+int ActionSemantics::can_have_noun(action_name *an) {
     if (an->semantics.max_parameters >= 1) return TRUE;
     return FALSE;
 }
 
-int ActionSemantics::can_have_second(action_name *an) {
+int ActionSemantics::can_have_second(action_name *an) {
     if (an->semantics.max_parameters >= 2) return TRUE;
     return FALSE;
 }
 
-int ActionSemantics::must_have_noun(action_name *an) {
+int ActionSemantics::must_have_noun(action_name *an) {
     if (an->semantics.min_parameters >= 1) return TRUE;
     return FALSE;
 }
 
-int ActionSemantics::must_have_second(action_name *an) {
+int ActionSemantics::must_have_second(action_name *an) {
     if (an->semantics.min_parameters >= 2) return TRUE;
     return FALSE;
 }
@@ -214,7 +214,7 @@ preferred way to do that is to use activities for selecting missing parameters.
     return FALSE;
 }
 
-int ActionSemantics::is_out_of_world(action_name *an) {
+int ActionSemantics::is_out_of_world(action_name *an) {
     if (an->semantics.out_of_world) return TRUE;
     return FALSE;
 }
@@ -227,11 +227,11 @@ preferred way to do that is to use activities for selecting missing parameters.
     return an->semantics.second_access;
 }
 
-kind *ActionSemantics::kind_of_noun(action_name *an) {
+kind *ActionSemantics::kind_of_noun(action_name *an) {
     return an->semantics.noun_kind;
 }
 
-kind *ActionSemantics::kind_of_second(action_name *an) {
+kind *ActionSemantics::kind_of_second(action_name *an) {
     return an->semantics.second_kind;
 }
 
@@ -356,7 +356,7 @@ clear from the implementation in }
diff --git a/docs/if-module/4-av.html b/docs/if-module/4-av.html index d1804be09..7a186c55c 100644 --- a/docs/if-module/4-av.html +++ b/docs/if-module/4-av.html @@ -81,7 +81,7 @@ into creations of action variables:
 int ActionVariables::actions_offered_property(kind *K, parse_node *owner, parse_node *prop) {
     if (Kinds::eq(K, K_action_name)) {
-        action_name *an = Rvalues::to_action_name(owner);
+        action_name *an = ARvalues::to_action_name(owner);
         if (an == NULL) internal_error("failed to extract action-name structure");
         if (global_pass_state.pass == 1) {
             Require the variable to have an explicit name1.1;
@@ -297,12 +297,12 @@ action patterns. For example, the Standard Rules define:
 

-stacked_variable *ActionVariables::parse_match_clause(action_name *an, wording W) {
+stacked_variable *ActionVariables::parse_match_clause(action_name *an, wording W) {
     return StackedVariables::parse_match_clause(an->action_variables, W);
 }
 
diff --git a/docs/if-module/4-ea.html b/docs/if-module/4-ea.html new file mode 100644 index 000000000..2b40450ac --- /dev/null +++ b/docs/if-module/4-ea.html @@ -0,0 +1,149 @@ + + + + Explicit Actions + + + + + + + + + + + + + + + + + + +
+ + +

An exactly specified action is called "explicit".

+ +

§1. Explicit actions are used inside the compiler whenever we kmow exactly what +action we are talking about; stored action constants are explicit_action +objects in a thin wrapper — see Action Kinds. +

+ +
+typedef struct explicit_action {
+    int request;
+    struct action_name *action;
+    struct parse_node *actor;
+    struct parse_node *first_noun;
+    struct parse_node *second_noun;
+    struct action_pattern *as_described;
+} explicit_action;
+
+
  • The structure explicit_action is accessed in 4/anaa, 4/ap2 and here.
+

§2.

+ +
define UNDERSPECIFIC_EA_FAILURE 1
+define OVERSPECIFIC_EA_FAILURE 2
+
+
+explicit_action *ExplicitActions::from_action_pattern(action_pattern *ap, int *reason) {
+    if (ExplicitActions::ap_underspecific(ap)) { *reason = UNDERSPECIFIC_EA_FAILURE; return NULL; }
+    if (ExplicitActions::ap_overspecific(ap)) { *reason = OVERSPECIFIC_EA_FAILURE; return NULL; }
+    *reason = 0;
+    explicit_action *ea = CREATE(explicit_action);
+    ea->action = ActionNameLists::get_the_one_true_action(ap->action_list);
+    ea->request = APClauses::is_request(ap);
+    ea->actor = APClauses::get_val(ap, ACTOR_AP_CLAUSE);
+    ea->first_noun = APClauses::get_val(ap, NOUN_AP_CLAUSE);
+    ea->second_noun = APClauses::get_val(ap, SECOND_AP_CLAUSE);
+    ea->as_described = ap;
+    return ea;
+}
+
+int ExplicitActions::ap_underspecific(action_pattern *ap) {
+    action_name *an = ActionPatterns::required_action(ap);
+    if (an == NULL) return TRUE;
+    if ((ActionSemantics::must_have_noun(an)) &&
+        (APClauses::get_val(ap, NOUN_AP_CLAUSE) == NULL)) return TRUE;
+    if ((ActionSemantics::must_have_second(an)) &&
+        (APClauses::get_val(ap, SECOND_AP_CLAUSE) == NULL)) return TRUE;
+    if ((ActionSemantics::can_have_noun(an)) &&
+        (ExplicitActions::clause_unspecific(ap, NOUN_AP_CLAUSE))) return TRUE;
+    if ((ActionSemantics::can_have_second(an)) &&
+        (ExplicitActions::clause_unspecific(ap, SECOND_AP_CLAUSE))) return TRUE;
+    if (ExplicitActions::clause_unspecific(ap, ACTOR_AP_CLAUSE)) return TRUE;
+    return FALSE;
+}
+
+int ExplicitActions::clause_unspecific(action_pattern *ap, int C) {
+    parse_node *spec = APClauses::get_val(ap, C);
+    if (spec == NULL) return FALSE;
+    if (Specifications::is_description(spec) == FALSE) return FALSE;
+    return TRUE;
+}
+
+int ExplicitActions::ap_overspecific(action_pattern *ap) {
+    for (ap_clause *apoc = (ap)?(ap->ap_clauses):NULL; apoc; apoc = apoc->next)
+        if ((APClauses::aspect(apoc) != PRIMARY_APCA) && (apoc->clause_spec))
+            return TRUE;
+    if (APClauses::has_any_actor(ap)) return TRUE;
+    if (ap->duration) return TRUE;
+    return FALSE;
+}
+
+ + +
+ + + diff --git a/docs/if-module/4-gng.html b/docs/if-module/4-gng.html index 05ab642a4..bc76e99ba 100644 --- a/docs/if-module/4-gng.html +++ b/docs/if-module/4-gng.html @@ -84,7 +84,7 @@ function togglePopup(material_id) {
 action_name *going_action = NULL;
-void Going::notice_new_action_name(action_name *an) {
+void Going::notice_new_action_name(action_name *an) {
     if (<going-action>(ActionNameNames::tensed(an, IS_TENSE))) going_action = an;
 }
 
@@ -198,7 +198,7 @@ function togglePopup(material_id) {

§5.

-int Going::check(action_pattern *ap) {
+int Going::check(action_pattern *ap) {
     if (Going::check_clause(APClauses::get_val(ap, GOING_FROM_AP_CLAUSE), "from",
         K_room, K_region) == FALSE) return FALSE;
     if (Going::check_clause(APClauses::get_val(ap, GOING_TO_AP_CLAUSE), "to",
@@ -249,20 +249,20 @@ function togglePopup(material_id) {
     return FALSE;
 }
 
-void Going::go_nowhere(action_pattern *ap) {
+void Going::go_nowhere(action_pattern *ap) {
     APClauses::set_val(ap, GOING_TO_AP_CLAUSE, Rvalues::new_nothing_object_constant());
 }
 
-void Going::go_somewhere(action_pattern *ap) {
+void Going::go_somewhere(action_pattern *ap) {
     APClauses::set_val(ap, GOING_TO_AP_CLAUSE, Descriptions::from_kind(K_room, FALSE));
 }
 
-int Going::going_nowhere(action_pattern *ap) {
+int Going::going_nowhere(action_pattern *ap) {
     if (Rvalues::is_nothing_object_constant(APClauses::get_val(ap, GOING_TO_AP_CLAUSE))) return TRUE;
     return FALSE;
 }
 
-int Going::going_somewhere(action_pattern *ap) {
+int Going::going_somewhere(action_pattern *ap) {
     parse_node *val = APClauses::get_val(ap, GOING_TO_AP_CLAUSE);
     if ((Descriptions::is_kind_like(val)) && (Kinds::eq(Descriptions::explicit_kind(val), K_room)))
         return TRUE;
@@ -296,7 +296,7 @@ to make sure it actually exists. So this can be used to see if the need arises:
 

§8.

-int Going::claim_noun(action_name *an, action_pattern *ap, wording W) {
+int Going::claim_noun(action_name *an, action_pattern *ap, wording W) {
     if ((an == going_action) && (<going-action-irregular-operand>(W))) {
         if (<<r>> == FALSE) Going::go_nowhere(ap);
         else Going::go_somewhere(ap);
@@ -306,7 +306,7 @@ to make sure it actually exists. So this can be used to see if the need arises:
 }
 
diff --git a/docs/if-module/4-nap.html b/docs/if-module/4-nap.html index 8c700e943..34f033033 100644 --- a/docs/if-module/4-nap.html +++ b/docs/if-module/4-nap.html @@ -135,7 +135,7 @@ an action. named_action_pattern *NamedActionPatterns::by_name(wording W) { parse_node *p = Lexicon::retrieve(NAMED_AP_MC, W); - if (p) return Rvalues::to_named_action_pattern(p); + if (p) return ARvalues::to_named_action_pattern(p); return NULL; } @@ -145,7 +145,7 @@ an action. nap->text_of_declaration = W; nap->compilation_data = RTNamedActionPatterns::new(nap); nap->as_noun = Nouns::new_proper_noun(W, NEUTER_GENDER, ADD_TO_LEXICON_NTOPT, - NAMED_AP_MC, Rvalues::from_named_action_pattern(nap), Task::language_of_syntax()); + NAMED_AP_MC, ARvalues::from_named_action_pattern(nap), Task::language_of_syntax()); return nap; }
@@ -177,7 +177,7 @@ if and only if it appears in one of the patterns in the list: }
diff --git a/docs/if-module/4-pap.html b/docs/if-module/4-pap.html index af90a64a4..0786440a1 100644 --- a/docs/if-module/4-pap.html +++ b/docs/if-module/4-pap.html @@ -73,26 +73,53 @@ function togglePopup(material_id) {

Turning text into APs.

-

§1. When we parse action patterns, we record why they fail, in order to make +

§1. Action patterns, such as "taking a container" or "opening a closed door", +are wrapped up as values here: +

+ +
+<s-action-pattern-as-value> internal {
+    if (Wordings::mismatched_brackets(W)) { ==> { fail nonterminal }; }
+    if (Lexer::word(Wordings::first_wn(W)) == OPENBRACE_V) { ==> { fail nonterminal }; }
+    int pto = permit_trying_omission;
+    if (<definite-article>(Wordings::first_word(W)) == FALSE) permit_trying_omission = TRUE;
+    int r = <action-pattern>(W);
+    permit_trying_omission = pto;
+    if (r) {
+        action_pattern *ap = <<rp>>;
+        if ((APClauses::get_val(ap, ACTOR_AP_CLAUSE)) &&
+            (Dash::validate_parameter(APClauses::get_val(ap, ACTOR_AP_CLAUSE), K_person) == FALSE)) {
+            r = <action-pattern>(W);
+        }
+    }
+    if (r) {
+        ==> { -, AConditions::new_action_TEST_VALUE(<<rp>>, W) };
+        return TRUE;
+    }
+    ==> { fail nonterminal };
+}
+
+ +

§2. When we parse action patterns, we record why they fail, in order to make it easier to produce helpful error messages. (We can't simply fire off errors at the time they occur, because text is often parsed in several contexts at once, so just because it fails this one does not mean it is wrong.) PAPF stands for "parse action pattern failure".

-
define MISC_PAPF 1
-define NOPARTICIPLE_PAPF 2
-define MIXEDNOUNS_PAPF 3
-define WHEN_PAPF 4
-define WHENOKAY_PAPF 5
-define IMMISCIBLE_PAPF 6
+
define MISC_PAPF 1
+define NOPARTICIPLE_PAPF 2
+define MIXEDNOUNS_PAPF 3
+define WHEN_PAPF 4
+define WHENOKAY_PAPF 5
+define IMMISCIBLE_PAPF 6
 
 int pap_failure_reason;  one of the above
 int permit_trying_omission = FALSE;  allow the keyword 'trying' to be omitted
 int permit_nonconstant_action_parameters = TRUE;
 
-

§2. NB: Next time this is rewritten - (1) handle in, in the presence of, with +

§3. NB: Next time this is rewritten - (1) handle in, in the presence of, with STV clauses; (2) get this right:

@@ -103,7 +130,7 @@ STV clauses; (2) get this right: say "Where did you want to go?"

-

§3. First a much easier, parametric form of parsing, used for the APs which +

§4. First a much easier, parametric form of parsing, used for the APs which form the usage conditions for rules in object-based rulebooks.

@@ -111,23 +138,23 @@ form the usage conditions for rules in object-based rulebooks. action_pattern ParseActionPatterns::parametric(wording W, kind *K) { action_pattern ap = ActionPatterns::new(); ap.parameter_kind = K; - parse_node *spec = ParseActionPatterns::parameter(W); + parse_node *spec = ParseActionPatterns::parameter(W); APClauses::set_val(&ap, PARAMETRIC_AP_CLAUSE, spec); ap.valid = Dash::validate_parameter(spec, K); return ap; }
-

§4. A useful utility: parsing a parameter in an action pattern. +

§5. A useful utility: parsing a parameter in an action pattern.

-parse_node *ParseActionPatterns::parameter(wording W) {
+parse_node *ParseActionPatterns::parameter(wording W) {
     if (<action-parameter>(W)) return <<rp>>;
     return Specifications::new_UNKNOWN(W);
 }
 
 parse_node *ParseActionPatterns::verified_action_parameter(wording W) {
-    parse_node *spec = ParseActionPatterns::parameter(W);
+    parse_node *spec = ParseActionPatterns::parameter(W);
     if (Node::is(spec, UNKNOWN_NT)) {
         Problems::quote_source(1, current_sentence);
         Problems::quote_wording(2, W);
@@ -141,7 +168,7 @@ form the usage conditions for rules in object-based rulebooks.
     return spec;
 }
 
-

§5.

+

§6.

 int scanning_anl_only_mode = FALSE;
@@ -164,7 +191,7 @@ form the usage conditions for rules in object-based rulebooks.
     return anl;
 }
 
-

§6. The main action pattern parser is called only by the following shell +

§7. The main action pattern parser is called only by the following shell routine, which exists in order to change some parsing rules.

@@ -177,7 +204,7 @@ matched action pattern. wording last_successful_wording = EMPTY_WORDING_INIT; int prevailing_ap_tense = IS_TENSE;
-

§7. In fact these codes aren't used any more: +

§8. In fact these codes aren't used any more:

define ACTOR_REQUESTED 0
@@ -186,7 +213,7 @@ matched action pattern.
 define ACTOR_EXPLICITLY_PLAYER 3
 define ACTOR_IMPLICITLY_PLAYER 4
 
-

§8. Action patterns are textual descriptions which act as predicates on actions, +

§9. Action patterns are textual descriptions which act as predicates on actions, that is, they are descriptions which are true of some actions and false of others. For example,

@@ -234,7 +261,7 @@ These are always present tense, and can't be negated. <action-pattern-core-actor> ==> { ACTOR_IMPLICITLY_PLAYER, RP[1] };
-

§9. The second version is for contexts where the AP occurs as a condition: e.g., +

§10. The second version is for contexts where the AP occurs as a condition: e.g., in a sentence like "if we have taken a jewel". Since these can occur in both tenses and can be negated ("if we are not taking a jewel"), there are four combinations: @@ -280,7 +307,7 @@ four combinations: we have not <action-pattern-past-core> ==> { ACTOR_EXPLICITLY_PLAYER, RP[1] };

-

§10. There is one more tweak at this top level. Inform allows an ambiguous but +

§11. There is one more tweak at this top level. Inform allows an ambiguous but shorter and more natural syntax in which the actor's name simply appears at the front of the AP:

@@ -302,7 +329,7 @@ actorless possibility can always be written. <actor-description> <action-pattern-core> ==> { ACTOR_NAMED, RP[2] }; action_pattern *ap = *XP; APClauses::clear_request(ap); APClauses::set_val(ap, ACTOR_AP_CLAUSE, RP[1]);
-

§11. And this voracious token matches the actor's name as an initial excerpt, +

§12. And this voracious token matches the actor's name as an initial excerpt, which is much faster than exhaustive searching. It tries to break just before any "-ing" word (i.e., participle) which is not inside parentheses; but only if the resulting name matches <action-parameter> as a constant, @@ -332,9 +359,9 @@ would match as an abbreviated form of the name of "angry waiting man". if (<k-kind>(Wordings::up_to(W, i-1))) continue; parse_node *try_stem = NULL; instance *I; - int old_state = ParseActionPatterns::suppress(); + int old_state = ParseActionPatterns::suppress(); if (<action-parameter>(Wordings::up_to(W, i-1))) try_stem = <<rp>>; - ParseActionPatterns::resume(old_state); + ParseActionPatterns::resume(old_state); int k = 0; LOOP_THROUGH_WORDING(j, Wordings::up_to(W, i-1)) if (Vocabulary::test_flags(j, ACTION_PARTICIPLE_MC)) k++; @@ -358,20 +385,20 @@ would match as an abbreviated form of the name of "angry waiting man". }

-

§12.

+

§13.

-int ParseActionPatterns::suppress(void) {
+int ParseActionPatterns::suppress(void) {
     int old_state = suppress_ap_parsing;
     suppress_ap_parsing = TRUE;
     return old_state;
 }
 
-void ParseActionPatterns::resume(int old_state) {
+void ParseActionPatterns::resume(int old_state) {
     suppress_ap_parsing = old_state;
 }
 
-

§13. That completes the top level, and we can forget about actors. All of those +

§14. That completes the top level, and we can forget about actors. All of those productions come down now to just two nonterminals, one for the present tense,

@@ -399,19 +426,19 @@ trimmed away;
 <action-pattern-core> internal {
     if (suppress_ap_parsing) return FALSE;
-    action_pattern *ap = ParseActionPatterns::inner(W, IS_TENSE);
+    action_pattern *ap = ParseActionPatterns::inner(W, IS_TENSE);
     if (ap) { ==> { -, ap }; return TRUE; }
     ==> { fail nonterminal };
 }
 
 <action-pattern-past-core> internal {
-    action_pattern *ap = ParseActionPatterns::inner(W, HASBEEN_TENSE);
+    action_pattern *ap = ParseActionPatterns::inner(W, HASBEEN_TENSE);
     if (ap) { ==> { -, ap }; return TRUE; }
     ==> { fail nonterminal };
 }
 
-

§14. "Doing it" is not the happiest of syntaxes. The idea is for this to be +

§15. "Doing it" is not the happiest of syntaxes. The idea is for this to be a sort of pronoun for actions, allowing for anaphora, but to parse such things naturally in all cases is wishful thinking. It enables us to write, e.g.:

@@ -429,10 +456,10 @@ possibility for confusion is too great; perhaps we should just cut this idea. doing it
-

§15.

+

§16.

-action_pattern *ParseActionPatterns::inner(wording W, int tense) {
+action_pattern *ParseActionPatterns::inner(wording W, int tense) {
     if (Lexer::word(Wordings::first_wn(W)) == OPENBRACE_V) return NULL;
 
     if (Wordings::empty(W)) internal_error("PAP on illegal word range");
@@ -472,7 +499,7 @@ possibility for confusion is too great; perhaps we should just cut this idea.
     return ap;
 }
 
-

§16. Anyway, we are now down to level 3: all action patterns have been whittled +

§17. Anyway, we are now down to level 3: all action patterns have been whittled down to a single use of <ap-common-core>. Our next step is to recognise a condition attached with "when":

@@ -485,7 +512,7 @@ a condition attached with "when": ... when/while ... ==> { 0, NULL }; if (pap_failure_reason != WHENOKAY_PAPF) pap_failure_reason = WHEN_PAPF; return FALSE; used only to diagnose problems
-

§17. <condition-in-ap> is really just <spec-condition> in disguise — i.e., +

§18. <condition-in-ap> is really just <spec-condition> in disguise — i.e., it matches a standard Inform condition — but it's implemented as an internal to enable Inform to set up a stack frame if there isn't one already, and so on.

@@ -515,7 +542,7 @@ to enable Inform to set up a stack frame if there isn't one already, and so on. } -

§18. Level 4 now. The optional "in the presence of": +

§19. Level 4 now. The optional "in the presence of":

@@ -524,7 +551,7 @@ to enable Inform to set up a stack frame if there isn't one already, and so on.
     <ap-common-core-inner-inner>                                            ==> { 0, RP[1] };
 
-

§19. Level 5 now. The initial "in" clause, e.g., "in the Pantry", requires +

§20. Level 5 now. The initial "in" clause, e.g., "in the Pantry", requires special handling to prevent it from clashing with other interpretations of "in" elsewhere in the grammar. It's perhaps unexpected that "in the Pantry" is valid as an AP, but this enables many natural-looking rules to be written @@ -533,11 +560,11 @@ is valid as an AP, but this enables many natural-looking rules to be written

 <ap-common-core-inner-inner> ::=
-    in <action-parameter> |             ==> Make an actionless action pattern, specifying room only19.1
+    in <action-parameter> |             ==> Make an actionless action pattern, specifying room only20.1
     <ap-common-core-inner-inner-inner>  ==> { 0, RP[1] };
 
-

§19.1. Make an actionless action pattern, specifying room only19.1 = +

§20.1. Make an actionless action pattern, specifying room only20.1 =

@@ -549,8 +576,8 @@ is valid as an AP, but this enables many natural-looking rules to be written
     APClauses::set_val(&ap, IN_AP_CLAUSE, RP[1]);
     ==> { 0, ActionPatterns::ap_store(ap) };
 
-
  • This code is used in §19.
-

§20. And that's as far down as we go: to level 6. Most of the complexity is gone +

  • This code is used in §20.
+

§21. And that's as far down as we go: to level 6. Most of the complexity is gone now, but what's left can't very efficiently be written in Preform. Essentially we apply <action-list> to the text and then parse the operands using <action-operand>, though it's a bit more involved because we also recognise @@ -574,7 +601,7 @@ box" makes no sense since only one is transitive). } else { LOGIF(ACTION_PATTERN_PARSING, "Parsing action pattern: %W\n", W); LOG_INDENT; - action_pattern ap = ParseActionPatterns::dash(W); + action_pattern ap = ParseActionPatterns::dash(W); LOG_OUTDENT; if (ActionPatterns::is_valid(&ap)) { ==> { -, ActionPatterns::ap_store(ap) }; @@ -585,7 +612,7 @@ box" makes no sense since only one is transitive). }

-

§21. The "operands" of an action pattern are the nouns to which it applies: for +

§22. The "operands" of an action pattern are the nouns to which it applies: for example, in "Kevin taking or dropping something", the operand is "something". We treat words like "something" specially to avoid them being read as "some thing" and thus forcing the kind of the operand to be "thing". @@ -602,7 +629,7 @@ We treat words like "something" specially to avoid them being read as it ==> { FALSE, - }

-

§22. Finally, then, <action-parameter>. Almost anything syntactically matches +

§23. Finally, then, <action-parameter>. Almost anything syntactically matches here — a constant, a description, a table entry, a variable, and so on.

@@ -619,11 +646,11 @@ here — a constant, a description, a table entry, a variable, and so on. } -

§23. We can't put it off any longer. Here goes. +

§24. We can't put it off any longer. Here goes.

-action_pattern ParseActionPatterns::dash(wording W) {
+action_pattern ParseActionPatterns::dash(wording W) {
     int failure_this_call = pap_failure_reason;
     int i, j, k = 0;
     action_name_list *list = NULL;
@@ -632,19 +659,19 @@ here — a constant, a description, a table entry, a variable, and so on.
     action_pattern ap = ActionPatterns::new(); ap.valid = FALSE;
     ap.text_of_pattern = W;
 
-    PAR - (f) Parse Special Going Clauses23.3;
-    PAR - (i) Parse Initial Action Name List23.4;
-    PAR - (j) Parse Parameters23.5;
-    PAR - (k) Verify Mixed Action23.6;
-    With one small proviso, a valid action pattern has been parsed23.1;
+    PAR - (f) Parse Special Going Clauses24.3;
+    PAR - (i) Parse Initial Action Name List24.4;
+    PAR - (j) Parse Parameters24.5;
+    PAR - (k) Verify Mixed Action24.6;
+    With one small proviso, a valid action pattern has been parsed24.1;
     return ap;
 
     Failed: ;
-    No valid action pattern has been parsed23.2;
+    No valid action pattern has been parsed24.2;
     return ap;
 }
 
-

§23.1. With one small proviso, a valid action pattern has been parsed23.1 = +

§24.1. With one small proviso, a valid action pattern has been parsed24.1 =

@@ -666,8 +693,8 @@ here — a constant, a description, a table entry, a variable, and so on.
     if (ap.valid == FALSE) goto Failed;
     LOGIF(ACTION_PATTERN_PARSING, "Matched action pattern: $A\n", &ap);
 
-
  • This code is used in §23.
-

§23.2. No valid action pattern has been parsed23.2 = +

  • This code is used in §24.
+

§24.2. No valid action pattern has been parsed24.2 =

@@ -676,12 +703,12 @@ here — a constant, a description, a table entry, a variable, and so on.
     ap.ap_clauses = NULL;
     LOGIF(ACTION_PATTERN_PARSING, "Parse action failed: %W\n", W);
 
-
  • This code is used in §23.
-

§23.3. Special clauses are allowed after "going..."; trim them +

  • This code is used in §24.
+

§24.3. Special clauses are allowed after "going..."; trim them away as they are recorded.

-

PAR - (f) Parse Special Going Clauses23.3 = +

PAR - (f) Parse Special Going Clauses24.3 =

@@ -714,13 +741,13 @@ away as they are recorded.
         if (j >= 0) W = Wordings::up_to(W, j);
     }
 
-
  • This code is used in §23.
-

§23.4. Extract the information as to which actions are intended: +

  • This code is used in §24.
+

§24.4. Extract the information as to which actions are intended: e.g., from "taking or dropping something", that it will be taking or dropping.

-

PAR - (i) Parse Initial Action Name List23.4 = +

PAR - (i) Parse Initial Action Name List24.4 =

@@ -729,8 +756,8 @@ taking or dropping.
     list = try_list;
     LOGIF(ACTION_PATTERN_PARSING, "ANL from PAR(i):\n$L\n", list);
 
-
  • This code is used in §23.
-

§23.5. Now to fill in the gaps. At this point we have the action name +

  • This code is used in §24.
+

§24.5. Now to fill in the gaps. At this point we have the action name list as a linked list of all possible lexical matches, but want to whittle it down to remove those which do not semantically make sense. For instance, "taking inventory" has two possible lexical @@ -748,23 +775,23 @@ crucial word position except for the one matched.

define MAX_AP_POSITIONS 100
 define UNTHINKABLE_POSITION -1
 
-

PAR - (j) Parse Parameters23.5 = +

PAR - (j) Parse Parameters24.5 =

     int no_positions = 0;
     int position_at[MAX_AP_POSITIONS], position_min_parc[MAX_AP_POSITIONS];
-    Find the positions of individual action names, and their minimum parameter counts23.5.1;
-    Report to the debugging log on the action decomposition23.5.2;
-    Find how many different positions have each possible minimum count23.5.3;
+    Find the positions of individual action names, and their minimum parameter counts24.5.1;
+    Report to the debugging log on the action decomposition24.5.2;
+    Find how many different positions have each possible minimum count24.5.3;
 
     int first_position = ActionNameLists::first_position(list);
     int one_was_valid = FALSE;
     action_pattern trial_ap;
     LOOP_THROUGH_ANL(entry, list) {
         LOGIF(ACTION_PATTERN_PARSING, "Entry (%d):\n$8\n", ActionNameLists::parc(entry), entry);
-        Fill out the noun, second, room and nowhere fields of the AP as if this action were right23.5.4;
-        Check the validity of this speculative AP23.5.5;
+        Fill out the noun, second, room and nowhere fields of the AP as if this action were right24.5.4;
+        Check the validity of this speculative AP24.5.5;
         if ((trial_ap.valid) && (one_was_valid == FALSE) && (ActionNameLists::word_position(entry) == first_position)) {
             one_was_valid = TRUE;
             APClauses::set_val(&ap, NOUN_AP_CLAUSE, APClauses::get_val(&trial_ap, NOUN_AP_CLAUSE));
@@ -778,32 +805,32 @@ crucial word position except for the one matched.
     }
     if (one_was_valid == FALSE) goto Failed;
 
-    Adjudicate between topic and other actions23.5.6;
+    Adjudicate between topic and other actions24.5.6;
     LOGIF(ACTION_PATTERN_PARSING, "List before action winnowing:\n$L\n", list);
-    Delete those action names which are to be deleted23.5.7;
+    Delete those action names which are to be deleted24.5.7;
     LOGIF(ACTION_PATTERN_PARSING, "List after action winnowing:\n$L\n", list);
 
-
  • This code is used in §23.
-

§23.5.1. For example, "taking inventory or waiting" produces two positions, words +

  • This code is used in §24.
+

§24.5.1. For example, "taking inventory or waiting" produces two positions, words 0 and 3, and minimum parameter count 0 in each case. ("Taking inventory" can be read as "taking (inventory)", par-count 1, or "taking inventory", par-count 0, so the minimum is 0.)

-

Find the positions of individual action names, and their minimum parameter counts23.5.1 = +

Find the positions of individual action names, and their minimum parameter counts24.5.1 =

     LOOP_THROUGH_ANL(entry, list) {
         int pos = -1;
-        Find the position word of this particular action name23.5.1.1;
+        Find the position word of this particular action name24.5.1.1;
         if ((position_min_parc[pos] == UNTHINKABLE_POSITION) ||
             (ActionNameLists::parc(entry) < position_min_parc[pos]))
             position_min_parc[pos] = ActionNameLists::parc(entry);
     }
 
- -

§23.5.1.1. Find the position word of this particular action name23.5.1.1 = +

+

§24.5.1.1. Find the position word of this particular action name24.5.1.1 =

@@ -818,8 +845,8 @@ par-count 0, so the minimum is 0.)
         pos = no_positions++;
     }
 
- -

§23.5.2. Report to the debugging log on the action decomposition23.5.2 = +

+

§24.5.2. Report to the debugging log on the action decomposition24.5.2 =

@@ -830,14 +857,14 @@ par-count 0, so the minimum is 0.)
             i, position_at[i], min);
     }
 
- -

§23.5.3. The following test is done to reject patterns like "taking ball or dropping +

+

§24.5.3. The following test is done to reject patterns like "taking ball or dropping bat", which have a positive minimum parameter count in more than one position; which means there couldn't be an action pattern which shared the same noun description.

-

Find how many different positions have each possible minimum count23.5.3 = +

Find how many different positions have each possible minimum count24.5.3 =

@@ -853,15 +880,15 @@ description.
         failure_this_call = MIXEDNOUNS_PAPF; goto Failed;
     }
 
- -

§23.5.4. Fill out the noun, second, room and nowhere fields of the AP as if this action were right23.5.4 = +

+

§24.5.4. Fill out the noun, second, room and nowhere fields of the AP as if this action were right24.5.4 =

     trial_ap.ap_clauses = NULL;
     if (Wordings::nonempty(ActionNameLists::par(entry, 0))) {
         if (Going::claim_noun(ActionNameLists::action(entry), &trial_ap, ActionNameLists::par(entry, 0)) == FALSE)
-            ParseActionPatterns::put_action_object_into_ap(&trial_ap, NOUN_AP_CLAUSE, ActionNameLists::par(entry, 0));
+            ParseActionPatterns::put_action_object_into_ap(&trial_ap, NOUN_AP_CLAUSE, ActionNameLists::par(entry, 0));
     }
 
     if (Wordings::nonempty(ActionNameLists::par(entry, 1))) {
@@ -869,20 +896,20 @@ description.
             && (K_understanding)
             && (Kinds::eq(ActionSemantics::kind_of_second(ActionNameLists::action(entry)), K_understanding))
             && (<understanding-action-irregular-operand>(ActionNameLists::par(entry, 1)))) {
-            parse_node *val = Rvalues::from_grammar_verb(NULL);  Why no GV here?
+            parse_node *val = ARvalues::from_grammar_verb(NULL);  Why no GV here?
             Node::set_text(val, ActionNameLists::par(entry, 1));
             APClauses::set_val(&trial_ap, SECOND_AP_CLAUSE, val);
         } else {
-            ParseActionPatterns::put_action_object_into_ap(&trial_ap, SECOND_AP_CLAUSE, ActionNameLists::par(entry, 1));
+            ParseActionPatterns::put_action_object_into_ap(&trial_ap, SECOND_AP_CLAUSE, ActionNameLists::par(entry, 1));
         }
     }
 
     if (Wordings::nonempty(ActionNameLists::in_clause(entry)))
-        ParseActionPatterns::put_action_object_into_ap(&trial_ap, IN_AP_CLAUSE,
+        ParseActionPatterns::put_action_object_into_ap(&trial_ap, IN_AP_CLAUSE,
             ActionNameLists::in_clause(entry));
 
- -

§23.5.5. Check the validity of this speculative AP23.5.5 = +

+

§24.5.5. Check the validity of this speculative AP24.5.5 =

@@ -900,8 +927,8 @@ description.
     if (APClauses::validate(APClauses::clause(&trial_ap, IN_AP_CLAUSE), K_object) == FALSE)
         trial_ap.valid = FALSE;
 
- -

§23.5.6. Adjudicate between topic and other actions23.5.6 = +

+

§24.5.6. Adjudicate between topic and other actions24.5.6 =

@@ -942,15 +969,15 @@ description.
         }
     }
 
- -

§23.5.7. Delete those action names which are to be deleted23.5.7 = +

+

§24.5.7. Delete those action names which are to be deleted24.5.7 =

     ActionNameLists::remove_entries_marked_for_deletion(list);
 
- -

§23.6. Not all actions can cohabit. We require that as far as the user has +

+

§24.6. Not all actions can cohabit. We require that as far as the user has specified the parameters, the actions in the list must all agree (i) to be allowed to have such a parameter, and (ii) to be allowed to have a parameter of the same type. Thus "waiting or taking something" fails @@ -960,7 +987,7 @@ that the "doing anything" action is always allowed a parameter (this is the case when the first action name in the list is NULL).

-

PAR - (k) Verify Mixed Action23.6 = +

PAR - (k) Verify Mixed Action24.6 =

@@ -1010,13 +1037,13 @@ the case when the first action name in the list is         goto Failed;
     }
 
-
  • This code is used in §23.
-

§24. And an anticlimactic little routine for putting objects +

  • This code is used in §24.
+

§25. And an anticlimactic little routine for putting objects into action patterns in the noun or second noun position.

-void ParseActionPatterns::put_action_object_into_ap(action_pattern *ap, int C, wording W) {
+void ParseActionPatterns::put_action_object_into_ap(action_pattern *ap, int C, wording W) {
     parse_node *spec = NULL;
     int any_flag = FALSE;
     if (<action-operand>(W)) {
@@ -1034,7 +1061,7 @@ into action patterns in the noun or second noun position.
 }
 
diff --git a/docs/if-module/5-gpr.html b/docs/if-module/5-gpr.html index a3f372d54..ca789f7cc 100644 --- a/docs/if-module/5-gpr.html +++ b/docs/if-module/5-gpr.html @@ -169,7 +169,7 @@ will simply compile a parse_n return gv->gv_parse_name_iname; } -inter_name *PL::Parsing::Tokens::General::compile_parse_name_property(inference_subject *subj) { +inter_name *PL::Parsing::Tokens::General::compile_parse_name_property(inference_subject *subj) { inter_name *symb = NULL; grammar_verb *gv = PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object; if (PL::Parsing::Verbs::is_empty(gv) == FALSE) { diff --git a/docs/if-module/5-gt2.html b/docs/if-module/5-gt2.html index 3ed7994dc..70860ad09 100644 --- a/docs/if-module/5-gt2.html +++ b/docs/if-module/5-gt2.html @@ -507,7 +507,7 @@ look seriously at tokens is in Phase II.

-    parse_node *val = Rvalues::from_grammar_verb(<<grammar_verb:named>>);
+    parse_node *val = ARvalues::from_grammar_verb(<<grammar_verb:named>>);
     spec = PL::Parsing::Verbs::determine(<<grammar_verb:named>>, depth+1);  this is where Phase II recurses
     Node::set_grammar_value(pn, val);
 
@@ -1387,7 +1387,7 @@ nothing else. } else { if (Node::is(spec, CONSTANT_NT)) { if ((K_understanding) && (Rvalues::is_CONSTANT_of_kind(spec, K_understanding))) { - gv = Rvalues::to_grammar_verb(spec); + gv = ARvalues::to_grammar_verb(spec); if (code_mode) { Produce::inv_primitive(Emit::tree(), STORE_BIP); Produce::down(Emit::tree()); diff --git a/docs/if-module/5-pp.html b/docs/if-module/5-pp.html index c68a26b03..ef427d7de 100644 --- a/docs/if-module/5-pp.html +++ b/docs/if-module/5-pp.html @@ -84,10 +84,11 @@ chapter. PluginManager::plug(PRODUCTION_LINE_PLUG, ParsingPlugin::production_line); PluginManager::plug(MAKE_SPECIAL_MEANINGS_PLUG, ParsingPlugin::make_special_meanings); - PluginManager::plug(NEW_VARIABLE_NOTIFY_PLUG, ParsingPlugin::new_variable_notify); + PluginManager::plug(COMPARE_CONSTANT_PLUG, ParsingPlugin::compare_CONSTANT); + PluginManager::plug(NEW_VARIABLE_NOTIFY_PLUG, ParsingPlugin::new_variable_notify); PluginManager::plug(NEW_SUBJECT_NOTIFY_PLUG, ParsingPlugin::new_subject_notify); PluginManager::plug(NEW_PERMISSION_NOTIFY_PLUG, Visibility::new_permission_notify); - PluginManager::plug(COMPLETE_MODEL_PLUG, ParsingPlugin::complete_model); + PluginManager::plug(COMPLETE_MODEL_PLUG, ParsingPlugin::complete_model); } int ParsingPlugin::production_line(int stage, int debugging, @@ -128,7 +129,22 @@ chapter. return FALSE; } -

§2. A number of global variables are given special treatment here, including +

§2.

+ +
+int ParsingPlugin::compare_CONSTANT(parse_node *spec1, parse_node *spec2, int *rv) {
+    kind *K = Node::get_kind_of_value(spec1);
+    if (Kinds::eq(K, K_understanding)) {
+        if (ARvalues::to_grammar_verb(spec1) == ARvalues::to_grammar_verb(spec2)) {
+            *rv = TRUE;
+        }
+        *rv = FALSE;
+        return TRUE;
+    }
+    return FALSE;
+}
+
+

§3. A number of global variables are given special treatment here, including a whole family with names like "the K understood", for different kinds K. This is an awkward contrivance to bridge Inform 7, which is typed, with the original Inform 6 parser at runtime, whose data is typeless. @@ -144,7 +160,7 @@ original Inform 6 parser at runtime, whose data is typeless. person asked ==> { 5, - }

-

§3.

+

§4.

 nonlocal_variable *real_location_VAR = NULL;
@@ -154,10 +170,10 @@ original Inform 6 parser at runtime, whose data is typeless.
 nonlocal_variable *I6_second_VAR = NULL;
 nonlocal_variable *I6_actor_VAR = NULL;
 
-

§4.

+

§5.

-int ParsingPlugin::new_variable_notify(nonlocal_variable *var) {
+int ParsingPlugin::new_variable_notify(nonlocal_variable *var) {
     if (<notable-parsing-variables>(var->name)) {
         switch (<<r>>) {
             case 0:
@@ -176,7 +192,7 @@ original Inform 6 parser at runtime, whose data is typeless.
     return FALSE;
 }
 
-

§5. Once the traverse is done, we can infer values for the two key Inter properties +

§6. Once the traverse is done, we can infer values for the two key Inter properties for parsing:

@@ -188,7 +204,7 @@ for parsing: return P_name; } -int ParsingPlugin::complete_model(int stage) { +int ParsingPlugin::complete_model(int stage) { if (stage == WORLD_STAGE_V) { instance *I; P_name = ValueProperties::new_nameless(I"name", K_text); @@ -199,25 +215,25 @@ for parsing: LOOP_OVER_INSTANCES(I, K_object) { inference_subject *subj = Instances::as_subject(I); - Assert the Inter name property5.1; - Assert the Inter parse-name property5.2; - Assert the Inter action-bitmap property5.3; + Assert the Inter name property6.1; + Assert the Inter parse-name property6.2; + Assert the Inter action-bitmap property6.3; } kind *K; LOOP_OVER_BASE_KINDS(K) if (Kinds::Behaviour::is_subkind_of_object(K)) { inference_subject *subj = KindSubjects::from_kind(K); - Assert the Inter parse-name property5.2; + Assert the Inter parse-name property6.2; } inference_subject *subj = KindSubjects::from_kind(K_thing); - Assert the Inter action-bitmap property5.3; + Assert the Inter action-bitmap property6.3; } return FALSE; } -

§5.1. Assert the Inter name property5.1 = +

§6.1. Assert the Inter name property6.1 =

@@ -238,12 +254,12 @@ for parsing:
             RTParsing::name_property_array(I, W, PW, from_kind), CERTAIN_CE);
     }
 
-
  • This code is used in §5.
-

§5.2. We attach numbered parse name routines as properties for any object +

  • This code is used in §6.
+

§6.2. We attach numbered parse name routines as properties for any object where grammar has specified a need. (By default, this will not happen.)

-

Assert the Inter parse-name property5.2 = +

Assert the Inter parse-name property6.2 =

@@ -252,8 +268,8 @@ where grammar has specified a need. (By default, this will not happen.)
         ValueProperties::assert(P_parse_name, subj,
             Rvalues::from_iname(S), CERTAIN_CE);
 
-
  • This code is used in §5 (twice).
-

§5.3. The action bitmap is an array of bits attached to each object, one +

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

§6.3. The action bitmap is an array of bits attached to each object, one for each action, which records whether that action has yet applied successfully to that object. This is used at run-time to handle past tense conditions such as "the jewels have been taken". Note that @@ -262,7 +278,7 @@ to ensure that it will be inherited by all Inter objects of this class, i.e., all Inter objects corresponding to I7 things.

-

Assert the Inter action-bitmap property5.3 = +

Assert the Inter action-bitmap property6.3 =

@@ -274,7 +290,7 @@ i.e., all Inter objects corresponding to I7 things.
             ValueProperties::assert(P_action_bitmap, subj, S, CERTAIN_CE);
         }
 
-
  • This code is used in §5 (twice).
+
  • This code is used in §6 (twice).
diff --git a/docs/if-module/5-tfg.html b/docs/if-module/5-tfg.html index a4ff24679..f84f2720f 100644 --- a/docs/if-module/5-tfg.html +++ b/docs/if-module/5-tfg.html @@ -108,7 +108,7 @@ function togglePopup(material_id) { struct understanding_reference *next; } understanding_reference; -
  • The structure understanding_item is accessed in 2/ri, 3/tm, 3/scn, 3/ts, 4/ap, 4/av, 4/ap2, 4/apc, 5/gl and here.
  • The structure understanding_reference is accessed in 2/ri, 3/tm, 3/scn, 3/ts, 4/ap, 4/av, 4/ap2, 4/apc, 5/gl and here.
+
  • The structure understanding_item is accessed in 2/ri, 3/tm, 3/scn, 3/ts, 4/ap, 4/av, 4/ap2, 4/ea, 4/apc, 5/gl and here.
  • The structure understanding_reference is accessed in 2/ri, 3/tm, 3/scn, 3/ts, 4/ap, 4/av, 4/ap2, 4/ea, 4/apc, 5/gl and here.

§3. New grammar arrives in the system in two ways: primarily by means of explicit Understand sentences in the source text, but also secondarily in the form of table entries or other values used to match against snippets. For example: diff --git a/docs/if-module/index.html b/docs/if-module/index.html index a739b0b9d..80cd31b81 100644 --- a/docs/if-module/index.html +++ b/docs/if-module/index.html @@ -198,6 +198,16 @@ Actions-Only Nodes and Annotations - Additional syntax tree node and annotation types used by the actions plugin.

+
  • +

    + Action Kinds - + Three action-related kinds of value.

    +
  • +
  • +

    + Action Conditions - + A special condition for testing against action patterns.

    +
  • Actions - @@ -228,6 +238,11 @@ Action Patterns - An action pattern is a description which may match many actions or none. The text "doing something" matches every action, while "throwing something at a door in a dark room" is seldom matched.

  • +
  • +

    + Explicit Actions - + An exactly specified action is called "explicit".

    +
  • Action Pattern Clauses - diff --git a/docs/imperative-module/4-chr.html b/docs/imperative-module/4-chr.html index 7f4331fec..a0639234a 100644 --- a/docs/imperative-module/4-chr.html +++ b/docs/imperative-module/4-chr.html @@ -267,8 +267,9 @@ storage: the following simple structures are used for this. #ifdef IF_MODULE action_pattern *ap = NULL; - if (Node::is(spec, TEST_VALUE_NT)) ap = Rvalues::to_action_pattern(spec->down); + if (AConditions::is_action_TEST_VALUE(spec)) ap = ActionPatterns::action_from_TEST(spec); if ((ap) && (tense != IS_TENSE)) { +LOG("Here we go! $A\n", ap); if ((duration) && (Occurrence::units(duration) == TIMES_UNIT) && (Occurrence::length(duration) >= 2)) { StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_NoMoreRonNewcombMoment), "a condition like 'we have X', where X is an action, has either " diff --git a/docs/imperative-module/6-pi.html b/docs/imperative-module/6-pi.html index d33164507..1ffff7820 100644 --- a/docs/imperative-module/6-pi.html +++ b/docs/imperative-module/6-pi.html @@ -512,7 +512,7 @@ parser needs our help in the first place.)

         if (<action-pattern>(XW))
    -        as_parsed = Conditions::new_TEST_ACTION(<<rp>>, XW);
    +        as_parsed = AConditions::new_action_TEST_VALUE(<<rp>>, XW);
         else {
             permit_trying_omission = FALSE;
             Parse any other token5.2;
    diff --git a/docs/runtime-module/5-act.html b/docs/runtime-module/5-act.html
    index 888b56fc2..84633d1bc 100644
    --- a/docs/runtime-module/5-act.html
    +++ b/docs/runtime-module/5-act.html
    @@ -429,7 +429,7 @@ infrastructure, and we access it with a single call.
         if (PluginManager::active(actions_plugin) == FALSE)
             internal_error("actions plugin inactive");
         if (Kinds::eq(K, K_action_name)) {
    -        action_name *an = Rvalues::to_action_name(spec);
    +        action_name *an = ARvalues::to_action_name(spec);
             if (Holsters::data_acceptable(VH)) {
                 inter_name *N = RTActions::iname(an);
                 if (N) Emit::holster(VH, N);
    diff --git a/docs/runtime-module/5-ap.html b/docs/runtime-module/5-ap.html
    index f82e0287f..535d8d4ff 100644
    --- a/docs/runtime-module/5-ap.html
    +++ b/docs/runtime-module/5-ap.html
    @@ -428,9 +428,10 @@ and in this case we therefore ignore void RTActionPatterns::compile_pattern_match(value_holster *VH, action_pattern ap, int naming_mode) {
         int cpm_count = 0, needed[MAX_CPM_CLAUSES];
         ap_clause *needed_apoc[MAX_CPM_CLAUSES];
    -    LOGIF(ACTION_PATTERN_COMPILATION, "Compiling action pattern:\n  $A", &ap);
    +    LOGIF(ACTION_PATTERN_COMPILATION, "Compiling action pattern:\n  $A\n", &ap);
     
         if (ap.duration) {
    +        LOGIF(ACTION_PATTERN_COMPILATION, "As past action\n");
             Chronology::compile_past_action_pattern(VH, ap.duration, ap);
         } else {
             kind *kind_of_noun = K_object;
    diff --git a/docs/values-module/2-cnd.html b/docs/values-module/2-cnd.html
    index 762ef137d..7324a15d8 100644
    --- a/docs/values-module/2-cnd.html
    +++ b/docs/values-module/2-cnd.html
    @@ -86,7 +86,7 @@ function togglePopup(material_id) {
         
     

    States of being which at any given point, at run-time, might be true or false.

    -
    +

    §1. Creation. In Inform, conditions are not values, nor can values be used directly as conditions: we therefore need to provide the logical operations of AND, OR, @@ -150,7 +150,7 @@ in any other way.)

     parse_node *Conditions::new(time_period *tp) {
         parse_node *spec = Node::new(TEST_PROPOSITION_NT);
    -    Conditions::attach_historic_requirement(spec, tp);
    +    Conditions::attach_historic_requirement(spec, tp);
         return spec;
     }
     
    @@ -204,54 +204,13 @@ exactly feasible, since the specification data field is 16 bits wide. return spec; }
    -

    §10.

    - -
    -#ifdef IF_MODULE
    -parse_node *Conditions::new_TEST_ACTION(action_pattern *ap, wording W) {
    -    if (ap == NULL) internal_error("null action pattern");
    -    parse_node *spec = Node::new_with_words(TEST_VALUE_NT, W);
    -    spec->down = Rvalues::from_action_pattern(ap);
    -    Node::set_text(spec->down, W);
    -    return spec;
    -}
    -#endif
    -#ifndef IF_MODULE
    -parse_node *Conditions::new_TEST_ACTION(void *ap, wording W) {
    -    internal_error("can't make test action without IF module");
    -    return NULL;
    -}
    -#endif
    -
    -int Conditions::is_TEST_ACTION(parse_node *spec) {
    -    #ifdef IF_MODULE
    -    if ((Node::is(spec, TEST_VALUE_NT)) &&
    -        ((Rvalues::to_action_pattern(spec->down)) ||
    -        (Rvalues::to_explicit_action(spec->down)))) return TRUE;
    -    #endif
    -    return FALSE;
    -}
    -
    -parse_node *Conditions::action_tested(parse_node *spec) {
    -    #ifdef IF_MODULE
    -    if (Conditions::is_TEST_ACTION(spec) == FALSE)
    -        internal_error("action improperly extracted");
    -    return spec->down;
    -    #endif
    -    #ifndef IF_MODULE
    -    internal_error("can't perform action_tested without IF module");
    -    return NULL;
    -    #endif
    -}
    -
    -
    • The function Conditions::new_TEST_ACTION is used in Type Expressions and Values (§22), Conditions and Phrases (§3, §7, §8.1).
    -

    §11. Since, in principle, any condition might also have a time period attached +

    §10. Since, in principle, any condition might also have a time period attached to it, we need a follow-up routine to attach this as necessary to a newly created condition:

    -parse_node *Conditions::attach_tense(parse_node *cond, int t) {
    +parse_node *Conditions::attach_tense(parse_node *cond, int t) {
         parse_node *spec = NULL;
         grammatical_usage *gu = Stock::new_usage(NULL, Task::language_of_syntax());
         Stock::add_form_to_usage(gu, Lcon::set_tense(Lcon::base(), t));
    @@ -265,13 +224,13 @@ created condition:
         return spec;
     }
     
    -parse_node *Conditions::attach_historic_requirement(parse_node *cond, time_period *tp) {
    +parse_node *Conditions::attach_historic_requirement(parse_node *cond, time_period *tp) {
         if (Node::is(cond, AMBIGUITY_NT)) {
             parse_node *amb = NULL;
             for (cond = cond->down; cond; cond = cond->next_alternative) {
                 parse_node *reading = Node::duplicate(cond);
                 reading->next_alternative = NULL;
    -            reading = Conditions::attach_historic_requirement(reading, tp);
    +            reading = Conditions::attach_historic_requirement(reading, tp);
                 if (Node::is(reading, UNKNOWN_NT) == FALSE)
                     amb = SyntaxTree::add_reading(amb,
                         reading, Node::get_text(cond));
    @@ -289,10 +248,10 @@ created condition:
         return spec;
     }
     
    -

    §12. Pretty-printing.

    +

    §11. Pretty-printing.

    -void Conditions::write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
    +void Conditions::write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
         if (Specifications::is_description(spec)) {
             Descriptions::write_out_in_English(OUT, spec);
         } else if ((Node::is(spec, TEST_VALUE_NT)) && (Node::is(spec->down, CONSTANT_NT))) {
    @@ -306,7 +265,7 @@ created condition:
         }
     }
     
    -

    §13. Specificity. We will need a way of determining which of two conditions is more complex, +

    §12. Specificity. We will need a way of determining which of two conditions is more complex, so that action-based rules with "when..." clauses tacked on can be sorted: the following is used to compare such "when..." conditions.

    @@ -318,33 +277,33 @@ beat shorter ones.
     int Conditions::compare_specificity_of_CONDITIONs(parse_node *spec1, parse_node *spec2) {
         if ((spec1 == NULL) && (spec2 == NULL)) return 0;
    -    int count1 = Conditions::count(spec1);
    -    int count2 = Conditions::count(spec2);
    +    int count1 = Conditions::count(spec1);
    +    int count2 = Conditions::count(spec2);
         if (count1 > count2) return 1;
         if (count1 < count2) return -1;
         return 0;
     }
     
    -

    §14. The only justification for the following complexity score is that it does +

    §13. The only justification for the following complexity score is that it does seem to accord well with what people expect. (There's clearly no theoretically perfect way to define complexity of conditions in a language as complex as Inform; this bit of scruffy, rather than neat, logic will have to do.)

    -int Conditions::count(parse_node *spec) {
    +int Conditions::count(parse_node *spec) {
         if (spec == NULL) return 0;
         if (Specifications::is_condition(spec) == FALSE) return 1;
         switch (Node::get_type(spec)) {
             case LOGICAL_AND_NT:
    -            return Conditions::count(spec->down)
    -                + Conditions::count(spec->down->next);
    +            return Conditions::count(spec->down)
    +                + Conditions::count(spec->down->next);
             case LOGICAL_OR_NT:
                 return -1;
             case LOGICAL_NOT_NT:
    -            return Conditions::count(spec->down);
    +            return Conditions::count(spec->down);
             case LOGICAL_TENSE_NT:
    -            return Conditions::count(spec->down);
    +            return Conditions::count(spec->down);
             case TEST_PROPOSITION_NT:
                 return Propositions::length(Specifications::to_proposition(spec));
             case TEST_PHRASE_OPTION_NT:
    @@ -354,7 +313,7 @@ Inform; this bit of scruffy, rather than neat, logic will have to do.)
         return 0;
     }
     
    -

    §15. Compiling. We clear two oddball cases out of the way, and then for the most part we +

    §14. Compiling. We clear two oddball cases out of the way, and then for the most part we delegate to potent routines elsewhere. Note that in some situations a valid I6 condition must be enclosed in round brackets, and that a redundant pair of brackets never does any harm; so we always compile one. @@ -370,13 +329,18 @@ of brackets never does any harm; so we always compile one. case LOGICAL_TENSE_NT: Chronology::compile_past_tense_condition(VH, spec_found); break; - case LOGICAL_NOT_NT: Compile a logical negation15.1; break; - case LOGICAL_AND_NT: case LOGICAL_OR_NT: Compile a logical operator15.2; break; + case LOGICAL_NOT_NT: Compile a logical negation14.1; break; + case LOGICAL_AND_NT: case LOGICAL_OR_NT: Compile a logical operator14.2; break; case TEST_VALUE_NT: { - if (Conditions::is_TEST_ACTION(spec_found)) { + if (AConditions::is_action_TEST_VALUE(spec_found)) { #ifdef IF_MODULE - action_pattern *ap = Rvalues::to_action_pattern( - Conditions::action_tested(spec_found)); + action_pattern *ap = ARvalues::to_action_pattern( + AConditions::action_tested(spec_found)); + if (ap == NULL) { + explicit_action *ea = Node::get_constant_explicit_action(AConditions::action_tested(spec_found)); + if (ea) ap = ea->as_described; + } + if (ap == NULL) internal_error("no action pattern to test"); RTActionPatterns::compile_pattern_match(VH, *ap, FALSE); #endif } else if (Specifications::is_description(spec_found)) { @@ -387,14 +351,14 @@ of brackets never does any harm; so we always compile one. } break; } - case TEST_PHRASE_OPTION_NT: Compile a phrase option test15.3; break; + case TEST_PHRASE_OPTION_NT: Compile a phrase option test14.3; break; } } -

    §15.1. An easy case, running straight out to I6 operators: +

    §14.1. An easy case, running straight out to I6 operators:

    -

    Compile a logical negation15.1 = +

    Compile a logical negation14.1 =

    @@ -405,11 +369,11 @@ of brackets never does any harm; so we always compile one.
             Specifications::Compiler::emit_as_val(K_value, spec_found->down);
         Produce::up(Emit::tree());
     
    -
    • This code is used in §15.
    -

    §15.2. An easy case, running straight out to I6 operators: +

    • This code is used in §14.
    +

    §14.2. An easy case, running straight out to I6 operators:

    -

    Compile a logical operator15.2 = +

    Compile a logical operator14.2 =

    @@ -427,15 +391,15 @@ of brackets never does any harm; so we always compile one.
             Specifications::Compiler::emit_as_val(K_value, right_operand);
         Produce::up(Emit::tree());
     
    -
    • This code is used in §15.
    -

    §15.3. Phrase options are stored as bits in a 16-bit map, so that each individual +

    • This code is used in §14.
    +

    §14.3. Phrase options are stored as bits in a 16-bit map, so that each individual option is a power of two from \(2^0\) to \(2^15\). We test if this is valid by performing logical-and against the I6 local variable phrase_options, which exists if and only if the enclosing I6 routine takes phrase options. The type-checker won't allow these specifications to be compiled anywhere else.

    -

    Compile a phrase option test15.3 = +

    Compile a phrase option test14.3 =

    @@ -449,7 +413,7 @@ type-checker won't allow these specifications to be compiled anywhere else.
                 (inter_ti) Annotations::read_int(spec_found, phrase_option_ANNOT));
         Produce::up(Emit::tree());
     
    -
    • This code is used in §15.
    +
    • This code is used in §14.
    diff --git a/docs/values-module/2-dsc.html b/docs/values-module/2-dsc.html index 5483c3436..99b68e620 100644 --- a/docs/values-module/2-dsc.html +++ b/docs/values-module/2-dsc.html @@ -399,7 +399,7 @@ a list. It's sometimes convenient to loop through this list:

    §11. Pretty-printing.

    -void Descriptions::write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
    +void Descriptions::write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
         kind *K = Specifications::to_kind(spec);
         WRITE("a description");
         if (K) {
    diff --git a/docs/values-module/2-dsh.html b/docs/values-module/2-dsh.html
    index cb30f059f..0e2a99ab3 100644
    --- a/docs/values-module/2-dsh.html
    +++ b/docs/values-module/2-dsh.html
    @@ -3671,17 +3671,15 @@ action value, which is a specific action.
     
     
         LOG_DASH("(5.d.1)");
    -        LOGIF(MATCHING, "Kind expected %u; ista %d cond %d\n", kind_expected, Conditions::is_TEST_ACTION(p), condition_context);
    -    if ((Conditions::is_TEST_ACTION(p)) && (kind_expected) &&
    +    if ((AConditions::is_action_TEST_VALUE(p)) && (kind_expected) &&
             (Kinds::compatible(K_stored_action, kind_expected))) {
    -LOGIF(MATCHING, "Madeit\n");
             explicit_action *ea = Node::get_constant_explicit_action(p->down);
             if (ea == NULL) {
                 action_pattern *ap = Node::get_constant_action_pattern(p->down);
                 int failure_code = 0;
    -            ea = ActionPatterns::to_explicit_action(ap, &failure_code);
    +            ea = ExplicitActions::from_action_pattern(ap, &failure_code);
     
    -            if (failure_code == 1) {
    +            if (failure_code == UNDERSPECIFIC_EA_FAILURE) {
                     THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
                     Problems::quote_source(1, current_sentence);
                     Problems::quote_wording(2, Node::get_text(p));
    @@ -3694,7 +3692,7 @@ action value, which is a specific action.
                     Problems::issue_problem_end();
                     return NEVER_MATCH;
                 }
    -            if (failure_code == 2) {
    +            if (failure_code == OVERSPECIFIC_EA_FAILURE) {
                     THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
                     Problems::quote_source(1, current_sentence);
                     Problems::quote_wording(2, Node::get_text(p));
    @@ -4206,7 +4204,7 @@ into treating it as such.
         ap_validation_suspended = state;
     }
     
    -int Dash::validate_parameter(parse_node *spec, kind *K) {
    +int Dash::validate_parameter(parse_node *spec, kind *K) {
         parse_node *vts;
         kind *kind_found = NULL;
         if (spec == NULL) return TRUE;
    @@ -4258,7 +4256,7 @@ into treating it as such.
     
     int verbose_checking_state = FALSE;
     
    -void Dash::tracing_phrases(wchar_t *text) {
    +void Dash::tracing_phrases(wchar_t *text) {
         if ((text) && (text[0])) {
             TEMPORARY_TEXT(LT)
             WRITE_TO(LT, "%w", text);
    @@ -4286,7 +4284,7 @@ at run time.
     

    -int Dash::compatible_with_description(parse_node *from_spec, parse_node *to_spec) {
    +int Dash::compatible_with_description(parse_node *from_spec, parse_node *to_spec) {
         LOGIF(KIND_CHECKING, "[Can we match from: $P to: $P?]\n", from_spec, to_spec);
     
         kind *from = Specifications::to_kind(from_spec);
    diff --git a/docs/values-module/2-rvl.html b/docs/values-module/2-rvl.html
    index de35bea74..ec7273d66 100644
    --- a/docs/values-module/2-rvl.html
    +++ b/docs/values-module/2-rvl.html
    @@ -102,36 +102,13 @@ pointers:
         return spec;
     
    -#ifdef IF_MODULE
    -parse_node *Rvalues::from_action_name(action_name *val) {
    -        CONV_FROM(action_name, K_action_name) }
    -parse_node *Rvalues::from_action_pattern(action_pattern *val) {
    -    int failure_code = 0;
    -    explicit_action *ea = ActionPatterns::to_explicit_action(val, &failure_code);
    -    if (ea) {
    -        parse_node *spec = Node::new(CONSTANT_NT);
    -        Node::set_kind_of_value(spec, K_stored_action);
    -        Node::set_constant_action_pattern(spec, val);
    -        Node::set_constant_explicit_action(spec, ea);
    -        return spec;
    -    } else {
    -        CONV_FROM(action_pattern, K_description_of_action);
    -    }
    -}
    -parse_node *Rvalues::from_grammar_verb(grammar_verb *val) {
    -        CONV_FROM(grammar_verb, K_understanding) }
    -parse_node *Rvalues::from_named_action_pattern(named_action_pattern *val) {
    -        CONV_FROM(named_action_pattern, K_nil) }
    -parse_node *Rvalues::from_scene(scene *val) {
    -        CONV_FROM(scene, K_scene) }
    -#endif
     parse_node *Rvalues::from_activity(activity *val) {
             CONV_FROM(activity, Activities::to_kind(val)) }
     parse_node *Rvalues::from_binary_predicate(binary_predicate *val) {
             CONV_FROM(binary_predicate, Kinds::base_construction(CON_relation)) }
     parse_node *Rvalues::from_constant_phrase(constant_phrase *val) {
             CONV_FROM(constant_phrase, Kinds::base_construction(CON_phrase)) }
    -parse_node *Rvalues::from_equation(equation *val) {
    +parse_node *Rvalues::from_equation(equation *val) {
             CONV_FROM(equation, K_equation) }
     parse_node *Rvalues::from_named_rulebook_outcome(named_rulebook_outcome *val) {
             CONV_FROM(named_rulebook_outcome, K_rulebook_outcome) }
    @@ -147,7 +124,7 @@ pointers:
             CONV_FROM(table_column, Tables::Columns::to_kind(val)) }
     parse_node *Rvalues::from_use_option(use_option *val) {
             CONV_FROM(use_option, K_use_option) }
    -parse_node *Rvalues::from_verb_form(verb_form *val) {
    +parse_node *Rvalues::from_verb_form(verb_form *val) {
             CONV_FROM(verb_form, K_verb) }
     

    §3. Contrariwise, here's how to get back again: @@ -159,43 +136,29 @@ pointers: return val;

    -#ifdef IF_MODULE
    -action_name *Rvalues::to_action_name(parse_node *spec) {
    -        CONV_TO(action_name) }
    -action_pattern *Rvalues::to_action_pattern(parse_node *spec) {
    -        CONV_TO(action_pattern) }
    -explicit_action *Rvalues::to_explicit_action(parse_node *spec) {
    -        CONV_TO(explicit_action) }
    -grammar_verb *Rvalues::to_grammar_verb(parse_node *spec) {
    -        CONV_TO(grammar_verb) }
    -named_action_pattern *Rvalues::to_named_action_pattern(parse_node *spec) {
    -        CONV_TO(named_action_pattern) }
    -scene *Rvalues::to_scene(parse_node *spec) {
    -        CONV_TO(scene) }
    -#endif
    -activity *Rvalues::to_activity(parse_node *spec) {
    +activity *Rvalues::to_activity(parse_node *spec) {
             CONV_TO(activity) }
    -binary_predicate *Rvalues::to_binary_predicate(parse_node *spec) {
    +binary_predicate *Rvalues::to_binary_predicate(parse_node *spec) {
             CONV_TO(binary_predicate) }
    -constant_phrase *Rvalues::to_constant_phrase(parse_node *spec) {
    +constant_phrase *Rvalues::to_constant_phrase(parse_node *spec) {
             CONV_TO(constant_phrase) }
    -equation *Rvalues::to_equation(parse_node *spec) {
    +equation *Rvalues::to_equation(parse_node *spec) {
             CONV_TO(equation) }
    -named_rulebook_outcome *Rvalues::to_named_rulebook_outcome(parse_node *spec) {
    +named_rulebook_outcome *Rvalues::to_named_rulebook_outcome(parse_node *spec) {
             CONV_TO(named_rulebook_outcome) }
    -property *Rvalues::to_property(parse_node *spec) {
    +property *Rvalues::to_property(parse_node *spec) {
             CONV_TO(property) }
    -rule *Rvalues::to_rule(parse_node *spec) {
    +rule *Rvalues::to_rule(parse_node *spec) {
             CONV_TO(rule) }
    -rulebook *Rvalues::to_rulebook(parse_node *spec) {
    +rulebook *Rvalues::to_rulebook(parse_node *spec) {
             CONV_TO(rulebook) }
    -table *Rvalues::to_table(parse_node *spec) {
    +table *Rvalues::to_table(parse_node *spec) {
             CONV_TO(table) }
    -table_column *Rvalues::to_table_column(parse_node *spec) {
    +table_column *Rvalues::to_table_column(parse_node *spec) {
             CONV_TO(table_column) }
    -use_option *Rvalues::to_use_option(parse_node *spec) {
    +use_option *Rvalues::to_use_option(parse_node *spec) {
             CONV_TO(use_option) }
    -verb_form *Rvalues::to_verb_form(parse_node *spec) {
    +verb_form *Rvalues::to_verb_form(parse_node *spec) {
             CONV_TO(verb_form) }
     

    §4.

    @@ -207,7 +170,7 @@ objects.

    -parse_node *Rvalues::from_instance(instance *I) {
    +parse_node *Rvalues::from_instance(instance *I) {
         parse_node *val = Node::new(CONSTANT_NT);
         Node::set_kind_of_value(val, Instances::to_kind(I));
         Node::set_constant_instance(val, I);
    @@ -216,21 +179,21 @@ objects.
         return val;
     }
     
    -instance *Rvalues::to_instance(parse_node *spec) {
    +instance *Rvalues::to_instance(parse_node *spec) {
             CONV_TO(instance) }
     

    §6. An instance of a subkind of K_object is called an "object":

    -int Rvalues::is_object(parse_node *spec) {
    +int Rvalues::is_object(parse_node *spec) {
         if ((Node::is(spec, CONSTANT_NT)) &&
             (Kinds::Behaviour::is_object(Node::get_kind_of_value(spec))))
             return TRUE;
         return FALSE;
     }
     
    -instance *Rvalues::to_object_instance(parse_node *spec) {
    +instance *Rvalues::to_object_instance(parse_node *spec) {
         if (Rvalues::is_object(spec)) return Rvalues::to_instance(spec);
         return NULL;
     }
    @@ -241,14 +204,14 @@ special annotations.
     

    -parse_node *Rvalues::new_self_object_constant(void) {
    +parse_node *Rvalues::new_self_object_constant(void) {
         parse_node *spec = Node::new(CONSTANT_NT);
         Node::set_kind_of_value(spec, K_object);
         Annotations::write_int(spec, self_object_ANNOT, TRUE);
         return spec;
     }
     
    -parse_node *Rvalues::new_nothing_object_constant(void) {
    +parse_node *Rvalues::new_nothing_object_constant(void) {
         parse_node *spec = Node::new(CONSTANT_NT);
         Node::set_kind_of_value(spec, K_object);
         Annotations::write_int(spec, nothing_object_ANNOT, TRUE);
    @@ -260,12 +223,12 @@ title from "The Big Bang Theory"),
     

    -int Rvalues::is_nothing_object_constant(parse_node *spec) {
    +int Rvalues::is_nothing_object_constant(parse_node *spec) {
         if (Annotations::read_int(spec, nothing_object_ANNOT)) return TRUE;
         return FALSE;
     }
     
    -int Rvalues::is_self_object_constant(parse_node *spec) {
    +int Rvalues::is_self_object_constant(parse_node *spec) {
         if (Annotations::read_int(spec, self_object_ANNOT)) return TRUE;
         return FALSE;
     }
    @@ -275,7 +238,7 @@ perhaps 24000, and the following turns that into an rvalue:
     

    -parse_node *Rvalues::from_encoded_notation(kind *K, int encoded_value, wording W) {
    +parse_node *Rvalues::from_encoded_notation(kind *K, int encoded_value, wording W) {
         parse_node *spec = Node::new_with_words(CONSTANT_NT, W);
         Node::set_kind_of_value(spec, K);
         Annotations::write_int(spec, explicit_literal_ANNOT, TRUE);
    @@ -283,7 +246,7 @@ perhaps 24000, and the following turns that into an rvalue:
         return spec;
     }
     
    -int Rvalues::to_encoded_notation(parse_node *spec) {
    +int Rvalues::to_encoded_notation(parse_node *spec) {
         if (Annotations::read_int(spec, explicit_literal_ANNOT))
             return Annotations::read_int(spec, constant_number_ANNOT);
         return 0;
    @@ -294,7 +257,7 @@ annotation, not a pointer one.
     

    -parse_node *Rvalues::from_int(int n, wording W) {
    +parse_node *Rvalues::from_int(int n, wording W) {
         parse_node *spec = Node::new_with_words(CONSTANT_NT, W);
         Node::set_kind_of_value(spec, K_number);
         Annotations::write_int(spec, explicit_literal_ANNOT, TRUE);
    @@ -302,7 +265,7 @@ annotation, not a pointer one.
         return spec;
     }
     
    -int Rvalues::to_int(parse_node *spec) {
    +int Rvalues::to_int(parse_node *spec) {
         if (spec == NULL) return 0;
         if (Annotations::read_int(spec, explicit_literal_ANNOT))
             return Annotations::read_int(spec, constant_number_ANNOT);
    @@ -315,7 +278,7 @@ of float to be
     

    -parse_node *Rvalues::from_IEEE_754(unsigned int n, wording W) {
    +parse_node *Rvalues::from_IEEE_754(unsigned int n, wording W) {
         parse_node *spec = Node::new_with_words(CONSTANT_NT, W);
         Node::set_kind_of_value(spec, K_real_number);
         Annotations::write_int(spec, explicit_literal_ANNOT, TRUE);
    @@ -333,7 +296,7 @@ of float to be
     

    -parse_node *Rvalues::from_boolean(int flag, wording W) {
    +parse_node *Rvalues::from_boolean(int flag, wording W) {
         parse_node *spec = Node::new_with_words(CONSTANT_NT, W);
         Node::set_kind_of_value(spec, K_truth_state);
         Annotations::write_int(spec, explicit_literal_ANNOT, TRUE);
    @@ -351,7 +314,7 @@ of float to be
     

    -parse_node *Rvalues::from_Unicode(int code_point, wording W) {
    +parse_node *Rvalues::from_Unicode(int code_point, wording W) {
         parse_node *spec = Node::new_with_words(CONSTANT_NT, W);
         Node::set_kind_of_value(spec, K_unicode_character);
         Annotations::write_int(spec, explicit_literal_ANNOT, TRUE);
    @@ -370,7 +333,7 @@ reduced modulo 1440, the number of minutes in a day.
     

    -parse_node *Rvalues::from_time(int minutes_since_midnight, wording W) {
    +parse_node *Rvalues::from_time(int minutes_since_midnight, wording W) {
         parse_node *spec = Node::new_with_words(CONSTANT_NT, W);
         Node::set_kind_of_value(spec, TimesOfDay::kind());
         Annotations::write_int(spec, explicit_literal_ANNOT, TRUE);
    @@ -389,7 +352,7 @@ together with their kinds:
     

    -parse_node *Rvalues::from_wording_of_list(kind *K, wording W) {
    +parse_node *Rvalues::from_wording_of_list(kind *K, wording W) {
         parse_node *spec = Node::new_with_words(CONSTANT_NT, W);
         Node::set_kind_of_value(spec, K);
         return spec;
    @@ -399,7 +362,7 @@ together with their kinds:
     

    -parse_node *Rvalues::from_wording(wording W) {
    +parse_node *Rvalues::from_wording(wording W) {
         parse_node *spec = Node::new_with_words(CONSTANT_NT, W);
         Node::set_kind_of_value(spec, K_text);
         return spec;
    @@ -433,7 +396,7 @@ an l-value.
     

    -parse_node *Rvalues::from_pair(parse_node *X, parse_node *Y) {
    +parse_node *Rvalues::from_pair(parse_node *X, parse_node *Y) {
         if (X == NULL) X = Specifications::new_UNKNOWN(EMPTY_WORDING);
         if (Y == NULL) Y = Specifications::new_UNKNOWN(EMPTY_WORDING);
         kind *kX = Specifications::to_true_kind_disambiguated(X);
    @@ -456,7 +419,7 @@ in the proposition.
     

    -parse_node *Rvalues::constant_description(pcalc_prop *prop, wording W) {
    +parse_node *Rvalues::constant_description(pcalc_prop *prop, wording W) {
         parse_node *con = Node::new_with_words(CONSTANT_NT, W);
         Node::set_kind_of_value(con,
             Kinds::unary_con(CON_description, K_object));
    @@ -464,7 +427,7 @@ in the proposition.
         return con;
     }
     
    -void Rvalues::set_constant_description_proposition(parse_node *spec, pcalc_prop *prop) {
    +void Rvalues::set_constant_description_proposition(parse_node *spec, pcalc_prop *prop) {
         if (Rvalues::is_CONSTANT_construction(spec, CON_description)) {
             Node::set_proposition(spec, prop);
             Node::set_kind_of_value(spec,
    @@ -476,14 +439,14 @@ in the proposition.
     

    §21. Testing.

    -int Rvalues::is_CONSTANT_construction(parse_node *spec, kind_constructor *con) {
    +int Rvalues::is_CONSTANT_construction(parse_node *spec, kind_constructor *con) {
         if ((Node::is(spec, CONSTANT_NT)) &&
             (Kinds::get_construct(Node::get_kind_of_value(spec)) == con))
             return TRUE;
         return FALSE;
     }
     
    -int Rvalues::is_CONSTANT_of_kind(parse_node *spec, kind *K) {
    +int Rvalues::is_CONSTANT_of_kind(parse_node *spec, kind *K) {
         if ((Node::is(spec, CONSTANT_NT)) &&
             (Kinds::eq(Node::get_kind_of_value(spec), K)))
             return TRUE;
    @@ -521,7 +484,7 @@ doesn't need to be especially rapid.
         KCOMPARE_CONSTANTS_USING(DATA, STRUCTURE, Rvalues::to_##STRUCTURE)
     
    -int Rvalues::compare_CONSTANT(parse_node *spec1, parse_node *spec2) {
    +int Rvalues::compare_CONSTANT(parse_node *spec1, parse_node *spec2) {
         if (Node::is(spec1, CONSTANT_NT) == FALSE) return FALSE;
         if (Node::is(spec2, CONSTANT_NT) == FALSE) return FALSE;
         kind *K1 = Node::get_kind_of_value(spec1);
    @@ -557,11 +520,9 @@ doesn't need to be especially rapid.
                 KCOMPARE_CONSTANTS(rulebook_outcome, named_rulebook_outcome)
                 KCOMPARE_CONSTANTS(table, table)
                 KCOMPARE_CONSTANTS(use_option, use_option)
    -            #ifdef IF_MODULE
    -            KCOMPARE_CONSTANTS(action_name, action_name)
    -            KCOMPARE_CONSTANTS(scene, scene)
    -            KCOMPARE_CONSTANTS(understanding, grammar_verb)
    -            #endif
    +            int rv = NOT_APPLICABLE;
    +            PluginCalls::compare_constant(spec1, spec2, &rv);
    +            if (rv != NOT_APPLICABLE) return rv;
             }
         }
         return FALSE;
    @@ -570,7 +531,7 @@ doesn't need to be especially rapid.
     

    §23. Pretty-printing.

    -void Rvalues::write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
    +void Rvalues::write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
         switch (Node::get_type(spec)) {
             case PHRASE_TO_DECIDE_VALUE_NT: {
                 kind *dtr = Specifications::to_kind(spec);
    @@ -604,7 +565,7 @@ result have?
     

    -kind *Rvalues::to_kind(parse_node *spec) {
    +kind *Rvalues::to_kind(parse_node *spec) {
         if (spec == NULL) internal_error("Rvalues::to_kind on NULL");
         switch (Node::get_type(spec)) {
             case CONSTANT_NT:
    diff --git a/docs/values-module/2-spc.html b/docs/values-module/2-spc.html
    index bdc74ee54..f903305d1 100644
    --- a/docs/values-module/2-spc.html
    +++ b/docs/values-module/2-spc.html
    @@ -104,7 +104,7 @@ for creating and using them.
         return Descriptions::from_kind(K, FALSE);
     }
     
    -kind *Specifications::to_kind(parse_node *spec) {
    +kind *Specifications::to_kind(parse_node *spec) {
         if (Node::is(spec, AMBIGUITY_NT)) spec = spec->down;
         if (Specifications::is_description(spec))
             return Descriptions::to_kind(spec);
    @@ -141,7 +141,7 @@ for creating and using them.
         return FALSE;
     }
     
    -int Specifications::is_condition(parse_node *spec) {
    +int Specifications::is_condition(parse_node *spec) {
         node_type_metadata *metadata = NodeType::get_metadata(Node::get_type(spec));
         if ((metadata) && (metadata->category == COND_NCAT)) return TRUE;
         return FALSE;
    @@ -179,7 +179,7 @@ but "12" is not.
         return g;
     }
     
    -int Specifications::is_description(parse_node *p) {
    +int Specifications::is_description(parse_node *p) {
         if ((Node::is(p, TEST_VALUE_NT)) &&
             (Rvalues::is_CONSTANT_construction(p->down, CON_description))) return TRUE;
         return FALSE;
    @@ -190,7 +190,7 @@ but "12" is not.
     
    define NP_TO_PROPOSITION Specifications::to_proposition
     
    -pcalc_prop *Specifications::to_proposition(parse_node *p) {
    +pcalc_prop *Specifications::to_proposition(parse_node *p) {
         if (p == NULL) return NULL;
         if (Specifications::is_description(p))
             return Descriptions::to_proposition(p);
    @@ -265,7 +265,7 @@ Index; those have to be English language forms.
         if (spec == NULL) WRITE("something unknown");
         else if (Lvalues::is_lvalue(spec)) Lvalues::write_out_in_English(OUT, spec);
         else if (Rvalues::is_rvalue(spec)) Rvalues::write_out_in_English(OUT, spec);
    -    else if (Specifications::is_condition(spec)) Conditions::write_out_in_English(OUT, spec);
    +    else if (Specifications::is_condition(spec)) Conditions::write_out_in_English(OUT, spec);
         else if (Node::is(spec, AMBIGUITY_NT)) Specifications::write_out_in_English(OUT, spec->down);
         else WRITE("something unrecognised");
     }
    diff --git a/docs/values-module/3-ll.html b/docs/values-module/3-ll.html
    index 8dc1741a0..481a63f83 100644
    --- a/docs/values-module/3-ll.html
    +++ b/docs/values-module/3-ll.html
    @@ -229,7 +229,7 @@ which happens to be a malformed list.
         for (lle = ll->first_llist_entry; lle; lle = lle->next_llist_entry) {
             parse_node *spec = lle->llist_entry_value;
             if (!Node::is(spec, UNKNOWN_NT)) {
    -            if (Conditions::is_TEST_ACTION(spec))
    +            if (AConditions::is_action_TEST_VALUE(spec))
                     Dash::check_value_silently(spec, K_stored_action);
                 else
                     Dash::check_value_silently(spec, NULL);
    diff --git a/docs/values-module/4-cap.html b/docs/values-module/4-cap.html
    index 87189fc75..0bdebef9c 100644
    --- a/docs/values-module/4-cap.html
    +++ b/docs/values-module/4-cap.html
    @@ -135,10 +135,10 @@ following implements this as a hand-coded nonterminal instead.
                 parse_node *atomic_cnd = <<rp>>;
                 parse_node *spec = atomic_cnd;
                 if (Node::is(spec, CONSTANT_NT)) {
    -                action_pattern *ap = Rvalues::to_action_pattern(spec);
    -                spec = Conditions::new_TEST_ACTION(ap, W);
    +                action_pattern *ap = ARvalues::to_action_pattern(spec);
    +                spec = AConditions::new_action_TEST_VALUE(ap, W);
                 }
    -            ==> { -, Conditions::attach_historic_requirement(spec, tp) };
    +            ==> { -, Conditions::attach_historic_requirement(spec, tp) };
                 return TRUE;
             }
         }
    @@ -272,10 +272,10 @@ conditions, so this is where the condition in
     
     
     <s-action-pattern-as-condition> ::=
    -    <we-are-action-pattern>         ==> { -, Conditions::new_TEST_ACTION(RP[1], W) }
    +    <we-are-action-pattern>         ==> { -, AConditions::new_action_TEST_VALUE(RP[1], W) }
     
     <s-action-pattern-as-negated-condition> ::=
    -    <action-pattern-negated>        ==> { -, Conditions::new_TEST_ACTION(RP[1], W) }
    +    <action-pattern-negated>        ==> { -, AConditions::new_action_TEST_VALUE(RP[1], W) }
     

    §8. And similarly: @@ -303,8 +303,8 @@ conditions, so this is where the condition in "too much information about past events."); return FALSE; } - parse_node *C = Conditions::new_TEST_ACTION(ap, W); - C = Conditions::attach_tense(C, HASBEEN_TENSE); + parse_node *C = AConditions::new_action_TEST_VALUE(ap, W); + C = Conditions::attach_tense(C, HASBEEN_TENSE); ==> { -, C }; #endif #ifndef IF_MODULE diff --git a/docs/values-module/4-ets.html b/docs/values-module/4-ets.html index f0959e901..75657c7eb 100644 --- a/docs/values-module/4-ets.html +++ b/docs/values-module/4-ets.html @@ -257,7 +257,7 @@ back into the original tree but throw away the S-node head. if (Rvalues::is_CONSTANT_of_kind(S, K_stored_action)) { ==> { -, S }; return TRUE; - } else if (Conditions::is_TEST_ACTION(S)) { + } else if (AConditions::is_action_TEST_VALUE(S)) { ==> { -, S->down }; return TRUE; } else { @@ -282,7 +282,7 @@ back into the original tree but throw away the S-node head. if (Rvalues::is_CONSTANT_of_kind(S, K_stored_action)) { ==> { -, S }; return TRUE; - } else if (Conditions::is_TEST_ACTION(S)) { + } else if (AConditions::is_action_TEST_VALUE(S)) { ==> { -, S->down }; return TRUE; } else { diff --git a/docs/values-module/4-teav.html b/docs/values-module/4-teav.html index 0e41d1967..02c8519d5 100644 --- a/docs/values-module/4-teav.html +++ b/docs/values-module/4-teav.html @@ -672,36 +672,6 @@ Again, this is part of a condition, and can't evaluate. return Node::duplicate(val); }

    -

    §22. Action patterns, such as "taking a container" or "opening a closed door", -are parsed by code in the chapter on Actions; all we do here is to wrap the -result. -

    - -
    -<s-action-pattern-as-value> internal {
    -    #ifdef IF_MODULE
    -    if (Wordings::mismatched_brackets(W)) { ==> { fail nonterminal }; }
    -    if (Lexer::word(Wordings::first_wn(W)) == OPENBRACE_V) { ==> { fail nonterminal }; }
    -    int pto = permit_trying_omission;
    -    if (<definite-article>(Wordings::first_word(W)) == FALSE) permit_trying_omission = TRUE;
    -    int r = <action-pattern>(W);
    -    permit_trying_omission = pto;
    -    if (r) {
    -        action_pattern *ap = <<rp>>;
    -        if ((APClauses::get_val(ap, ACTOR_AP_CLAUSE)) &&
    -            (Dash::validate_parameter(APClauses::get_val(ap, ACTOR_AP_CLAUSE), K_person) == FALSE)) {
    -            r = <action-pattern>(W);
    -        }
    -    }
    -    if (r) {
    -        ==> { -, Conditions::new_TEST_ACTION(<<rp>>, W) };
    -        return TRUE;
    -    }
    -    #endif
    -    ==> { fail nonterminal };
    -}
    -
    - diff --git a/docs/values-module/4-varc.html b/docs/values-module/4-varc.html index 8ffa2e7b7..cef3e868a 100644 --- a/docs/values-module/4-varc.html +++ b/docs/values-module/4-varc.html @@ -511,7 +511,7 @@ using a tense other than the present, and all is well. if (VerbUsages::get_tense_used(vu) != IS_TENSE) { if (Binding::detect_locals(Specifications::to_proposition(spec), NULL) > 0) Issue a problem for referring to temporary values at a time when they did not exist11.3.1; - spec = Conditions::attach_tense(spec, VerbUsages::get_tense_used(vu)); + spec = Conditions::attach_tense(spec, VerbUsages::get_tense_used(vu)); } if (explicit_negation) spec = Conditions::negate(spec); diff --git a/inform7/Downloads/preform-diagnostics.txt b/inform7/Downloads/preform-diagnostics.txt index a4d94e26c..565f4a87b 100644 --- a/inform7/Downloads/preform-diagnostics.txt +++ b/inform7/Downloads/preform-diagnostics.txt @@ -7550,21 +7550,19 @@ of in (hits 2/579) (matched long text) constraint DS = {26} extremes [5, infinity) - internal hits 3/19876 nti 10 constraint (none) extremes [1, infinity) - - hits 1074/2238 nti 11 constraint (none) extremes [3, infinity) + hits 1074/2238 nti 10 constraint (none) extremes [3, infinity) English: (hits 0/737) constraint DS = {19} extremes [3, infinity) (hits 1074/1108) (matched long text) constraint (none) extremes [3, infinity) - hits 11/22 nti 12 constraint FS = {7} extremes [2, infinity) + hits 11/22 nti 11 constraint FS = {7} extremes [2, infinity) English: (hits 11/11) (matched long text) constraint FS = {7} extremes [2, infinity) - hits 2149/6658 nti 13 constraint (none) extremes [2, infinity) + hits 2149/6658 nti 12 constraint (none) extremes [2, infinity) English: (hits 0/660) constraint DS = {29} & FS = {9} extremes [4, infinity) @@ -7578,7 +7576,7 @@ to constraint DS = {29} extremes [3, infinity) - hits 260/9966 nti 14 constraint (none) extremes [3, infinity) + hits 260/9966 nti 13 constraint (none) extremes [3, infinity) English: (hits 169/4515) (matched long text) constraint DS = {13} extremes [3, infinity) @@ -7592,7 +7590,7 @@ not (hits 1/6077) (matched: 'not carried by the person asked') constraint DS = {13, 28} extremes [3, infinity) - hits 183/23360 nti 15 constraint DS = {30} extremes [3, infinity) + hits 183/23360 nti 14 constraint DS = {30} extremes [3, infinity) English: (hits 0/2196) constraint DS = {29, 30} extremes [5, infinity) @@ -7601,11 +7599,11 @@ (hits 151/5594) (matched: 'which provide the property initial appearance') constraint DS = {30} extremes [3, infinity) - internal hits 791/18290 nti 16 constraint (none) extremes [1, infinity) + internal hits 791/18290 nti 15 constraint (none) extremes [1, infinity) - internal hits 1208/34552 nti 17 constraint (none) extremes [0, 0] + internal hits 1208/34552 nti 16 constraint (none) extremes [0, 0] - hits 4662/9648 nti 18 constraint (none) extremes [1, infinity) + hits 4662/9648 nti 17 constraint (none) extremes [1, infinity) English: (hits 30/4824) (matched: 'the person asked') constraint (none) extremes [1, infinity) @@ -7614,7 +7612,7 @@ ^ (hits 4602/4764) (matched long text) constraint (none) extremes [1, infinity) - hits 797/2188 nti 19 constraint (none) extremes [1, infinity) + hits 797/2188 nti 18 constraint (none) extremes [1, infinity) English: (hits 143/1094) (matched: 'the second noun') constraint (none) extremes [1, infinity) @@ -7634,7 +7632,7 @@ (hits 2/248) (matched: 'switched off') constraint (none) extremes [1, infinity) - hits 1071/2634 nti 20 constraint (none) extremes [0, infinity) + hits 1071/2634 nti 19 constraint (none) extremes [0, infinity) English: (hits 1069/1317) (matched long text) constraint (none) extremes [0, infinity) @@ -7658,7 +7656,7 @@ (hits 1197/1457) (matched long text) constraint (none) extremes [0, infinity) - internal hits 0/2914 nti 21 constraint (none) extremes [1, infinity) + internal hits 0/2914 nti 20 constraint (none) extremes [1, infinity) hits 1197/2914 nti 16 constraint (none) extremes [0, infinity) English: @@ -7704,26 +7702,26 @@ is/are {...} (hits 22/802) (matched long text) constraint DS = {9, 19} extremes [3, infinity) - internal hits 94/2912 nti 22 constraint (none) extremes [1, infinity) + internal hits 94/2912 nti 21 constraint (none) extremes [1, infinity) - internal hits 1/2914 nti 23 constraint (none) extremes [1, infinity) + internal hits 1/2914 nti 22 constraint (none) extremes [1, infinity) - hits 28/2746 nti 24 constraint (none) extremes [1, infinity) + hits 28/2746 nti 23 constraint (none) extremes [1, infinity) English: (hits 28/1373) (matched long text) constraint (none) extremes [1, infinity) - hits 0/2208 nti 25 constraint DS = {14} extremes [2, infinity) + hits 0/2208 nti 24 constraint DS = {14} extremes [2, infinity) English: (hits 0/1104) constraint DS = {14} extremes [2, infinity) - hits 0/2182 nti 26 constraint DS = {11} extremes [3, infinity) + hits 0/2182 nti 25 constraint DS = {11} extremes [3, infinity) English: (hits 0/1091) constraint DS = {11} extremes [3, infinity) - hits 0/1890 nti 27 constraint DS = {12} extremes [4, infinity) + hits 0/1890 nti 26 constraint DS = {12} extremes [4, infinity) English: (hits 0/945) constraint DS = {12} extremes [4, infinity) @@ -7761,28 +7759,28 @@ (hits 0/2342) constraint (none) extremes [1, infinity) - internal hits 0/4684 nti 28 constraint (none) extremes [1, infinity) + internal hits 0/4684 nti 27 constraint (none) extremes [1, infinity) - internal hits 1374/2748 nti 29 constraint (none) extremes [1, infinity) + internal hits 1374/2748 nti 28 constraint (none) extremes [1, infinity) - internal hits 2388/4776 nti 30 constraint (none) extremes [1, infinity) + internal hits 2388/4776 nti 29 constraint (none) extremes [1, infinity) internal hits 1102/4644 nti r4 constraint CW = {r2, r4} extremes [1, infinity) - internal hits 4/252 nti 31 constraint (none) extremes [1, infinity) + internal hits 4/252 nti 30 constraint (none) extremes [1, infinity) - nti 6 constraint (none) extremes [0, 0] + nti 31 constraint (none) extremes [0, 0] English: constraint (none) extremes [0, 0] constraint (none) extremes [0, 0] - internal hits 0/172 nti 7 constraint (none) extremes [1, infinity) + internal hits 0/172 nti 6 constraint (none) extremes [1, infinity) - internal hits 4/252 nti 8 constraint (none) extremes [1, infinity) + internal hits 4/252 nti 7 constraint (none) extremes [1, infinity) - nti 9 constraint (none) extremes [1, infinity) + nti 8 constraint (none) extremes [1, infinity) English: constraint (none) extremes [1, infinity) @@ -7805,27 +7803,27 @@ property {...} (hits 34/176) (matched: 'property initial appearance') constraint DS = {20} extremes [2, infinity) - internal hits 69/430 nti 10 constraint (none) extremes [1, infinity) + internal hits 69/430 nti 9 constraint (none) extremes [1, infinity) - internal hits 0/44 nti 11 constraint (none) extremes [1, infinity) + internal hits 0/44 nti 10 constraint (none) extremes [1, infinity) - internal hits 127/2212 nti 12 constraint (none) extremes [1, infinity) + internal hits 127/2212 nti 11 constraint (none) extremes [1, infinity) - internal hits 104/392 nti 13 constraint (none) extremes [1, infinity) + internal hits 104/392 nti 12 constraint (none) extremes [1, infinity) hits 0/292 nti 22 constraint DS = {22} extremes [1, infinity) English: {***} of {***} (hits 0/1) constraint DS = {22} extremes [1, infinity) - internal nti 14 constraint (none) extremes [1, infinity) + internal nti 13 constraint (none) extremes [1, infinity) nti 23 constraint DS = {23} extremes [4, infinity) English: the same {...} as constraint DS = {23} extremes [4, infinity) - hits 22/44 nti 15 constraint (none) extremes [1, infinity) + hits 22/44 nti 14 constraint (none) extremes [1, infinity) English: (hits 0/22) constraint (none) extremes [1, infinity) @@ -7880,9 +7878,9 @@ female (hits 1/1) (matched: 'female') constraint CS = {27} extremes [1, 1] - internal hits 82/164 nti 16 constraint (none) extremes [1, infinity) + internal hits 82/164 nti 15 constraint (none) extremes [1, infinity) - internal hits 123/246 nti 17 constraint (none) extremes [1, infinity) + internal hits 123/246 nti 16 constraint (none) extremes [1, infinity) hits 431/862 nti 28 constraint (none) extremes [1, infinity) English: @@ -7906,16 +7904,16 @@ {...} rulebook constraint DS = {29} extremes [2, infinity) - hits 7/14 nti 18 constraint (none) extremes [1, infinity) + hits 7/14 nti 17 constraint (none) extremes [1, infinity) English: (hits 0/7) constraint (none) extremes [1, infinity) {...} (hits 7/7) (matched: 'specific carry out rulebook') constraint (none) extremes [1, infinity) - internal hits 371/790 nti 19 constraint (none) extremes [1, infinity) + internal hits 371/790 nti 18 constraint (none) extremes [1, infinity) - hits 395/790 nti 20 constraint (none) extremes [1, infinity) + hits 395/790 nti 19 constraint (none) extremes [1, infinity) English: (hits 19/395) (matched: 'a first turn sequence rule') constraint (none) extremes [2, infinity) @@ -7959,7 +7957,7 @@ {...} constraint (none) extremes [1, infinity) - nti 21 constraint (none) extremes [1, infinity) + nti 20 constraint (none) extremes [1, infinity) English: constraint CS = {6} extremes [1, 2] @@ -7975,7 +7973,7 @@ no outcome constraint CS = {6} extremes [2, 2] - hits 27/54 nti 22 constraint (none) extremes [1, infinity) + hits 27/54 nti 21 constraint (none) extremes [1, infinity) English: {...} (hits 10/27) (matched long text) constraint (none) extremes [1, infinity) @@ -7991,7 +7989,7 @@ _,/and/or (hits 20/77) (matched long text) constraint DS = {8} extremes [2, infinity) - hits 27/54 nti 23 constraint (none) extremes [1, infinity) + hits 27/54 nti 22 constraint (none) extremes [1, infinity) English: (hits 27/27) (matched: 'there is sufficient light ( failure )') constraint (none) extremes [1, infinity) @@ -8022,7 +8020,7 @@ it is very unlikely (hits 1/1) (matched: 'it is very unlikely') constraint CS = {10} extremes [4, 4] - internal hits 8/1226 nti 24 constraint (none) extremes [1, infinity) + internal hits 8/1226 nti 23 constraint (none) extremes [1, infinity) hits 35/70 nti 14 constraint (none) extremes [1, infinity) English: @@ -8056,7 +8054,7 @@ {...} activity constraint DS = {15} extremes [2, infinity) - nti 25 constraint (none) extremes [1, infinity) + nti 24 constraint (none) extremes [1, infinity) English: constraint (none) extremes [1, infinity) @@ -8070,7 +8068,7 @@ (hits 40/40) (matched: 'dropping or throwing or inserting or putting') constraint (none) extremes [1, infinity) - hits 41/82 nti 26 constraint (none) extremes [1, infinity) + hits 41/82 nti 25 constraint (none) extremes [1, infinity) English: {...} (hits 14/41) (matched: 'throwing or inserting or putting') constraint (none) extremes [1, infinity) @@ -8108,9 +8106,9 @@ (hits 3/15) (matched: 'smelling') constraint (none) extremes [1, infinity) - internal hits 1/88 nti 27 constraint (none) extremes [1, infinity) + internal hits 1/88 nti 26 constraint (none) extremes [1, infinity) - internal hits 80/160 nti 28 constraint (none) extremes [0, 0] + internal hits 80/160 nti 27 constraint (none) extremes [0, 0] hits 438/876 nti 20 constraint (none) extremes [1, infinity) English: @@ -8269,7 +8267,7 @@ constraint (none) extremes [1, infinity) - nti 29 constraint (none) extremes [1, infinity) + nti 28 constraint (none) extremes [1, infinity) English: constraint DS = {8} extremes [3, infinity) @@ -8283,7 +8281,7 @@ _,/or constraint DS = {8} extremes [2, infinity) - nti 30 constraint (none) extremes [1, infinity) + nti 29 constraint (none) extremes [1, infinity) English: {......} constraint (none) extremes [1, infinity) @@ -8365,7 +8363,7 @@ to {...} (hits 302/302) (matched long text) constraint DS = {14} extremes [2, infinity) - hits 160/320 nti 31 constraint (none) extremes [1, infinity) + hits 160/320 nti 30 constraint (none) extremes [1, infinity) English: (hits 160/160) (matched: 'relation of objects') constraint (none) extremes [1, infinity) @@ -8438,9 +8436,9 @@ {......} (hits 0/5) constraint (none) extremes [1, infinity) - internal hits 24/68 nti 6 constraint (none) extremes [1, infinity) + internal hits 24/68 nti 31 constraint (none) extremes [1, infinity) - hits 65/130 nti 7 constraint (none) extremes [1, infinity) + hits 65/130 nti 6 constraint (none) extremes [1, infinity) English: {...} (hits 20/65) (matched long text) constraint (none) extremes [1, infinity) @@ -8460,14 +8458,14 @@ and/or (hits 0/37) constraint DS = {17} extremes [2, infinity) - hits 65/130 nti 8 constraint (none) extremes [1, infinity) + hits 65/130 nti 7 constraint (none) extremes [1, infinity) English: {...} (hits 20/65) (matched: 'without printing a room description') constraint (none) extremes [1, infinity) {...} (hits 45/45) (matched: 'without printing a room description') constraint (none) extremes [1, infinity) - hits 102/204 nti 9 constraint (none) extremes [1, infinity) + hits 102/204 nti 8 constraint (none) extremes [1, infinity) English: {...} (hits 43/102) (matched long text) constraint (none) extremes [1, infinity) @@ -8483,14 +8481,14 @@ _,/and (hits 86/160) (matched long text) constraint DS = {18} extremes [2, infinity) - hits 102/204 nti 10 constraint (none) extremes [1, infinity) + hits 102/204 nti 9 constraint (none) extremes [1, infinity) English: (hits 102/102) (matched: 'giving brief inventory information') constraint (none) extremes [1, infinity) {...} constraint (none) extremes [1, infinity) - internal hits 102/3322 nti 11 constraint (none) extremes [1, infinity) + internal hits 102/3322 nti 10 constraint (none) extremes [1, infinity) nti 20 constraint (none) extremes [1, infinity) English: @@ -8510,7 +8508,7 @@ {...} constraint (none) extremes [1, infinity) - hits 209/418 nti 12 constraint (none) extremes [1, infinity) + hits 209/418 nti 11 constraint (none) extremes [1, infinity) English: (hits 14/74) (matched: 'the current working sack') constraint (none) extremes [2, infinity) @@ -8528,7 +8526,7 @@ {...} (hits 73/73) (matched: 'item being printed') constraint (none) extremes [1, infinity) - internal hits 136/418 nti 13 constraint (none) extremes [1, infinity) + internal hits 136/418 nti 12 constraint (none) extremes [1, infinity) nti 22 constraint DS = {22} extremes [2, infinity) English: @@ -8546,7 +8544,7 @@ {...} constraint (none) extremes [1, infinity) - internal hits 1559/3118 nti 14 constraint (none) extremes [1, infinity) + internal hits 1559/3118 nti 13 constraint (none) extremes [1, infinity) hits 44/1880 nti 24 constraint CS = {24} extremes [1, 1] English: @@ -8912,14 +8910,14 @@ entire game (hits 1/1) (matched: 'entire game') constraint CS = {8} extremes [2, 2] - hits 4/8 nti 15 constraint (none) extremes [1, infinity) + hits 4/8 nti 14 constraint (none) extremes [1, infinity) English: (hits 4/4) (matched: 'the entire game') constraint (none) extremes [1, infinity) {...} constraint (none) extremes [1, infinity) - nti 16 constraint (none) extremes [1, infinity) + nti 15 constraint (none) extremes [1, infinity) English: constraint (none) extremes [1, infinity) @@ -8943,23 +8941,23 @@ (hits 0/2) constraint (none) extremes [1, infinity) - hits 4/8 nti 17 constraint (none) extremes [1, infinity) + hits 4/8 nti 16 constraint (none) extremes [1, infinity) English: (hits 4/4) (matched: 'the entire game') constraint (none) extremes [2, infinity) constraint (none) extremes [1, infinity) - hits 4/8 nti 18 constraint (none) extremes [1, infinity) + hits 4/8 nti 17 constraint (none) extremes [1, infinity) English: (hits 4/4) (matched: 'entire game') constraint (none) extremes [1, infinity) - internal nti 19 constraint (none) extremes [1, infinity) + internal nti 18 constraint (none) extremes [1, infinity) - internal nti 20 constraint (none) extremes [1, infinity) + internal nti 19 constraint (none) extremes [1, infinity) - nti 21 constraint (none) extremes [1, infinity) + nti 20 constraint (none) extremes [1, infinity) English: constraint (none) extremes [1, infinity) @@ -8981,7 +8979,7 @@ waiting (hits 1/20) (matched: 'waiting') constraint CS = {12} extremes [1, 1] - hits 90/1036 nti 22 constraint DS = {13} extremes [1, infinity) + hits 90/1036 nti 21 constraint DS = {13} extremes [1, infinity) English: (hits 90/357) (matched long text) constraint DS = {13} extremes [2, infinity) @@ -8995,7 +8993,7 @@ action (hits 0/3) constraint CS = {13} extremes [1, 1] - hits 90/182 nti 23 constraint (none) extremes [0, infinity) + hits 90/182 nti 22 constraint (none) extremes [0, infinity) English: ^ (hits 90/91) (matched long text) constraint (none) extremes [0, infinity) @@ -9007,21 +9005,21 @@ {***} variable (hits 0/90) constraint DS = {14} extremes [1, infinity) - hits 90/180 nti 24 constraint (none) extremes [1, infinity) + hits 90/180 nti 23 constraint (none) extremes [1, infinity) English: (hits 0/90) constraint (none) extremes [1, infinity) {...} (hits 90/90) (matched: 'switching the story transcript on') constraint (none) extremes [1, infinity) - hits 90/180 nti 25 constraint (none) extremes [1, infinity) + hits 90/180 nti 24 constraint (none) extremes [1, infinity) English: (hits 90/90) (matched long text) constraint (none) extremes [1, infinity) {...} constraint (none) extremes [1, infinity) - hits 128/256 nti 26 constraint (none) extremes [1, infinity) + hits 128/256 nti 25 constraint (none) extremes [1, infinity) English: {...} (hits 19/128) (matched: 'applying to nothing or one thing and') constraint (none) extremes [1, infinity) @@ -9077,12 +9075,12 @@ {...} constraint (none) extremes [1, infinity) - hits 70/140 nti 27 constraint (none) extremes [1, infinity) + hits 70/140 nti 26 constraint (none) extremes [1, infinity) English: (hits 70/70) (matched: 'visible thing') constraint (none) extremes [1, infinity) - hits 70/140 nti 28 constraint (none) extremes [1, infinity) + hits 70/140 nti 27 constraint (none) extremes [1, infinity) English: (hits 12/12) (matched: 'visible thing') constraint DS = {15} extremes [2, infinity) @@ -9107,7 +9105,7 @@ (hits 7/7) (matched: 'abbreviated form allowed') constraint (none) extremes [1, infinity) - hits 13/26 nti 29 constraint (none) extremes [1, infinity) + hits 13/26 nti 28 constraint (none) extremes [1, infinity) English: (hits 0/13) constraint (none) extremes [1, infinity) @@ -9128,7 +9126,7 @@ report {...} constraint DS = {21} extremes [2, infinity) - internal hits 227/664 nti 30 constraint (none) extremes [1, infinity) + internal hits 227/664 nti 29 constraint (none) extremes [1, infinity) hits 378/10710 nti 22 constraint DS = {22} extremes [2, infinity) English: @@ -9166,14 +9164,14 @@ {...} constraint (none) extremes [1, infinity) - hits 326/652 nti 31 constraint (none) extremes [1, infinity) + hits 326/652 nti 30 constraint (none) extremes [1, infinity) English: (hits 0/120) constraint DS = {23} extremes [3, infinity) (hits 326/326) (matched long text) constraint (none) extremes [1, infinity) - hits 326/652 nti 6 constraint (none) extremes [1, infinity) + hits 326/652 nti 31 constraint (none) extremes [1, infinity) English: {...} (hits 326/326) (matched long text) constraint (none) extremes [1, infinity) @@ -9187,7 +9185,7 @@ in {...} (hits 12/1665) (matched: 'in the public library') constraint DS = {23} extremes [2, infinity) - hits 958/2310 nti 7 constraint (none) extremes [1, infinity) + hits 958/2310 nti 6 constraint (none) extremes [1, infinity) English: (hits 0/549) constraint DS = {24} extremes [3, infinity) @@ -9201,7 +9199,7 @@ _,/or (hits 0/1262) constraint DS = {24} extremes [2, infinity) - hits 958/2310 nti 8 constraint (none) extremes [1, infinity) + hits 958/2310 nti 7 constraint (none) extremes [1, infinity) English: (hits 0/1155) constraint (none) extremes [1, infinity) @@ -9210,7 +9208,7 @@ (hits 958/1155) (matched long text) constraint (none) extremes [1, infinity) - internal hits 958/2310 nti 9 constraint (none) extremes [1, infinity) + internal hits 958/2310 nti 8 constraint (none) extremes [1, infinity) hits 1/180 nti 28 constraint CS = {28} extremes [1, 1] English: @@ -9224,6 +9222,8 @@ somewhere (hits 0/3) constraint CS = {29} extremes [1, 1] + internal hits 3/19876 nti 9 constraint (none) extremes [1, infinity) + hits 556/21224 nti 30 constraint (none) extremes [1, infinity) English: asking to try diff --git a/inform7/Downloads/syntax-diagnostics.txt b/inform7/Downloads/syntax-diagnostics.txt index e7119c3e5..73b4d452c 100644 --- a/inform7/Downloads/syntax-diagnostics.txt +++ b/inform7/Downloads/syntax-diagnostics.txt @@ -23401,7 +23401,7 @@ ROOT_NT } LOGICAL_AND_NT'looking and a marked for listing person is not in the locati' TEST_VALUE_NT'looking' - CONSTANT_NT'looking' {kind: action} {action pattern: } {explicit action: } + CONSTANT_NT'looking' {kind: action} {explicit action: } TEST_PROPOSITION_NT'a marked for listing person is not in the location' {proposition: << Exists x : kind=person(x) ^ marked for listing(x) ^ NOT< ('the location' == ) NOT> >>} {term: x} CODE_BLOCK_NT INVOCATION_LIST_NT'clear marked people' {indent: 3} diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt index ddff75e1a..4a9489e7a 100644 --- a/inform7/Figures/memory-diagnostics.txt +++ b/inform7/Figures/memory-diagnostics.txt @@ -1,13 +1,13 @@ Total memory consumption was 257775K = 252 MB -62.3% was used for 1339896 objects, in 278621 frames in 201 x 800K = 160800K = 157 MB: +62.3% was used for 1339899 objects, in 278624 frames in 201 x 800K = 160800K = 157 MB: 9.8% inter_tree_node_array 36 x 8192 = 294912 objects, 25953408 bytes 5.5% text_stream_array 2595 x 100 = 259500 objects, 14615040 bytes 3.9% parse_node 129996 objects, 10399680 bytes 2.8% verb_conjugation 160 objects, 7425280 bytes 2.6% parse_node_annotation_array 431 x 500 = 215500 objects, 6909792 bytes - 2.4% linked_list 11778 objects, 6595680 bytes + 2.4% linked_list 11781 objects, 6597360 bytes 2.3% inter_symbol_array 70 x 1024 = 71680 objects, 6310080 bytes 1.2% pcalc_prop_array 24 x 1000 = 24000 objects, 3264768 bytes 1.2% map_data 670 objects, 3178480 bytes @@ -246,5 +246,5 @@ Total memory consumption was 257775K = 252 MB ---- emitter array storage 12320 bytes in 8 claims ---- code generation workspace for objects 9200 bytes in 9 claims -19.7% was overhead - 52176848 bytes = 50953K = 49 MB +19.7% was overhead - 52175168 bytes = 50952K = 49 MB diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt index c7baedd9d..a6ce33455 100644 --- a/inform7/Figures/timings-diagnostics.txt +++ b/inform7/Figures/timings-diagnostics.txt @@ -1,15 +1,15 @@ 100.0% in inform7 run 66.9% in compilation to Inter - 25.5% in //Phrases::Manager::compile_first_block// - 8.5% in //Phrases::Manager::compile_as_needed// - 6.8% in //Strings::compile_responses// - 6.3% in //InferenceSubjects::emit_all// - 4.1% in //MajorNodes::pre_pass// - 3.4% in //MajorNodes::pass_1// - 1.9% in //Phrases::Manager::RulePrintingRule_routine// + 25.4% in //Phrases::Manager::compile_first_block// + 8.8% in //Phrases::Manager::compile_as_needed// + 7.0% in //Strings::compile_responses// + 6.0% in //InferenceSubjects::emit_all// + 4.2% in //MajorNodes::pre_pass// + 3.3% in //MajorNodes::pass_1// + 2.0% in //Phrases::Manager::RulePrintingRule_routine// 1.8% in //Phrases::Manager::rulebooks_array// - 0.9% in //Phrases::Manager::traverse// - 0.9% in //RTVerbs::ConjugateVerb// + 1.1% in //RTVerbs::ConjugateVerb// + 0.7% in //Phrases::Manager::traverse// 0.5% in //Phrases::Manager::parse_rule_parameters// 0.5% in //World::stage_V// 0.3% in //MajorNodes::pass_2// @@ -19,11 +19,11 @@ 0.1% in //RTKinds::compile_data_type_support_routines// 0.1% in //Task::make_built_in_kind_constructors// 0.1% in //World::stages_II_and_III// - 3.4% not specifically accounted for + 3.3% not specifically accounted for 30.6% in running Inter pipeline 9.9% in step preparation - 9.8% in inter step 2/12: link - 7.2% in inter step 12/12: generate inform6 -> auto.inf + 9.7% in inter step 2/12: link + 7.3% in inter step 12/12: generate inform6 -> auto.inf 0.3% in inter step 9/12: make-identifiers-unique 0.1% in inter step 10/12: reconcile-verbs 0.1% in inter step 11/12: eliminate-redundant-labels @@ -31,6 +31,6 @@ 0.1% in inter step 6/12: assimilate 0.1% in inter step 7/12: resolve-external-symbols 0.1% in inter step 8/12: inspect-plugs - 2.2% not specifically accounted for - 1.9% in supervisor + 2.1% not specifically accounted for + 2.0% in supervisor 0.4% not specifically accounted for diff --git a/inform7/Tests/Groups/actions.testgroup b/inform7/Tests/Groups/actions.testgroup index c5a24c73f..eccd07ebb 100644 --- a/inform7/Tests/Groups/actions.testgroup +++ b/inform7/Tests/Groups/actions.testgroup @@ -12,6 +12,8 @@ RelDynamicPointer ConstantStoredActionsWithTopics InheritedStoredActions TableDefinedSAs +ForLengthsOfTime +C9ScenesPastTenseActions PM_NamedAPIsArticle PM_NamedAPWithActor PM_GoingWrongKind diff --git a/inform7/assertions-module/Chapter 4/Assertions.w b/inform7/assertions-module/Chapter 4/Assertions.w index 063b0d386..f26c96030 100644 --- a/inform7/assertions-module/Chapter 4/Assertions.w +++ b/inform7/assertions-module/Chapter 4/Assertions.w @@ -595,19 +595,10 @@ further sub-cases later. Problems::issue_problem_end(); return; } - #ifdef IF_MODULE - if (Node::get_type(py) == ACTION_NT) { - action_pattern *ap = Node::get_action_meaning(py); - if (ap) { - parse_node *val = Rvalues::from_action_pattern(ap); - if (Rvalues::is_CONSTANT_of_kind(val, K_stored_action)) { - Refiner::give_spec_to_noun(py, val); - Assertions::make_coupling(px, py); - return; - } - } + if (PluginCalls::unusual_property_value(py)) { + Assertions::make_coupling(px, py); + return; } - #endif Problems::Using::assertion_problem(Task::syntax_tree(), _p_(PM_PeculiarProperty), "that is a very peculiar property value", "and ought to be something more definite and explicit."); diff --git a/inform7/assertions-module/Chapter 4/Refine Parse Tree.w b/inform7/assertions-module/Chapter 4/Refine Parse Tree.w index b5a553f6a..8e5367549 100644 --- a/inform7/assertions-module/Chapter 4/Refine Parse Tree.w +++ b/inform7/assertions-module/Chapter 4/Refine Parse Tree.w @@ -316,7 +316,7 @@ is allowed to stand. Wordings::last_wn(Node::get_text(p->down->next))); if (Wordings::nonempty(W)) { if ((W)) { - ActionPatterns::make_ACTION_node(p, <>); + ActionsNodes::convert_to_ACTION_node(p, <>); Node::set_text(p, W); } } @@ -601,7 +601,7 @@ here, given that we know we are looking for a noun. #ifdef IF_MODULE if (Node::get_article(p) == NULL) { if ((Node::get_text(p))) { - ActionPatterns::make_ACTION_node(p, <>); + ActionsNodes::convert_to_ACTION_node(p, <>); return; } } diff --git a/inform7/assertions-module/Chapter 4/The Creator.w b/inform7/assertions-module/Chapter 4/The Creator.w index 22c289a01..a24e02ceb 100644 --- a/inform7/assertions-module/Chapter 4/The Creator.w +++ b/inform7/assertions-module/Chapter 4/The Creator.w @@ -71,41 +71,13 @@ about this kind of value sometimes comes from a particular node somewhere in |py|, which (if it exists) we'll call its "governing node". @ = - @; + PluginCalls::creation(px, py); parse_node *govx = NULL, *govy = NULL; kind *kindx = NULL, *kindy = NULL; @; Assertions::Creator::noun_creator(px, kindy, govy); Assertions::Creator::noun_creator(py, kindx, govx); -@ The first case here is to take care of a sentence like: - ->> Taking something is proactive behaviour. - -Here |Refiner::refine| will correctly report that "proactive behaviour" is -a new term, and give it a |CREATED_NT| node. But we don't want it to become an -object or a value -- it will become a named kind of action instead. So we -amend the node to |ACTION_NT|. - -The second case occurs much less often -- for instance, the only time it comes -up in the test suite is in the example "Chronic Hinting Syndrome": - ->> Setting is a kind of value. The settings are bright and dull. - -Here the first sentence wants to create something called "setting", which -ought to have a |CREATED_NT| node type, but doesn't because it has been read -as an action instead. We correct the spurious |ACTION_NT| to a |CREATED_NT|. - -@ = - if ((Assertions::Creator::actionlike(px)) && (Node::get_type(py) == CREATED_NT)) - Node::set_type(py, ACTION_NT); - if ((Assertions::Creator::actionlike(px)) && (Assertions::Creator::actionlike(py))) { - Assertions::Creator::to_action_node(px); - Assertions::Creator::to_action_node(py); - } - if ((Node::get_type(px) == ACTION_NT) && (Node::get_type(py) == KIND_NT)) - Node::set_type(px, CREATED_NT); - @ There are two ways to know the kind being expressed. One is that the sentence makes unambiguous use of a relation which forces the kinds on each side. For example, @@ -144,34 +116,6 @@ The other way to find the kinds is to look at what the two sides explicitly say: kindy = Assertions::Creator::kind_of_subtree(py, &govy); } -@ = -int Assertions::Creator::actionlike(parse_node *p) { - #ifdef IF_MODULE - if (Node::get_type(p) == ACTION_NT) return TRUE; - if (Node::get_type(p) == PROPER_NOUN_NT) { - parse_node *spec = Node::get_evaluation(p); - if (Rvalues::is_CONSTANT_of_kind(spec, K_stored_action)) - return TRUE; - } - #endif - return FALSE; -} - -void Assertions::Creator::to_action_node(parse_node *p) { - #ifdef IF_MODULE - if (Node::get_type(p) == ACTION_NT) return; - if (Node::get_type(p) == PROPER_NOUN_NT) { - parse_node *spec = Node::get_evaluation(p); - if (Rvalues::is_CONSTANT_of_kind(spec, K_stored_action)) { - explicit_action *ea = Node::get_constant_explicit_action(spec); - ActionPatterns::make_ACTION_node(p, ea->as_described); - return; - } - } - #endif - internal_error("misapplied to_action_node"); -} - @ So that just leaves the algorithms for finding the relation of a subtree: = diff --git a/inform7/core-module/Chapter 3/Plugin Calls.w b/inform7/core-module/Chapter 3/Plugin Calls.w index 19d2c64fd..bcc11559d 100644 --- a/inform7/core-module/Chapter 3/Plugin Calls.w +++ b/inform7/core-module/Chapter 3/Plugin Calls.w @@ -75,6 +75,29 @@ int PluginCalls::intervene_in_assertion(parse_node *px, parse_node *py) { PLUGINS_CALL(INTERVENE_IN_ASSERTION_PLUG, px, py); } +@ Called from //assertions: The Creator// when a copular sentence may be +creating something. For example, the actions plugin needs this. + +@e CREATION_PLUG + += +int PluginCalls::creation(parse_node *px, parse_node *py) { + PLUGINS_CALL(CREATION_PLUG, px, py); +} + +@ Called from //assertions: Assertions// when an unfamiliar node type appears +where a property value might be expected. For example, the actions plugin +uses this to deal with setting a property to an |ACTION_NT| node. To +intervene, set the node specification using //assertions: Refine Parse Tree// +and return |TRUE|; or return |FALSE| to let nature take its course. + +@e UNUSUAL_PROPERTY_VALUE_PLUG + += +int PluginCalls::unusual_property_value(parse_node *py) { + PLUGINS_CALL(UNUSUAL_PROPERTY_VALUE_PLUG, py); +} + @ Called from //assertions: The Creator// when an instance is being made in an assembly, and its name may involve a genitive. For example, if the assembly says "every person has a nose", then normally this would be called @@ -174,7 +197,20 @@ int PluginCalls::variable_set_warning(nonlocal_variable *q, parse_node *val) { } @h Influencing values. -Called from //values: Rvalues// to allow plugins to compile rvalues in +Called from //values: Rvalues// to allow plugins to help decide whether values +of the same kind would be equal if evaluated at runtime. For example, the +"scenes" plugin uses this to determine if two |K_scene| constants are equal. +To make a decision, set |rv| to either |TRUE| or |FALSE| and return |TRUE|. +To make no decision, return |FALSE|. + +@e COMPARE_CONSTANT_PLUG + += +int PluginCalls::compare_constant(parse_node *c1, parse_node *c2, int *rv) { + PLUGINS_CALL(COMPARE_CONSTANT_PLUG, c1, c2, rv); +} + +@ Called from //values: Rvalues// to allow plugins to compile rvalues in eccentric ways of their own: not in fact just for the whimsy of it, but to make it possible for plugins to support base kinds of their own. For example, the "actions" plugin needs this to deal with the "stored action" kind. diff --git a/inform7/if-module/Chapter 3/Scenes.w b/inform7/if-module/Chapter 3/Scenes.w index 2618936ea..c2df5d4cb 100644 --- a/inform7/if-module/Chapter 3/Scenes.w +++ b/inform7/if-module/Chapter 3/Scenes.w @@ -16,6 +16,7 @@ void Scenes::start(void) { PluginManager::plug(NEW_PROPERTY_NOTIFY_PLUG, Scenes::new_property_notify); PluginManager::plug(NEW_INSTANCE_NOTIFY_PLUG, Scenes::new_named_instance_notify); PluginManager::plug(NEW_BASE_KIND_NOTIFY_PLUG, Scenes::new_base_kind_notify); + PluginManager::plug(COMPARE_CONSTANT_PLUG, Scenes::compare_CONSTANT); PluginManager::plug(MAKE_SPECIAL_MEANINGS_PLUG, Scenes::make_special_meanings); } @@ -62,6 +63,18 @@ int Scenes::new_base_kind_notify(kind *new_base, text_stream *name, wording W) { return FALSE; } +int Scenes::compare_CONSTANT(parse_node *spec1, parse_node *spec2, int *rv) { + kind *K = Node::get_kind_of_value(spec1); + if (Kinds::eq(K, K_scene)) { + if (ARvalues::to_scene(spec1) == ARvalues::to_scene(spec2)) { + *rv = TRUE; + } + *rv = FALSE; + return TRUE; + } + return FALSE; +} + @ //scene// structures are automatically created whenever a new instance of the kind "scene" is created, and this is where that happens. diff --git a/inform7/if-module/Chapter 4/Action Conditions.w b/inform7/if-module/Chapter 4/Action Conditions.w new file mode 100644 index 000000000..913a04f9b --- /dev/null +++ b/inform7/if-module/Chapter 4/Action Conditions.w @@ -0,0 +1,25 @@ +[AConditions::] Action Conditions. + +A special condition for testing against action patterns. + +@ = +parse_node *AConditions::new_action_TEST_VALUE(action_pattern *ap, wording W) { + if (ap == NULL) internal_error("null action pattern"); + parse_node *spec = Node::new_with_words(TEST_VALUE_NT, W); + spec->down = ARvalues::from_action_pattern(ap); + Node::set_text(spec->down, W); + return spec; +} + +int AConditions::is_action_TEST_VALUE(parse_node *spec) { + if ((Node::is(spec, TEST_VALUE_NT)) && + ((ARvalues::to_action_pattern(spec->down)) || + (ARvalues::to_explicit_action(spec->down)))) return TRUE; + return FALSE; +} + +parse_node *AConditions::action_tested(parse_node *spec) { + if (AConditions::is_action_TEST_VALUE(spec) == FALSE) + internal_error("action improperly extracted"); + return spec->down; +} diff --git a/inform7/if-module/Chapter 4/Action Kinds.w b/inform7/if-module/Chapter 4/Action Kinds.w new file mode 100644 index 000000000..60f8556ba --- /dev/null +++ b/inform7/if-module/Chapter 4/Action Kinds.w @@ -0,0 +1,115 @@ +[ARvalues::] Action Kinds. + +Three action-related kinds of value. + +@ The following represent action names, stored actions and descriptions of +actions respectively: see //Actions Plugin// for what these terms mean. + += (early code) +kind *K_action_name = NULL; +kind *K_stored_action = NULL; +kind *K_description_of_action = NULL; + +@ These are created by a Neptune file inside //WorldModelKit//, and are +recognised by their Inter identifiers: + +@ = +int ARvalues::new_base_kind_notify(kind *new_base, text_stream *name, wording W) { + if (Str::eq_wide_string(name, L"ACTION_NAME_TY")) { + K_action_name = new_base; return TRUE; + } + if (Str::eq_wide_string(name, L"DESCRIPTION_OF_ACTION_TY")) { + K_description_of_action = new_base; return TRUE; + } + if (Str::eq_wide_string(name, L"STORED_ACTION_TY")) { + K_stored_action = new_base; return TRUE; + } + return FALSE; +} + +@ A stored action can always be compared to a gerund: for instance, + +>> if the current action is taking something... + += +int ARvalues::actions_typecheck_equality(kind *K1, kind *K2) { + if ((Kinds::eq(K1, K_stored_action)) && (Kinds::eq(K2, K_description_of_action))) + return TRUE; + return FALSE; +} + +@ All three of these kinds can have constant values. For an action name, these +correspond simply to //action_name// objects: + += +parse_node *ARvalues::from_action_name(action_name *val) { + CONV_FROM(action_name, K_action_name) } +action_name *ARvalues::to_action_name(parse_node *spec) { + CONV_TO(action_name) } + +@ When text is parsed to an action pattern, the result can be stored as a +constant in two ways. If the pattern unambiguously describes a single explicit +action, the result has the kind "stored action" and corresponds to an +//explicit_action// object; if the pattern is looser than that, the result +is a "description of action" and correspond to an //action_pattern//. + +For example, "taking the golden telephone" might be a |K_stored_action| +constant, but "doing something to the golden telephone" or "taking something" +or "taking the golden telephone in the presence of Mr Wu" would all be +|K_description_of_action|. + += +parse_node *ARvalues::from_action_pattern(action_pattern *val) { + int failure_code = 0; + explicit_action *ea = ExplicitActions::from_action_pattern(val, &failure_code); + if (ea) { + parse_node *spec = Node::new(CONSTANT_NT); + Node::set_kind_of_value(spec, K_stored_action); + Node::set_constant_explicit_action(spec, ea); + return spec; + } else { + CONV_FROM(action_pattern, K_description_of_action); + } +} +action_pattern *ARvalues::to_action_pattern(parse_node *spec) { + CONV_TO(action_pattern) } +explicit_action *ARvalues::to_explicit_action(parse_node *spec) { + CONV_TO(explicit_action) } + +@ Finally, for a named action pattern, constant values correspond to +//named_action_pattern// objects. These are actually never used at run-time +and do not appear as rvalues in any permanent way inside the compiler, so +the kind |K_description_of_action| is given to them only on principle. If +they were used as values, this is the kind we would probably give them. + += +parse_node *ARvalues::from_named_action_pattern(named_action_pattern *val) { + CONV_FROM(named_action_pattern, K_description_of_action ) } +named_action_pattern *ARvalues::to_named_action_pattern(parse_node *spec) { + CONV_TO(named_action_pattern) } + +parse_node *ARvalues::from_grammar_verb(grammar_verb *val) { + CONV_FROM(grammar_verb, K_understanding) } +grammar_verb *ARvalues::to_grammar_verb(parse_node *spec) { + CONV_TO(grammar_verb) } +parse_node *ARvalues::from_scene(scene *val) { + CONV_FROM(scene, K_scene) } +scene *ARvalues::to_scene(parse_node *spec) { + CONV_TO(scene) } + +@ It's not useful to be able to compare description of action constants for +equality in this sense. There would be a case for doing so with stored actions, +but in practice there seems little need, so for the moment we do not. + += +int ARvalues::compare_CONSTANT(parse_node *spec1, parse_node *spec2, int *rv) { + kind *K = Node::get_kind_of_value(spec1); + if (Kinds::eq(K, K_action_name)) { + if (ARvalues::to_action_name(spec1) == ARvalues::to_action_name(spec2)) { + *rv = TRUE; + } + *rv = FALSE; + return TRUE; + } + return FALSE; +} diff --git a/inform7/if-module/Chapter 4/Action Name Names.w b/inform7/if-module/Chapter 4/Action Name Names.w index a9b12def1..efa16451c 100644 --- a/inform7/if-module/Chapter 4/Action Name Names.w +++ b/inform7/if-module/Chapter 4/Action Name Names.w @@ -34,7 +34,7 @@ void ActionNameNames::baptise(action_name *an, wording W) { WordAssemblages::from_wording(W)); wording AW = WordAssemblages::to_wording(&wa); an->naming_data.as_noun = Nouns::new_proper_noun(AW, NEUTER_GENDER, ADD_TO_LEXICON_NTOPT, - MISCELLANEOUS_MC, Rvalues::from_action_name(an), Task::language_of_syntax()); + MISCELLANEOUS_MC, ARvalues::from_action_name(an), Task::language_of_syntax()); Vocabulary::set_flags(Lexer::word(Wordings::first_wn(W)), ACTION_PARTICIPLE_MC); action_name *an2; LOOP_OVER(an2, action_name) diff --git a/inform7/if-module/Chapter 4/Action Pattern Clauses.w b/inform7/if-module/Chapter 4/Action Pattern Clauses.w index c494dfcd7..0ba466f01 100644 --- a/inform7/if-module/Chapter 4/Action Pattern Clauses.w +++ b/inform7/if-module/Chapter 4/Action Pattern Clauses.w @@ -320,7 +320,7 @@ int APClauses::cmp_clauses(int C1, action_pattern *ap1, int C2, action_pattern * } int APClauses::viable_in_past_tense(action_pattern *ap) { - if (ActionPatterns::is_overspecific(ap)) return FALSE; + if (ExplicitActions::ap_overspecific(ap)) return FALSE; if (APClauses::pta_acceptable(APClauses::get_val(ap, ACTOR_AP_CLAUSE)) == FALSE) return FALSE; if (APClauses::pta_acceptable(APClauses::get_val(ap, NOUN_AP_CLAUSE)) == FALSE) return FALSE; if (APClauses::pta_acceptable(APClauses::get_val(ap, SECOND_AP_CLAUSE)) == FALSE) return FALSE; diff --git a/inform7/if-module/Chapter 4/Action Patterns.w b/inform7/if-module/Chapter 4/Action Patterns.w index a0a7f96a3..07edb012d 100644 --- a/inform7/if-module/Chapter 4/Action Patterns.w +++ b/inform7/if-module/Chapter 4/Action Patterns.w @@ -43,19 +43,7 @@ action_pattern ActionPatterns::new(void) { return ap; } -@ - -= -typedef struct explicit_action { - int request; - struct action_name *action; - struct parse_node *actor; - struct parse_node *first_noun; - struct parse_node *second_noun; - struct action_pattern *as_described; -} explicit_action; - - +@ = void ActionPatterns::log(action_pattern *ap) { ActionPatterns::write(DL, ap); } @@ -112,54 +100,6 @@ int ActionPatterns::object_based(action_pattern *ap) { return FALSE; } -explicit_action *ActionPatterns::to_explicit_action(action_pattern *ap, int *reason) { - if (ActionPatterns::is_unspecific(ap)) { *reason = 1; return NULL; } - if (ActionPatterns::is_overspecific(ap)) { *reason = 2; return NULL; } - *reason = 0; - explicit_action *ea = CREATE(explicit_action); - ea->action = ActionNameLists::get_the_one_true_action(ap->action_list); - ea->request = APClauses::is_request(ap); - ea->actor = APClauses::get_val(ap, ACTOR_AP_CLAUSE); - ea->first_noun = APClauses::get_val(ap, NOUN_AP_CLAUSE); - ea->second_noun = APClauses::get_val(ap, SECOND_AP_CLAUSE); - ea->as_described = ap; - return ea; -} - -void ActionPatterns::make_ACTION_node(parse_node *p, action_pattern *ap) { - Node::set_type(p, ACTION_NT); - Node::set_action_meaning(p, ap); - p->down = NULL; -} - -int ActionPatterns::is_unspecific(action_pattern *ap) { - action_name *an = ActionPatterns::required_action(ap); - if (an == NULL) return TRUE; - if ((ActionSemantics::must_have_noun(an)) && (APClauses::get_val(ap, NOUN_AP_CLAUSE) == NULL)) return TRUE; - if ((ActionSemantics::must_have_second(an)) && (APClauses::get_val(ap, SECOND_AP_CLAUSE) == NULL)) return TRUE; - if ((ActionSemantics::can_have_noun(an)) && - (ActionPatterns::ap_clause_is_unspecific(APClauses::get_val(ap, NOUN_AP_CLAUSE)))) return TRUE; - if ((ActionSemantics::can_have_second(an)) && - (ActionPatterns::ap_clause_is_unspecific(APClauses::get_val(ap, SECOND_AP_CLAUSE)))) return TRUE; - if (ActionPatterns::ap_clause_is_unspecific(APClauses::get_val(ap, ACTOR_AP_CLAUSE))) return TRUE; - return FALSE; -} - -int ActionPatterns::ap_clause_is_unspecific(parse_node *spec) { - if (spec == NULL) return FALSE; - if (Specifications::is_description(spec) == FALSE) return FALSE; - return TRUE; -} - -int ActionPatterns::is_overspecific(action_pattern *ap) { - for (ap_clause *apoc = (ap)?(ap->ap_clauses):NULL; apoc; apoc = apoc->next) - if ((APClauses::aspect(apoc) != PRIMARY_APCA) && (apoc->clause_spec)) - return TRUE; - if (APClauses::has_any_actor(ap)) return TRUE; - if (ap->duration) return TRUE; - return FALSE; -} - void ActionPatterns::suppress_action_testing(action_pattern *ap) { if ((ap->duration == NULL) && (ap->action_list)) ActionNameLists::suppress_action_testing(ap->action_list); @@ -188,6 +128,19 @@ int ActionPatterns::makes_callings(action_pattern *ap) { return FALSE; } +action_pattern *ActionPatterns::action_from_TEST(parse_node *spec) { + if (AConditions::is_action_TEST_VALUE(spec)) { + action_pattern *ap = ARvalues::to_action_pattern( + AConditions::action_tested(spec)); + if (ap == NULL) { + explicit_action *ea = Node::get_constant_explicit_action(AConditions::action_tested(spec)); + if (ea) ap = ea->as_described; + } + return ap; + } + return NULL; +} + int ActionPatterns::compare_specificity(action_pattern *ap1, action_pattern *ap2) { if ((ap1 == NULL) && (ap2)) return -1; if ((ap1) && (ap2 == NULL)) return 1; diff --git a/inform7/if-module/Chapter 4/Action Variables.w b/inform7/if-module/Chapter 4/Action Variables.w index 4ceed495a..9388d130b 100644 --- a/inform7/if-module/Chapter 4/Action Variables.w +++ b/inform7/if-module/Chapter 4/Action Variables.w @@ -9,7 +9,7 @@ into creations of action variables: = int ActionVariables::actions_offered_property(kind *K, parse_node *owner, parse_node *prop) { if (Kinds::eq(K, K_action_name)) { - action_name *an = Rvalues::to_action_name(owner); + action_name *an = ARvalues::to_action_name(owner); if (an == NULL) internal_error("failed to extract action-name structure"); if (global_pass_state.pass == 1) { @; diff --git a/inform7/if-module/Chapter 4/Actions Plugin.w b/inform7/if-module/Chapter 4/Actions Plugin.w index 184ef00ea..ca3ab0829 100644 --- a/inform7/if-module/Chapter 4/Actions Plugin.w +++ b/inform7/if-module/Chapter 4/Actions Plugin.w @@ -5,16 +5,41 @@ A plugin for actions, by which animate characters change the world model. @ Support for actions is contained in the "actions" plugin, which occupies this entire chapter. The test group |:actions| may be helpful in trouble-shooting here. +It may be helpful to distinguish these ideas right from the outset: + +(*) An "action" (or "explicit action", for the sake of clarity) is a specific +impulse by a person in the model world to effect some change within it: for +example, "Henry taking the brick". Here Henry is the "actor", and the brick is +"the noun". Actions can be "stored" so that they are values in their own +right; thus, a variable could be set to the value "Henry taking the brick", +and this would have kind |K_stored_action|. Inside the compiler they are +represented by //explicit_action// objects. +(*) An "action name" -- not an ideal thing to call it, but traditional -- is the +type of action involved, taken in isolation: for example, "taking". These can +also be values at run-time, they have kind |K_action_name|, and they are +represented in the comoiler by //action_name// objections. +(*) An "action pattern" is a textual description which matches some actions but +not others, and can be vague or specific: for example, "wearing or examining +something". Action patterns become values of the kind |K_description_of_action|. +They can also be aggregated into "named action patterns", which characterise +behaviour; see //action_pattern// and //named_action_pattern//. +(*) A "past action pattern", which can never in any way be a value, is a +description of an action which have happened in the past: for example, "dropped +the hat". These are just a special case of action patterns. + = void ActionsPlugin::start(void) { ActionsNodes::nodes_and_annotations(); PluginManager::plug(MAKE_SPECIAL_MEANINGS_PLUG, ActionsPlugin::make_special_meanings); - PluginManager::plug(NEW_BASE_KIND_NOTIFY_PLUG, ActionsPlugin::new_base_kind_notify); + PluginManager::plug(NEW_BASE_KIND_NOTIFY_PLUG, ARvalues::new_base_kind_notify); + PluginManager::plug(COMPARE_CONSTANT_PLUG, ARvalues::compare_CONSTANT); PluginManager::plug(COMPILE_CONSTANT_PLUG, RTActions::actions_compile_constant); + PluginManager::plug(CREATION_PLUG, ActionsNodes::creation); + PluginManager::plug(UNUSUAL_PROPERTY_VALUE_PLUG, ActionsNodes::unusual_property_value_node); PluginManager::plug(OFFERED_PROPERTY_PLUG, ActionVariables::actions_offered_property); PluginManager::plug(OFFERED_SPECIFICATION_PLUG, ActionsPlugin::actions_offered_specification); - PluginManager::plug(TYPECHECK_EQUALITY_PLUG, ActionsPlugin::actions_typecheck_equality); + PluginManager::plug(TYPECHECK_EQUALITY_PLUG, ARvalues::actions_typecheck_equality); PluginManager::plug(PRODUCTION_LINE_PLUG, ActionsPlugin::production_line); Vocabulary::set_flags(Vocabulary::entry_for_text(L"doing"), ACTION_PARTICIPLE_MC); @@ -32,59 +57,6 @@ int ActionsPlugin::production_line(int stage, int debugging, stopwatch_timer *se return FALSE; } -@ It may be useful to distinguish three ideas right from the outset: - -(*) An "action" is a specific impulse by a person in the model world to effect -some change within it: for example, "Henry taking the brick". Here Henry is the -"actor", and the brick is "the noun". Actions can be "stored" so that they -are values in their own right; thus, a variable could be set to the value -"Henry taking the brick", and this would have kind |K_stored_action|. -(*) An "action name" -- not an ideal thing to call it, but traditional -- is the -type of action involved, taken in isolation: for example, "taking". These can -also be values at run-time, and have kind |K_action_name|. -(*) An "action pattern" is a textual description which matches some actions but -not others, and can be vague or specific: for example, "wearing or examining -something". Action patterns are in general not values, but names can be given -to them so that they are -- see //Named Action Patterns// -- and then they -have the kind |K_description_of_action|. -(*) A "past action pattern", which can never in any way be a value, is a -description of an action which have happened in the past: for example, "dropped -the hat". - -= (early code) -kind *K_action_name = NULL; -kind *K_stored_action = NULL; -kind *K_description_of_action = NULL; - -@ These are created by a Neptune file inside //WorldModelKit//, and are -recognised by their Inter identifiers: - -@ = -int ActionsPlugin::new_base_kind_notify(kind *new_base, text_stream *name, wording W) { - if (Str::eq_wide_string(name, L"ACTION_NAME_TY")) { - K_action_name = new_base; return TRUE; - } - if (Str::eq_wide_string(name, L"DESCRIPTION_OF_ACTION_TY")) { - K_description_of_action = new_base; return TRUE; - } - if (Str::eq_wide_string(name, L"STORED_ACTION_TY")) { - K_stored_action = new_base; return TRUE; - } - return FALSE; -} - -@ A stored action can always be compared to a gerund: for instance, - ->> if the current action is taking something... - -= -int ActionsPlugin::actions_typecheck_equality(kind *K1, kind *K2) { - if ((Kinds::eq(K1, K_stored_action)) && - (Kinds::eq(K2, K_description_of_action))) - return TRUE; - return FALSE; -} - @ Though |K_action_name| is very like an enumeration kind, its possible values, which correspond to //action_name// objects, are not strictly speaking instances in the Inform world model. (Because they do not have properties: see //Action Variables// @@ -127,7 +99,7 @@ a "specification" text as one, and have to make their own arrangements: int ActionsPlugin::actions_offered_specification(parse_node *owner, wording W) { if (Rvalues::is_CONSTANT_of_kind(owner, K_action_name)) { IXActions::actions_set_specification_text( - Rvalues::to_action_name(owner), Wordings::first_wn(W)); + ARvalues::to_action_name(owner), Wordings::first_wn(W)); return TRUE; } return FALSE; diff --git a/inform7/if-module/Chapter 4/Actions-Only Nodes and Annotations.w b/inform7/if-module/Chapter 4/Actions-Only Nodes and Annotations.w index f7a1e2b61..b931abe75 100644 --- a/inform7/if-module/Chapter 4/Actions-Only Nodes and Annotations.w +++ b/inform7/if-module/Chapter 4/Actions-Only Nodes and Annotations.w @@ -48,6 +48,80 @@ void ActionsNodes::nodes_and_annotations(void) { Annotations::allow(CONSTANT_NT, constant_explicit_action_ANNOT); } +@ ACTION nodes are converted from existing ones, not born: + += +void ActionsNodes::convert_to_ACTION_node(parse_node *p, action_pattern *ap) { + Node::set_type(p, ACTION_NT); + Node::set_action_meaning(p, ap); + p->down = NULL; +} + +int ActionsNodes::is_actionlike(parse_node *p) { + if (Node::get_type(p) == ACTION_NT) return TRUE; + if ((K_stored_action) && (Node::get_type(p) == PROPER_NOUN_NT)) { + parse_node *spec = Node::get_evaluation(p); + if (Rvalues::is_CONSTANT_of_kind(spec, K_stored_action)) return TRUE; + } + return FALSE; +} + +void ActionsNodes::convert_stored_action_constant(parse_node *p) { + if (Node::get_type(p) == PROPER_NOUN_NT) { + parse_node *spec = Node::get_evaluation(p); + if (Rvalues::is_CONSTANT_of_kind(spec, K_stored_action)) { + explicit_action *ea = Node::get_constant_explicit_action(spec); + ActionsNodes::convert_to_ACTION_node(p, ea->as_described); + return; + } + } +} + +@ The first case here is to take care of a sentence like: + +>> Taking something is proactive behaviour. + +Here |Refiner::refine| will correctly report that "proactive behaviour" is +a new term, and give it a |CREATED_NT| node. But we don't want it to become an +object or a value -- it will become a named kind of action instead. So we +amend the node to |ACTION_NT|. + +The second case occurs much less often -- for instance, the only time it comes +up in the test suite is in the example "Chronic Hinting Syndrome": + +>> Setting is a kind of value. The settings are bright and dull. + +Here the first sentence wants to create something called "setting", which +ought to have a |CREATED_NT| node type, but doesn't because it has been read +as an action instead. We correct the spurious |ACTION_NT| to a |CREATED_NT|. + += +int ActionsNodes::creation(parse_node *px, parse_node *py) { + if ((ActionsNodes::is_actionlike(px)) && (Node::get_type(py) == CREATED_NT)) + Node::set_type(py, ACTION_NT); + if ((ActionsNodes::is_actionlike(px)) && (ActionsNodes::is_actionlike(py))) { + ActionsNodes::convert_stored_action_constant(px); + ActionsNodes::convert_stored_action_constant(py); + } + if ((Node::get_type(px) == ACTION_NT) && (Node::get_type(py) == KIND_NT)) + Node::set_type(px, CREATED_NT); + return FALSE; +} + +int ActionsNodes::unusual_property_value_node(parse_node *py) { + if (Node::get_type(py) == ACTION_NT) { + action_pattern *ap = Node::get_action_meaning(py); + if (ap) { + parse_node *val = ARvalues::from_action_pattern(ap); + if (Rvalues::is_CONSTANT_of_kind(val, K_stored_action)) { + Refiner::give_spec_to_noun(py, val); + return TRUE; + } + } + } + return FALSE; +} + @ And for the debugging log: = diff --git a/inform7/if-module/Chapter 4/Explicit Actions.w b/inform7/if-module/Chapter 4/Explicit Actions.w new file mode 100644 index 000000000..3a8980cdd --- /dev/null +++ b/inform7/if-module/Chapter 4/Explicit Actions.w @@ -0,0 +1,68 @@ +[ExplicitActions::] Explicit Actions. + +An exactly specified action is called "explicit". + +@ Explicit actions are used inside the compiler whenever we kmow exactly what +action we are talking about; stored action constants are //explicit_action// +objects in a thin wrapper -- see //Action Kinds//. + += +typedef struct explicit_action { + int request; + struct action_name *action; + struct parse_node *actor; + struct parse_node *first_noun; + struct parse_node *second_noun; + struct action_pattern *as_described; +} explicit_action; + +@ + +@d UNDERSPECIFIC_EA_FAILURE 1 +@d OVERSPECIFIC_EA_FAILURE 2 + += +explicit_action *ExplicitActions::from_action_pattern(action_pattern *ap, int *reason) { + if (ExplicitActions::ap_underspecific(ap)) { *reason = UNDERSPECIFIC_EA_FAILURE; return NULL; } + if (ExplicitActions::ap_overspecific(ap)) { *reason = OVERSPECIFIC_EA_FAILURE; return NULL; } + *reason = 0; + explicit_action *ea = CREATE(explicit_action); + ea->action = ActionNameLists::get_the_one_true_action(ap->action_list); + ea->request = APClauses::is_request(ap); + ea->actor = APClauses::get_val(ap, ACTOR_AP_CLAUSE); + ea->first_noun = APClauses::get_val(ap, NOUN_AP_CLAUSE); + ea->second_noun = APClauses::get_val(ap, SECOND_AP_CLAUSE); + ea->as_described = ap; + return ea; +} + +int ExplicitActions::ap_underspecific(action_pattern *ap) { + action_name *an = ActionPatterns::required_action(ap); + if (an == NULL) return TRUE; + if ((ActionSemantics::must_have_noun(an)) && + (APClauses::get_val(ap, NOUN_AP_CLAUSE) == NULL)) return TRUE; + if ((ActionSemantics::must_have_second(an)) && + (APClauses::get_val(ap, SECOND_AP_CLAUSE) == NULL)) return TRUE; + if ((ActionSemantics::can_have_noun(an)) && + (ExplicitActions::clause_unspecific(ap, NOUN_AP_CLAUSE))) return TRUE; + if ((ActionSemantics::can_have_second(an)) && + (ExplicitActions::clause_unspecific(ap, SECOND_AP_CLAUSE))) return TRUE; + if (ExplicitActions::clause_unspecific(ap, ACTOR_AP_CLAUSE)) return TRUE; + return FALSE; +} + +int ExplicitActions::clause_unspecific(action_pattern *ap, int C) { + parse_node *spec = APClauses::get_val(ap, C); + if (spec == NULL) return FALSE; + if (Specifications::is_description(spec) == FALSE) return FALSE; + return TRUE; +} + +int ExplicitActions::ap_overspecific(action_pattern *ap) { + for (ap_clause *apoc = (ap)?(ap->ap_clauses):NULL; apoc; apoc = apoc->next) + if ((APClauses::aspect(apoc) != PRIMARY_APCA) && (apoc->clause_spec)) + return TRUE; + if (APClauses::has_any_actor(ap)) return TRUE; + if (ap->duration) return TRUE; + return FALSE; +} diff --git a/inform7/if-module/Chapter 4/Named Action Patterns.w b/inform7/if-module/Chapter 4/Named Action Patterns.w index b66fc2a04..85fd5ccfe 100644 --- a/inform7/if-module/Chapter 4/Named Action Patterns.w +++ b/inform7/if-module/Chapter 4/Named Action Patterns.w @@ -60,7 +60,7 @@ void NamedActionPatterns::add(action_pattern *ap, wording W) { named_action_pattern *NamedActionPatterns::by_name(wording W) { parse_node *p = Lexicon::retrieve(NAMED_AP_MC, W); - if (p) return Rvalues::to_named_action_pattern(p); + if (p) return ARvalues::to_named_action_pattern(p); return NULL; } @@ -70,7 +70,7 @@ named_action_pattern *NamedActionPatterns::new(wording W) { nap->text_of_declaration = W; nap->compilation_data = RTNamedActionPatterns::new(nap); nap->as_noun = Nouns::new_proper_noun(W, NEUTER_GENDER, ADD_TO_LEXICON_NTOPT, - NAMED_AP_MC, Rvalues::from_named_action_pattern(nap), Task::language_of_syntax()); + NAMED_AP_MC, ARvalues::from_named_action_pattern(nap), Task::language_of_syntax()); return nap; } diff --git a/inform7/if-module/Chapter 4/Parse Action Patterns.w b/inform7/if-module/Chapter 4/Parse Action Patterns.w index 50b0bebc8..ab7e23ee0 100644 --- a/inform7/if-module/Chapter 4/Parse Action Patterns.w +++ b/inform7/if-module/Chapter 4/Parse Action Patterns.w @@ -2,6 +2,31 @@ Turning text into APs. +@ Action patterns, such as "taking a container" or "opening a closed door", +are wrapped up as values here: + += + internal { + if (Wordings::mismatched_brackets(W)) { ==> { fail nonterminal }; } + if (Lexer::word(Wordings::first_wn(W)) == OPENBRACE_V) { ==> { fail nonterminal }; } + int pto = permit_trying_omission; + if ((Wordings::first_word(W)) == FALSE) permit_trying_omission = TRUE; + int r = (W); + permit_trying_omission = pto; + if (r) { + action_pattern *ap = <>; + if ((APClauses::get_val(ap, ACTOR_AP_CLAUSE)) && + (Dash::validate_parameter(APClauses::get_val(ap, ACTOR_AP_CLAUSE), K_person) == FALSE)) { + r = (W); + } + } + if (r) { + ==> { -, AConditions::new_action_TEST_VALUE(<>, W) }; + return TRUE; + } + ==> { fail nonterminal }; +} + @ When we parse action patterns, we record why they fail, in order to make it easier to produce helpful error messages. (We can't simply fire off errors at the time they occur, because text is often parsed in several @@ -686,7 +711,7 @@ description. && (K_understanding) && (Kinds::eq(ActionSemantics::kind_of_second(ActionNameLists::action(entry)), K_understanding)) && ((ActionNameLists::par(entry, 1)))) { - parse_node *val = Rvalues::from_grammar_verb(NULL); /* Why no GV here? */ + parse_node *val = ARvalues::from_grammar_verb(NULL); /* Why no GV here? */ Node::set_text(val, ActionNameLists::par(entry, 1)); APClauses::set_val(&trial_ap, SECOND_AP_CLAUSE, val); } else { diff --git a/inform7/if-module/Chapter 5/Grammar Tokens.w b/inform7/if-module/Chapter 5/Grammar Tokens.w index ac3bfb4a7..ec25a9e82 100644 --- a/inform7/if-module/Chapter 5/Grammar Tokens.w +++ b/inform7/if-module/Chapter 5/Grammar Tokens.w @@ -387,7 +387,7 @@ parse_node *PL::Parsing::Tokens::determine(parse_node *pn, int depth, int *score } @ = - parse_node *val = Rvalues::from_grammar_verb(<>); + parse_node *val = ARvalues::from_grammar_verb(<>); spec = PL::Parsing::Verbs::determine(<>, depth+1); /* this is where Phase II recurses */ Node::set_grammar_value(pn, val); @@ -1245,7 +1245,7 @@ kind *PL::Parsing::Tokens::compile(gpr_kit *gprk, parse_node *pn, int code_mode, } else { if (Node::is(spec, CONSTANT_NT)) { if ((K_understanding) && (Rvalues::is_CONSTANT_of_kind(spec, K_understanding))) { - gv = Rvalues::to_grammar_verb(spec); + gv = ARvalues::to_grammar_verb(spec); if (code_mode) { Produce::inv_primitive(Emit::tree(), STORE_BIP); Produce::down(Emit::tree()); diff --git a/inform7/if-module/Chapter 5/Parsing Plugin.w b/inform7/if-module/Chapter 5/Parsing Plugin.w index bf21b485d..7a5375ba7 100644 --- a/inform7/if-module/Chapter 5/Parsing Plugin.w +++ b/inform7/if-module/Chapter 5/Parsing Plugin.w @@ -12,6 +12,7 @@ void ParsingPlugin::start(void) { PluginManager::plug(PRODUCTION_LINE_PLUG, ParsingPlugin::production_line); PluginManager::plug(MAKE_SPECIAL_MEANINGS_PLUG, ParsingPlugin::make_special_meanings); + PluginManager::plug(COMPARE_CONSTANT_PLUG, ParsingPlugin::compare_CONSTANT); PluginManager::plug(NEW_VARIABLE_NOTIFY_PLUG, ParsingPlugin::new_variable_notify); PluginManager::plug(NEW_SUBJECT_NOTIFY_PLUG, ParsingPlugin::new_subject_notify); PluginManager::plug(NEW_PERMISSION_NOTIFY_PLUG, Visibility::new_permission_notify); @@ -56,6 +57,21 @@ int ParsingPlugin::new_subject_notify(inference_subject *subj) { return FALSE; } +@ + += +int ParsingPlugin::compare_CONSTANT(parse_node *spec1, parse_node *spec2, int *rv) { + kind *K = Node::get_kind_of_value(spec1); + if (Kinds::eq(K, K_understanding)) { + if (ARvalues::to_grammar_verb(spec1) == ARvalues::to_grammar_verb(spec2)) { + *rv = TRUE; + } + *rv = FALSE; + return TRUE; + } + return FALSE; +} + @ A number of global variables are given special treatment here, including a whole family with names like "the K understood", for different kinds K. This is an awkward contrivance to bridge Inform 7, which is typed, with the diff --git a/inform7/if-module/Contents.w b/inform7/if-module/Contents.w index 0ee153b8d..647d1db64 100644 --- a/inform7/if-module/Contents.w +++ b/inform7/if-module/Contents.w @@ -39,12 +39,15 @@ Chapter 4: Actions "Actions are impulses to do something within the simulated world." Actions Plugin Actions-Only Nodes and Annotations + Action Kinds + Action Conditions Actions Action Semantics Action Variables Action Name Names Action Name Lists Action Patterns + Explicit Actions Action Pattern Clauses Going Parse Action Patterns diff --git a/inform7/imperative-module/Chapter 4/Chronology.w b/inform7/imperative-module/Chapter 4/Chronology.w index f90038d3d..751adef20 100644 --- a/inform7/imperative-module/Chapter 4/Chronology.w +++ b/inform7/imperative-module/Chapter 4/Chronology.w @@ -188,8 +188,9 @@ void Chronology::compile_past_tense_condition(value_holster *VH, parse_node *spe #ifdef IF_MODULE action_pattern *ap = NULL; - if (Node::is(spec, TEST_VALUE_NT)) ap = Rvalues::to_action_pattern(spec->down); + if (AConditions::is_action_TEST_VALUE(spec)) ap = ActionPatterns::action_from_TEST(spec); if ((ap) && (tense != IS_TENSE)) { +LOG("Here we go! $A\n", ap); if ((duration) && (Occurrence::units(duration) == TIMES_UNIT) && (Occurrence::length(duration) >= 2)) { StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_NoMoreRonNewcombMoment), "a condition like 'we have X', where X is an action, has either " diff --git a/inform7/imperative-module/Chapter 6/Parse Invocations.w b/inform7/imperative-module/Chapter 6/Parse Invocations.w index d7090c0d0..7d8d4752b 100644 --- a/inform7/imperative-module/Chapter 6/Parse Invocations.w +++ b/inform7/imperative-module/Chapter 6/Parse Invocations.w @@ -344,7 +344,7 @@ void Phrases::Parser::parse_within_inv(parse_node *inv) { @ = if ((XW)) - as_parsed = Conditions::new_TEST_ACTION(<>, XW); + as_parsed = AConditions::new_action_TEST_VALUE(<>, XW); else { permit_trying_omission = FALSE; @; diff --git a/inform7/runtime-module/Chapter 5/Action Patterns.w b/inform7/runtime-module/Chapter 5/Action Patterns.w index ad67b2bd9..b3712a8c3 100644 --- a/inform7/runtime-module/Chapter 5/Action Patterns.w +++ b/inform7/runtime-module/Chapter 5/Action Patterns.w @@ -356,9 +356,10 @@ void RTActionPatterns::emit_pattern_match(action_pattern ap, int naming_mode) { void RTActionPatterns::compile_pattern_match(value_holster *VH, action_pattern ap, int naming_mode) { int cpm_count = 0, needed[MAX_CPM_CLAUSES]; ap_clause *needed_apoc[MAX_CPM_CLAUSES]; - LOGIF(ACTION_PATTERN_COMPILATION, "Compiling action pattern:\n $A", &ap); + LOGIF(ACTION_PATTERN_COMPILATION, "Compiling action pattern:\n $A\n", &ap); if (ap.duration) { + LOGIF(ACTION_PATTERN_COMPILATION, "As past action\n"); Chronology::compile_past_action_pattern(VH, ap.duration, ap); } else { kind *kind_of_noun = K_object; diff --git a/inform7/runtime-module/Chapter 5/Actions.w b/inform7/runtime-module/Chapter 5/Actions.w index ecd7dac0d..5541ef517 100644 --- a/inform7/runtime-module/Chapter 5/Actions.w +++ b/inform7/runtime-module/Chapter 5/Actions.w @@ -350,7 +350,7 @@ int RTActions::actions_compile_constant(value_holster *VH, kind *K, parse_node * if (PluginManager::active(actions_plugin) == FALSE) internal_error("actions plugin inactive"); if (Kinds::eq(K, K_action_name)) { - action_name *an = Rvalues::to_action_name(spec); + action_name *an = ARvalues::to_action_name(spec); if (Holsters::data_acceptable(VH)) { inter_name *N = RTActions::iname(an); if (N) Emit::holster(VH, N); diff --git a/inform7/values-module/Chapter 2/Conditions.w b/inform7/values-module/Chapter 2/Conditions.w index 2413c2a50..37d2bc517 100644 --- a/inform7/values-module/Chapter 2/Conditions.w +++ b/inform7/values-module/Chapter 2/Conditions.w @@ -101,44 +101,6 @@ parse_node *Conditions::new_TEST_PHRASE_OPTION(int opt_num) { return spec; } -@ = -#ifdef IF_MODULE -parse_node *Conditions::new_TEST_ACTION(action_pattern *ap, wording W) { - if (ap == NULL) internal_error("null action pattern"); - parse_node *spec = Node::new_with_words(TEST_VALUE_NT, W); - spec->down = Rvalues::from_action_pattern(ap); - Node::set_text(spec->down, W); - return spec; -} -#endif -#ifndef IF_MODULE -parse_node *Conditions::new_TEST_ACTION(void *ap, wording W) { - internal_error("can't make test action without IF module"); - return NULL; -} -#endif - -int Conditions::is_TEST_ACTION(parse_node *spec) { - #ifdef IF_MODULE - if ((Node::is(spec, TEST_VALUE_NT)) && - ((Rvalues::to_action_pattern(spec->down)) || - (Rvalues::to_explicit_action(spec->down)))) return TRUE; - #endif - return FALSE; -} - -parse_node *Conditions::action_tested(parse_node *spec) { - #ifdef IF_MODULE - if (Conditions::is_TEST_ACTION(spec) == FALSE) - internal_error("action improperly extracted"); - return spec->down; - #endif - #ifndef IF_MODULE - internal_error("can't perform action_tested without IF module"); - return NULL; - #endif -} - @ Since, in principle, any condition might also have a time period attached to it, we need a follow-up routine to attach this as necessary to a newly created condition: @@ -264,10 +226,15 @@ void Conditions::compile(value_holster *VH, parse_node *spec_found) { case LOGICAL_NOT_NT: @; break; case LOGICAL_AND_NT: case LOGICAL_OR_NT: @; break; case TEST_VALUE_NT: { - if (Conditions::is_TEST_ACTION(spec_found)) { + if (AConditions::is_action_TEST_VALUE(spec_found)) { #ifdef IF_MODULE - action_pattern *ap = Rvalues::to_action_pattern( - Conditions::action_tested(spec_found)); + action_pattern *ap = ARvalues::to_action_pattern( + AConditions::action_tested(spec_found)); + if (ap == NULL) { + explicit_action *ea = Node::get_constant_explicit_action(AConditions::action_tested(spec_found)); + if (ea) ap = ea->as_described; + } + if (ap == NULL) internal_error("no action pattern to test"); RTActionPatterns::compile_pattern_match(VH, *ap, FALSE); #endif } else if (Specifications::is_description(spec_found)) { diff --git a/inform7/values-module/Chapter 2/Dash.w b/inform7/values-module/Chapter 2/Dash.w index f55fb8ed3..e0dae0059 100644 --- a/inform7/values-module/Chapter 2/Dash.w +++ b/inform7/values-module/Chapter 2/Dash.w @@ -2916,17 +2916,15 @@ action value, which is a specific action. @ = LOG_DASH("(5.d.1)"); - LOGIF(MATCHING, "Kind expected %u; ista %d cond %d\n", kind_expected, Conditions::is_TEST_ACTION(p), condition_context); - if ((Conditions::is_TEST_ACTION(p)) && (kind_expected) && + if ((AConditions::is_action_TEST_VALUE(p)) && (kind_expected) && (Kinds::compatible(K_stored_action, kind_expected))) { -LOGIF(MATCHING, "Madeit\n"); explicit_action *ea = Node::get_constant_explicit_action(p->down); if (ea == NULL) { action_pattern *ap = Node::get_constant_action_pattern(p->down); int failure_code = 0; - ea = ActionPatterns::to_explicit_action(ap, &failure_code); + ea = ExplicitActions::from_action_pattern(ap, &failure_code); - if (failure_code == 1) { + if (failure_code == UNDERSPECIFIC_EA_FAILURE) { THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM; Problems::quote_source(1, current_sentence); Problems::quote_wording(2, Node::get_text(p)); @@ -2939,7 +2937,7 @@ LOGIF(MATCHING, "Madeit\n"); Problems::issue_problem_end(); return NEVER_MATCH; } - if (failure_code == 2) { + if (failure_code == OVERSPECIFIC_EA_FAILURE) { THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM; Problems::quote_source(1, current_sentence); Problems::quote_wording(2, Node::get_text(p)); diff --git a/inform7/values-module/Chapter 2/Rvalues.w b/inform7/values-module/Chapter 2/Rvalues.w index 12444649f..8e13c2498 100644 --- a/inform7/values-module/Chapter 2/Rvalues.w +++ b/inform7/values-module/Chapter 2/Rvalues.w @@ -29,29 +29,6 @@ pointers: return spec; = -#ifdef IF_MODULE -parse_node *Rvalues::from_action_name(action_name *val) { - CONV_FROM(action_name, K_action_name) } -parse_node *Rvalues::from_action_pattern(action_pattern *val) { - int failure_code = 0; - explicit_action *ea = ActionPatterns::to_explicit_action(val, &failure_code); - if (ea) { - parse_node *spec = Node::new(CONSTANT_NT); - Node::set_kind_of_value(spec, K_stored_action); - Node::set_constant_action_pattern(spec, val); - Node::set_constant_explicit_action(spec, ea); - return spec; - } else { - CONV_FROM(action_pattern, K_description_of_action); - } -} -parse_node *Rvalues::from_grammar_verb(grammar_verb *val) { - CONV_FROM(grammar_verb, K_understanding) } -parse_node *Rvalues::from_named_action_pattern(named_action_pattern *val) { - CONV_FROM(named_action_pattern, K_nil) } -parse_node *Rvalues::from_scene(scene *val) { - CONV_FROM(scene, K_scene) } -#endif parse_node *Rvalues::from_activity(activity *val) { CONV_FROM(activity, Activities::to_kind(val)) } parse_node *Rvalues::from_binary_predicate(binary_predicate *val) { @@ -85,20 +62,6 @@ parse_node *Rvalues::from_verb_form(verb_form *val) { return val; = -#ifdef IF_MODULE -action_name *Rvalues::to_action_name(parse_node *spec) { - CONV_TO(action_name) } -action_pattern *Rvalues::to_action_pattern(parse_node *spec) { - CONV_TO(action_pattern) } -explicit_action *Rvalues::to_explicit_action(parse_node *spec) { - CONV_TO(explicit_action) } -grammar_verb *Rvalues::to_grammar_verb(parse_node *spec) { - CONV_TO(grammar_verb) } -named_action_pattern *Rvalues::to_named_action_pattern(parse_node *spec) { - CONV_TO(named_action_pattern) } -scene *Rvalues::to_scene(parse_node *spec) { - CONV_TO(scene) } -#endif activity *Rvalues::to_activity(parse_node *spec) { CONV_TO(activity) } binary_predicate *Rvalues::to_binary_predicate(parse_node *spec) { @@ -471,11 +434,9 @@ int Rvalues::compare_CONSTANT(parse_node *spec1, parse_node *spec2) { KCOMPARE_CONSTANTS(rulebook_outcome, named_rulebook_outcome) KCOMPARE_CONSTANTS(table, table) KCOMPARE_CONSTANTS(use_option, use_option) - #ifdef IF_MODULE - KCOMPARE_CONSTANTS(action_name, action_name) - KCOMPARE_CONSTANTS(scene, scene) - KCOMPARE_CONSTANTS(understanding, grammar_verb) - #endif + int rv = NOT_APPLICABLE; + PluginCalls::compare_constant(spec1, spec2, &rv); + if (rv != NOT_APPLICABLE) return rv; } } return FALSE; diff --git a/inform7/values-module/Chapter 3/Literal Lists.w b/inform7/values-module/Chapter 3/Literal Lists.w index 2b47761dd..9273ab96e 100644 --- a/inform7/values-module/Chapter 3/Literal Lists.w +++ b/inform7/values-module/Chapter 3/Literal Lists.w @@ -141,7 +141,7 @@ kind *Lists::kind_of_ll(literal_list *ll, int issue_problems) { for (lle = ll->first_llist_entry; lle; lle = lle->next_llist_entry) { parse_node *spec = lle->llist_entry_value; if (!Node::is(spec, UNKNOWN_NT)) { - if (Conditions::is_TEST_ACTION(spec)) + if (AConditions::is_action_TEST_VALUE(spec)) Dash::check_value_silently(spec, K_stored_action); else Dash::check_value_silently(spec, NULL); diff --git a/inform7/values-module/Chapter 4/Conditions and Phrases.w b/inform7/values-module/Chapter 4/Conditions and Phrases.w index bec17a6a8..127a87677 100644 --- a/inform7/values-module/Chapter 4/Conditions and Phrases.w +++ b/inform7/values-module/Chapter 4/Conditions and Phrases.w @@ -52,8 +52,8 @@ following implements this as a hand-coded nonterminal instead. parse_node *atomic_cnd = <>; parse_node *spec = atomic_cnd; if (Node::is(spec, CONSTANT_NT)) { - action_pattern *ap = Rvalues::to_action_pattern(spec); - spec = Conditions::new_TEST_ACTION(ap, W); + action_pattern *ap = ARvalues::to_action_pattern(spec); + spec = AConditions::new_action_TEST_VALUE(ap, W); } ==> { -, Conditions::attach_historic_requirement(spec, tp) }; return TRUE; @@ -165,10 +165,10 @@ is handled. The following nonterminal exists to enter the AP to the meaning list = ::= - ==> { -, Conditions::new_TEST_ACTION(RP[1], W) } + ==> { -, AConditions::new_action_TEST_VALUE(RP[1], W) } ::= - ==> { -, Conditions::new_TEST_ACTION(RP[1], W) } + ==> { -, AConditions::new_action_TEST_VALUE(RP[1], W) } @ And similarly: @@ -190,7 +190,7 @@ is handled. The following nonterminal exists to enter the AP to the meaning list "too much information about past events."); return FALSE; } - parse_node *C = Conditions::new_TEST_ACTION(ap, W); + parse_node *C = AConditions::new_action_TEST_VALUE(ap, W); C = Conditions::attach_tense(C, HASBEEN_TENSE); ==> { -, C }; #endif diff --git a/inform7/values-module/Chapter 4/Enter the S-Parser.w b/inform7/values-module/Chapter 4/Enter the S-Parser.w index e22c40bea..fac3e30b5 100644 --- a/inform7/values-module/Chapter 4/Enter the S-Parser.w +++ b/inform7/values-module/Chapter 4/Enter the S-Parser.w @@ -174,7 +174,7 @@ These are meaningful only for interactive fiction, and serve the "if" module: if (Rvalues::is_CONSTANT_of_kind(S, K_stored_action)) { ==> { -, S }; return TRUE; - } else if (Conditions::is_TEST_ACTION(S)) { + } else if (AConditions::is_action_TEST_VALUE(S)) { ==> { -, S->down }; return TRUE; } else { @@ -199,7 +199,7 @@ These are meaningful only for interactive fiction, and serve the "if" module: if (Rvalues::is_CONSTANT_of_kind(S, K_stored_action)) { ==> { -, S }; return TRUE; - } else if (Conditions::is_TEST_ACTION(S)) { + } else if (AConditions::is_action_TEST_VALUE(S)) { ==> { -, S->down }; return TRUE; } else { diff --git a/inform7/values-module/Chapter 4/Type Expressions and Values.w b/inform7/values-module/Chapter 4/Type Expressions and Values.w index 3c1a59a25..0b4ed9516 100644 --- a/inform7/values-module/Chapter 4/Type Expressions and Values.w +++ b/inform7/values-module/Chapter 4/Type Expressions and Values.w @@ -494,31 +494,3 @@ parse_node *SPType::arg(parse_node *val) { if (val == NULL) return Specifications::new_UNKNOWN(EMPTY_WORDING); return Node::duplicate(val); } - -@ Action patterns, such as "taking a container" or "opening a closed door", -are parsed by code in the chapter on Actions; all we do here is to wrap the -result. - -= - internal { - #ifdef IF_MODULE - if (Wordings::mismatched_brackets(W)) { ==> { fail nonterminal }; } - if (Lexer::word(Wordings::first_wn(W)) == OPENBRACE_V) { ==> { fail nonterminal }; } - int pto = permit_trying_omission; - if ((Wordings::first_word(W)) == FALSE) permit_trying_omission = TRUE; - int r = (W); - permit_trying_omission = pto; - if (r) { - action_pattern *ap = <>; - if ((APClauses::get_val(ap, ACTOR_AP_CLAUSE)) && - (Dash::validate_parameter(APClauses::get_val(ap, ACTOR_AP_CLAUSE), K_person) == FALSE)) { - r = (W); - } - } - if (r) { - ==> { -, Conditions::new_TEST_ACTION(<>, W) }; - return TRUE; - } - #endif - ==> { fail nonterminal }; -} diff --git a/services/calculus-module/Chapter 5/Simplifications.w b/services/calculus-module/Chapter 5/Simplifications.w index 7b6a3e7eb..20a9ad33e 100644 --- a/services/calculus-module/Chapter 5/Simplifications.w +++ b/services/calculus-module/Chapter 5/Simplifications.w @@ -959,9 +959,9 @@ pcalc_prop *Simplifications::convert_gerunds(pcalc_prop *prop, int *changed) { TRAVERSE_PROPOSITION(pl, prop) if ((pl->element == PREDICATE_ATOM) && (pl->arity == 2)) for (int i=0; i<2; i++) - if (Conditions::is_TEST_ACTION(pl->terms[i].constant)) + if (AConditions::is_action_TEST_VALUE(pl->terms[i].constant)) pl->terms[i].constant = - Conditions::action_tested(pl->terms[i].constant); + AConditions::action_tested(pl->terms[i].constant); return prop; } #endif