@@ -2536,7 +2527,7 @@ can also be used adjectivally.
voidAssertions::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:
-voidAssertions::Assemblies::name_object_after(inference_subject *infs, inference_subject *after, wordingW) {
+voidAssertions::Assemblies::name_object_after(inference_subject *infs, inference_subject *after, wordingW) {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);}
-voidAssertions::PropertyKnowledge::assert_property_list(parse_node *owner_subtree,
+voidAssertions::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.
-voidRefiner::give_subject_to_noun(parse_node *p, inference_subject *infs) {
+voidRefiner::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;}
-voidRefiner::give_spec_to_noun(parse_node *p, parse_node *eval) {
+voidRefiner::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.
#ifdefIF_MODULEif (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) {
§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."
§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 =
-
§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 =
§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.
§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".
§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 =
§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;
§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.
§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.
@@ -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\".')");
@@ -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);
@@ -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);
@@ -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.");
@@ -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.");
@@ -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();
@@ -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.");
§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 =
@@ -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);
@@ -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());
§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());
§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);
@@ -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);
§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.)");
§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();
§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
§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.)
defineMAX_DUPLICATES_AT_ONCE100 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 =
§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 =
§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 =
§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>
-intAssertions::Creator::vet_name_for_noun(wordingW) {
+intAssertions::Creator::vet_name_for_noun(wordingW) {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.
returnTRUE;}
-
§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.
§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);}
-
§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.
+
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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.
+
§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);}
-
§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 I1PLUGINS_CALL(MORE_SPECIFIC_PLUG, I1, I2);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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);}
-
§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 }returnFALSE;}
+
+intScenes::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;
+returnTRUE;
+ }
+returnFALSE;
+}
§6. scene structures are automatically created whenever a new instance of the
kind "scene" is created, and this is where that happens.
-intScenes::new_named_instance_notify(instance *I) {
+intScenes::new_named_instance_notify(instance *I) {if ((K_scene) && (Kinds::eq(Instances::to_kind(I), K_scene))) {Scenes::new_scene(I);returnTRUE;
@@ -173,7 +186,7 @@ Standard Rules. (So there is no need to translate this to other languages.)
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:
-scene *Scenes::from_named_constant(instance *I) {
+scene *Scenes::from_named_constant(instance *I) {if (K_scene == NULL) returnNULL;kind *K = Instances::to_kind(I);if (Kinds::eq(K, K_scene)) returnPLUGIN_DATA_ON_SUBJECT(scenes, I->as_subject);
@@ -299,7 +312,7 @@ to translate this to other languages.)
§14. Creating and parsing ends.
-intScenes::parse_scene_end_name(scene *sc, wordingEW, intcreate) {
+intScenes::parse_scene_end_name(scene *sc, wordingEW, intcreate) {for (inti=2; i<sc->no_ends; i++)if (Wordings::match(EW, sc->ends[i].end_names))returni;
@@ -333,7 +346,7 @@ to translate this to other languages.)
§15. Scene end rulebooks.
-voidScenes::new_scene_rulebook(scene *sc, intend) {
+voidScenes::new_scene_rulebook(scene *sc, intend) {wordingRW = 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:
+
+
+
+
+
+
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(wordingW) {
+action_name *PL::Actions::act_new(wordingW) {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 }
§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.
+
§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.
+
§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.
+
§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.
+
-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");returnan;
@@ -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) {intposn = -1, best_score = -1;action_name *best = NULL;if (ActionNameLists::positive(list) == FALSE) returnNULL;
@@ -616,7 +616,7 @@ something other than something — or intanl_parsing_tense = IS_TENSE;
-action_name_list *ActionNameLists::parse(wordingW, inttense, int *sense) {
+action_name_list *ActionNameLists::parse(wordingW, inttense, int *sense) {if (Wordings::mismatched_brackets(W)) returnNULL;intt = anl_parsing_tense;anl_parsing_tense = tense;
@@ -905,7 +905,7 @@ the trial entry for future trials.
§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.
-voidActionNameNames::set_irregular_past(action_name *an, wordingC) {
+voidActionNameNames::set_irregular_past(action_name *an, wordingC) {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.
-wordingActionNameNames::tensed(action_name *an, inttense) {
+wordingActionNameNames::tensed(action_name *an, inttense) {if (tense == IS_TENSE) returnan->naming_data.present_name;if (tense == HASBEEN_TENSE) returnan->naming_data.past_name;internal_error("action tense unsupported");
@@ -215,7 +215,7 @@ preposition can be abbreviated is under the author's control:
returnan->naming_data.it_optional;}
-voidActionNameNames::make_abbreviable(action_name *an) {
+voidActionNameNames::make_abbreviable(action_name *an) {an->naming_data.abbreviable = TRUE;}
@@ -304,7 +304,7 @@ number of words.
-action_name *ActionNameNames::longest_nounless(wordingW, inttense, int *posn) {
+action_name *ActionNameNames::longest_nounless(wordingW, inttense, 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.
+
§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".
-
§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:
-voidActionsPlugin::notice_new_action_name(action_name *an) {
+voidActionsPlugin::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:
returnwaiting_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:
§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:
§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
§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)); }
§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.
§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
@@ -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.");
§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".
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".
intvalid; 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_patternActionPatterns::new(void) {
+action_patternActionPatterns::new(void) {action_patternap;ap.ap_clauses = NULL;ap.text_of_pattern = EMPTY_WORDING;
@@ -119,21 +119,11 @@ object instead of an action — "reaching inside the cabinet".
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.
-voidActionSemantics::give_action_an_optional_noun(action_name *an, intacc, kind *K) {
+voidActionSemantics::give_action_an_optional_noun(action_name *an, intacc, kind *K) {an->semantics.min_parameters = 0;an->semantics.max_parameters = 1;an->semantics.noun_access = acc;an->semantics.noun_kind = K;}
-voidActionSemantics::give_action_one_noun(action_name *an, intacc, kind *K) {
+voidActionSemantics::give_action_one_noun(action_name *an, intacc, kind *K) {an->semantics.min_parameters = 1;an->semantics.max_parameters = 1;an->semantics.noun_access = acc;an->semantics.noun_kind = K;}
-voidActionSemantics::give_action_two_nouns(action_name *an, intacc1, kind *K1,
+voidActionSemantics::give_action_two_nouns(action_name *an, intacc1, kind *K1,intacc2, 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.");}
-voidActionSemantics::make_action_out_of_world(action_name *an) {
+voidActionSemantics::make_action_out_of_world(action_name *an) {an->semantics.out_of_world = TRUE;}
-voidActionSemantics::make_action_require_light(action_name *an) {
+voidActionSemantics::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.
-intActionSemantics::can_have_noun(action_name *an) {
+intActionSemantics::can_have_noun(action_name *an) {if (an->semantics.max_parameters >= 1) returnTRUE;returnFALSE;}
-intActionSemantics::can_have_second(action_name *an) {
+intActionSemantics::can_have_second(action_name *an) {if (an->semantics.max_parameters >= 2) returnTRUE;returnFALSE;}
-intActionSemantics::must_have_noun(action_name *an) {
+intActionSemantics::must_have_noun(action_name *an) {if (an->semantics.min_parameters >= 1) returnTRUE;returnFALSE;}
-intActionSemantics::must_have_second(action_name *an) {
+intActionSemantics::must_have_second(action_name *an) {if (an->semantics.min_parameters >= 2) returnTRUE;returnFALSE;}
@@ -214,7 +214,7 @@ preferred way to do that is to use activities for selecting missing parameters.
returnFALSE;}
-intActionSemantics::is_out_of_world(action_name *an) {
+intActionSemantics::is_out_of_world(action_name *an) {if (an->semantics.out_of_world) returnTRUE;returnFALSE;}
@@ -227,11 +227,11 @@ preferred way to do that is to use activities for selecting missing parameters.
returnan->semantics.second_access;}
-kind *ActionSemantics::kind_of_noun(action_name *an) {
+kind *ActionSemantics::kind_of_noun(action_name *an) {returnan->semantics.noun_kind;}
-kind *ActionSemantics::kind_of_second(action_name *an) {
+kind *ActionSemantics::kind_of_second(action_name *an) {returnan->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:
intActionVariables::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:
§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.
+
@@ -198,7 +198,7 @@ function togglePopup(material_id) {
§5.
-intGoing::check(action_pattern *ap) {
+intGoing::check(action_pattern *ap) {if (Going::check_clause(APClauses::get_val(ap, GOING_FROM_AP_CLAUSE), "from",K_room, K_region) == FALSE) returnFALSE;if (Going::check_clause(APClauses::get_val(ap, GOING_TO_AP_CLAUSE), "to",
@@ -249,20 +249,20 @@ function togglePopup(material_id) {
returnFALSE;}
-voidGoing::go_nowhere(action_pattern *ap) {
+voidGoing::go_nowhere(action_pattern *ap) {APClauses::set_val(ap, GOING_TO_AP_CLAUSE, Rvalues::new_nothing_object_constant());}
-voidGoing::go_somewhere(action_pattern *ap) {
+voidGoing::go_somewhere(action_pattern *ap) {APClauses::set_val(ap, GOING_TO_AP_CLAUSE, Descriptions::from_kind(K_room, FALSE));}
-intGoing::going_nowhere(action_pattern *ap) {
+intGoing::going_nowhere(action_pattern *ap) {if (Rvalues::is_nothing_object_constant(APClauses::get_val(ap, GOING_TO_AP_CLAUSE))) returnTRUE;returnFALSE;}
-intGoing::going_somewhere(action_pattern *ap) {
+intGoing::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)))returnTRUE;
@@ -296,7 +296,7 @@ to make sure it actually exists. So this can be used to see if the need arises:
§8.
-intGoing::claim_noun(action_name *an, action_pattern *ap, wordingW) {
+intGoing::claim_noun(action_name *an, action_pattern *ap, wordingW) {if ((an == going_action) && (<going-action-irregular-operand>(W))) {if (<<r>> == FALSE) Going::go_nowhere(ap);elseGoing::go_somewhere(ap);
@@ -306,7 +306,7 @@ to make sure it actually exists. So this can be used to see if the need arises:
}
§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".
intpap_failure_reason; one of the aboveintpermit_trying_omission = FALSE; allow the keyword 'trying' to be omittedintpermit_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_patternParseActionPatterns::parametric(wordingW, kind *K) {action_patternap = 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);returnap;}
-
§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(wordingW) {
+parse_node *ParseActionPatterns::parameter(wordingW) {if (<action-parameter>(W)) return<<rp>>;returnSpecifications::new_UNKNOWN(W);}parse_node *ParseActionPatterns::verified_action_parameter(wordingW) {
-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.
returnspec;}
-
§5.
+
§6.
intscanning_anl_only_mode = FALSE;
@@ -164,7 +191,7 @@ form the usage conditions for rules in object-based rulebooks.
returnanl;}
-
§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.
§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:
wehavenot<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:
§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;
-intold_state = ParseActionPatterns::suppress();
+intold_state = ParseActionPatterns::suppress();if (<action-parameter>(Wordings::up_to(W, i-1))) try_stem = <<rp>>;
-ParseActionPatterns::resume(old_state);
+ParseActionPatterns::resume(old_state);intk = 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".
}
§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,
§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.
doingit
-action_pattern *ParseActionPatterns::inner(wordingW, inttense) {
+action_pattern *ParseActionPatterns::inner(wordingW, inttense) {if (Lexer::word(Wordings::first_wn(W)) == OPENBRACE_V) returnNULL;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.
returnap;}
-
§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.
}
§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
§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) };
§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_patternap = ParseActionPatterns::dash(W);
+action_patternap = 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, - }
§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) gotoFailed;LOGIF(ACTION_PATTERN_PARSING, "Matched action pattern: $A\n", &ap);
§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);
§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.
§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 =
§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 =
§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 gotoFailed; }
§25. And an anticlimactic little routine for putting objects
into action patterns in the noun or second noun position.
-voidParseActionPatterns::put_action_object_into_ap(action_pattern *ap, intC, wordingW) {
+voidParseActionPatterns::put_action_object_into_ap(action_pattern *ap, intC, wordingW) {parse_node *spec = NULL;intany_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
returngv->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 recursesNode::set_grammar_value(pn, val);
§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.
personasked==> { 5, - }
§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);
§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); }
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 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.
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.
#ifdefIF_MODULEaction_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 voidRTActionPatterns::compile_pattern_match(value_holster *VH, action_patternap, intnaming_mode) {intcpm_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) {
§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.)
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:
§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.
§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.)
-intConditions::count(parse_node *spec) {
+intConditions::count(parse_node *spec) {if (spec == NULL) return0;if (Specifications::is_condition(spec) == FALSE) return1;switch (Node::get_type(spec)) {caseLOGICAL_AND_NT:
-returnConditions::count(spec->down)
- + Conditions::count(spec->down->next);
+returnConditions::count(spec->down)
+ + Conditions::count(spec->down->next);caseLOGICAL_OR_NT:return -1;caseLOGICAL_NOT_NT:
-returnConditions::count(spec->down);
+returnConditions::count(spec->down);caseLOGICAL_TENSE_NT:
-returnConditions::count(spec->down);
+returnConditions::count(spec->down);caseTEST_PROPOSITION_NT:returnPropositions::length(Specifications::to_proposition(spec));caseTEST_PHRASE_OPTION_NT:
@@ -354,7 +313,7 @@ Inform; this bit of scruffy, rather than neat, logic will have to do.)
return0;}
-
§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.
caseLOGICAL_TENSE_NT:Chronology::compile_past_tense_condition(VH, spec_found);break;
-caseLOGICAL_NOT_NT:Compile a logical negation15.1; break;
-caseLOGICAL_AND_NT:caseLOGICAL_OR_NT:Compile a logical operator15.2; break;
+caseLOGICAL_NOT_NT:Compile a logical negation14.1; break;
+caseLOGICAL_AND_NT:caseLOGICAL_OR_NT:Compile a logical operator14.2; break;caseTEST_VALUE_NT: {
-if (Conditions::is_TEST_ACTION(spec_found)) {
+if (AConditions::is_action_TEST_VALUE(spec_found)) { #ifdefIF_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 } elseif (Specifications::is_description(spec_found)) {
@@ -387,14 +351,14 @@ of brackets never does any harm; so we always compile one.
}break; }
-caseTEST_PHRASE_OPTION_NT:Compile a phrase option test15.3; break;
+caseTEST_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());
§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());
§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());
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.
-voidDescriptions::write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
+voidDescriptions::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.
§8. And similarly:
@@ -303,8 +303,8 @@ conditions, so this is where the condition in
"too much information about past events.");returnFALSE; }
-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 #ifndefIF_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 };returnTRUE;
- } elseif (Conditions::is_TEST_ACTION(S)) {
+ } elseif (AConditions::is_action_TEST_VALUE(S)) { ==> { -, S->down };returnTRUE; } 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 };returnTRUE;
- } elseif (Conditions::is_TEST_ACTION(S)) {
+ } elseif (AConditions::is_action_TEST_VALUE(S)) { ==> { -, S->down };returnTRUE; } 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.
returnNode::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.
-