The structure use_option is accessed in 3/dbtr, 3/rpr, 4/ass, 5/tpf, 6/tc, 6/tbl, 6/eqt and here.
+
The structure use_option is accessed in 3/dbtr, 3/rpr, 4/ass, 5/tpf, 5/po, 6/tc, 6/tbl, 6/eqt and here.
§3.2. Create a new use option3.2 =
diff --git a/docs/assertions-module/5-adf.html b/docs/assertions-module/5-adf.html
index 5800bdd95..e4dae31b1 100644
--- a/docs/assertions-module/5-adf.html
+++ b/docs/assertions-module/5-adf.html
@@ -185,7 +185,7 @@ container (called the sack) is capacious if...".
}
diff --git a/docs/assertions-module/5-id.html b/docs/assertions-module/5-id.html
index 6dfbfcff6..8c66a49c7 100644
--- a/docs/assertions-module/5-id.html
+++ b/docs/assertions-module/5-id.html
@@ -276,7 +276,6 @@ Inform 7 source text written underneath the heading.
typedefstructid_body {structimperative_defn *head_of_defn;structid_type_datatype_data;
-structid_options_dataoptions_data;structid_runtime_context_dataruntime_context_data;structid_compilation_datacompilation_data;CLASS_DEFINITION
@@ -286,14 +285,13 @@ Inform 7 source text written underneath the heading.
LOGIF(PHRASE_CREATIONS, "Creating body: <%W>\n", id->log_text);id_body *body = CREATE(id_body);body->head_of_defn = id;
-body->options_data = Phrases::Options::new(EMPTY_WORDING);body->runtime_context_data = Phrases::Context::new();body->type_data = IDTypeData::new();body->compilation_data = IDCompilation::new_data(id->at);returnbody;}
-
The structure id_body is accessed in 5/idf, 5/adf, 5/tpf, 5/ptd, 5/rf, 6/eqt and here.
+
The structure id_body is accessed in 5/idf, 5/adf, 5/tpf, 5/ptd, 5/po, 5/rf, 6/eqt and here.
§8. Definition bodies can be written in two different ways. In one way, the
body is a list of instructions to follow. For example:
@@ -442,7 +440,7 @@ Inter kit instead.
}
diff --git a/docs/assertions-module/5-idf.html b/docs/assertions-module/5-idf.html
index 078cd6c29..ffcb244ba 100644
--- a/docs/assertions-module/5-idf.html
+++ b/docs/assertions-module/5-idf.html
@@ -294,7 +294,7 @@ go into the Phrasebook page of the index.
}
diff --git a/docs/imperative-module/3-po.html b/docs/assertions-module/5-po.html
similarity index 65%
rename from docs/imperative-module/3-po.html
rename to docs/assertions-module/5-po.html
index 45ae94f7a..d253efce7 100644
--- a/docs/imperative-module/3-po.html
+++ b/docs/assertions-module/5-po.html
@@ -41,10 +41,10 @@ function togglePopup(material_id) {
§1. A "phrase option" is a sort of modifier tacked on to the instruction to
-do something, changing how it works but not enough to merit an entirely new
-phrase. It's like an argument passed to a routine which specifies optional
-behaviour, and indeed that will be how it is compiled.
+
§1. Introduction. A "phrase option" is a sort of modifier tacked on to an invocation of a
+phrase; the only modifiers allowed are those declared in that phrase's
+preamble. Phrase pptions are an early feature of Inform 7 going back to a
+time when its priority was to enable the paraphrasing of Inform 6 library
+features (such as the bitmap passed as a parameter to the list-printer).
-
Like the token names, phrase option names have local scope (which is why
-they are here and not in the excerpts database). Unlike them, they are not
-valid as values, since a condition is not also a value in Inform 7.
-
-
-
The packet of these associated with a phrase is stored in the PHOD structure.
-
-
-
defineMAX_OPTIONS_PER_PHRASE16 because held in a 16-bit Z-machine bitmap
-
-
-typedefstructid_options_data {
-structphrase_option *options_permitted[MAX_OPTIONS_PER_PHRASE]; see below
-intno_options_permitted;
-structwordingoptions_declaration; the text declaring the whole set of options
-intmultiple_options_permitted; can be combined, or mutually exclusive?
-} id_options_data;
-
-
The structure id_options_data is private to this section.
-
§2. There's nothing to a phrase option, really:
-
-
-
-typedefstructphrase_option {
-structwordingname; text of name
-} phrase_option;
-
-
The structure phrase_option is accessed in 2/rls, 2/fao, 2/act, 4/sv, 6/cii, 6/cste and here.
-
§3. Creation. By default, a phrase has no options.
-
§4. Parsing. This isn't very efficient, but doesn't need to be, since phrase options
-are parsed only in a condition context, not in a value context, and
-these are relatively rare in Inform source text.
-
§6. I have to say that I regret the syntax for phrase options, which makes
-us write commas like the one here:
+
I now sligjtly regret the existence of phrase options, but above all the
+comma-based syntax used for them, as here. Brackets would have been better;
+it makes phrase options impossible to use for text substitutions.
@@ -168,74 +97,153 @@ But it's mostly the comma which annoys me (making text substitutions unable
to support phrase options); I should have gone for brackets.
-
The syntax for declaring phrase options is uncontroversial — it's just
-a list of names — but there are wrinkles: if the list is divided with "or"
-then the options are mutually exclusive, but with "and/or" they're not.
-For example, in:
+
The id_options_data for an imperative definition, which is part of its
+type data, says what options it allows:
-
-
To decide which object is best route from (R1 - object) to (R2 - object), using doors or using even locked doors: ...
-
-
-
the following parses this list:
-
-
-
-
using doors or using even locked doors
-
-
-
and creates two options with <phrase-option-declaration-setting-entry>.
-
+typedefstructid_options_data {
+structphrase_option *options_permitted[MAX_OPTIONS_PER_PHRASE];
+intno_options_permitted;
+structwordingoptions_declaration; the text declaring the whole set of options
+intmultiple_options_permitted; can be combined, or mutually exclusive?
+} id_options_data;
+
+typedefstructphrase_option {
+structwordingname; text of name
+} phrase_option;
+
+
The structure id_options_data is private to this section.
The structure phrase_option is accessed in 3/nuor, 3/dbtr, 3/rpr, 4/ass, 5/tpf, 6/tc, 6/tbl, 6/eqt and here.
+
§2. Creation. By default, a phrase has no options.
-inttoo_many_POs_error = FALSE;
-voidPhrases::Options::phod_add_phrase_option(id_options_data *phod, wordingW) {
+intPM_TooManyPhraseOptions_issued = FALSE;
+voidPhraseOptions::phod_add_phrase_option(id_options_data *phod, wordingW) {LOGIF(PHRASE_CREATIONS, "Adding phrase option <%W>\n", W);if (phod->no_options_permitted >= MAX_OPTIONS_PER_PHRASE) {
-if (too_many_POs_error == FALSE)
-StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_TooManyPhraseOptions),
+if (PM_TooManyPhraseOptions_issued == FALSE)
+StandardProblems::sentence_problem(Task::syntax_tree(),
+_p_(PM_TooManyPhraseOptions),"a phrase is only allowed to have 16 different options",
-"so either some of these will need to go, or you may want to "
-"consider breaking up the phrase into simpler ones whose usage "
-"is easier to describe.");
-too_many_POs_error = TRUE;
+"so either some of these will need to go, or you may want to consider "
+"breaking up the phrase into simpler ones whose usage is easier to describe.");
+PM_TooManyPhraseOptions_issued = TRUE;return; }
-too_many_POs_error = FALSE; so that the problem can recur on later phrases
+PM_TooManyPhraseOptions_issued = FALSE; so the problem can recur on later phrasesphrase_option *po = CREATE(phrase_option);po->name = W;phod->options_permitted[phod->no_options_permitted++] = po;}
+
§4. Parsing. This isn't very efficient, but doesn't need to be, since phrase options are parsed
+only in a condition context, not in a value context, and these are relatively
+rare in Inform source text.
+
§6. Parsing phrase options in a declaration. The following is called with W set to just the part of a phrase prototype
+containing its phrase options. In this example:
+
+
+
+Todecidewhichobjectisbestroutefrom (R1 - object) to (R2 - object),
+usingdoorsorusingevenlockeddoors:
+
+
W would be "using doors or using even locked doors".
+
+
+
The syntax is just a list of names, but with the wrinkle that if the list is divided
+with "or" then the options are mutually exclusive, but with "and/or" they're not.
+
§7. Note the following Preform grammar passes the return value TRUE up from
+the final element of the list when the connective used for it was "and/or".
+Note also the rare use of the Preform literal marker in \and/or to show
+that the slash between "and" and "or" is part of the word.
+
§8. Parsing phrase options in an invocation. At this point, we're looking at the text after the first comma in something
like:
@@ -264,18 +272,18 @@ produce.
intphod_being_parsed_silently = FALSE; context for the grammar below
-intPhrases::Options::parse_invoked_options(parse_node *inv, intsilently) {
-id_body *idb = Node::get_phrase_invoked(inv);
-wordingW = Invocations::get_phrase_options(inv);
+intPhraseOptions::parse_invoked_options(parse_node *inv, intsilently) {
+id_body *idb = Node::get_phrase_invoked(inv);
+wordingW = Invocations::get_phrase_options(inv);idb_being_parsed = idb;
-phod_being_parsed = &(idb_being_parsed->options_data);
+phod_being_parsed = &(idb_being_parsed->type_data.options_data);intbitmap = 0;intpc = problem_count;
-Parse the supplied list of options into a bitmap8.1;
+Parse the supplied list of options into a bitmap8.1;
-Invocations::set_phrase_options_bitmap(inv, bitmap);
+Invocations::set_phrase_options_bitmap(inv, bitmap);if (problem_count > pc) returnFALSE;returnTRUE;}
@@ -291,11 +299,11 @@ produce.
if ((problem_count == pc) && (phod_being_parsed->multiple_options_permitted == FALSE))
-Reject this if multiple options are set8.1.1;
+Reject this if multiple options are set8.1.1;
§8.1.1. Ah, bit-twiddling: fun for all the family. There's no point computing the
-Hamming distance of the bitmap, that is, the number of bits set: we only need
+population count of the bitmap, that is, the number of bits set: we only need
to know if it's a power of 2 or not. Note that subtracting 1, in binary,
clears the least significant set bit, leaves the higher bits as they are,
and changes the lower bits (which were previously all 0s) to 1s. So taking
@@ -314,7 +322,8 @@ this residue is zero.
Problems::quote_wording(2, W);Problems::quote_phrase(3, idb);Problems::quote_wording(4, phod_being_parsed->options_declaration);
-StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_PhraseOptionsExclusive));
+StandardProblems::handmade_problem(Task::syntax_tree(),
+_p_(PM_PhraseOptionsExclusive));Problems::issue_problem_segment("You wrote %1, supplying the options '%2' to the phrase '%3', but ""the options listed for this phrase ('%4') are mutually exclusive.");
@@ -323,24 +332,24 @@ this residue is zero.
returnFALSE; }
-
§9.1. Issue PM_NotAPhraseOption or C22NotTheOnlyPhraseOption problem9.1 =
@@ -353,13 +362,15 @@ by "and":
Problems::quote_phrase(3, idb_being_parsed);Problems::quote_wording(4, phod_being_parsed->options_declaration);if (phod_being_parsed->no_options_permitted > 1) {
-StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_NotAPhraseOption));
+StandardProblems::handmade_problem(Task::syntax_tree(),
+_p_(PM_NotAPhraseOption));Problems::issue_problem_segment("You wrote %1, but '%2' is not one of the options allowed on ""the end of the phrase '%3'. (The options allowed are: '%4'.)");Problems::issue_problem_end(); } else {
-StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_NotTheOnlyPhraseOption));
+StandardProblems::handmade_problem(Task::syntax_tree(),
+_p_(PM_NotTheOnlyPhraseOption));Problems::issue_problem_segment("You wrote %1, but the only option allowed on the end of the ""phrase '%3' is '%4', so '%2' is not something I know how to "
@@ -368,21 +379,9 @@ by "and":
} }
-
diff --git a/docs/assertions-module/5-ptd.html b/docs/assertions-module/5-ptd.html
index 58dcbea13..8fe6b2a46 100644
--- a/docs/assertions-module/5-ptd.html
+++ b/docs/assertions-module/5-ptd.html
@@ -121,13 +121,15 @@ parts in brackets.
intmanner_of_return; one of the *_MOR valuesstructkind *return_kind; NULL except in the DECIDES_VALUE_MOR case
+structid_options_dataoptions_data;
+
structsay_detailsas_say; used only for "say" phrases, that is, text substitutionsstructinline_detailsas_inline; side effects for phrases like C keywordsintnow_deprecated; is this a phrase likely to be withdrawn in future?} id_type_data;
-
The structure id_type_data is accessed in 5/ptd2 and here.
+
The structure id_type_data is accessed in 5/ptd2, 5/po and here.
@@ -1102,7 +1105,7 @@ match is shown.
diff --git a/docs/assertions-module/5-ptd2.html b/docs/assertions-module/5-ptd2.html
index f7c647df0..b7d28f7fb 100644
--- a/docs/assertions-module/5-ptd2.html
+++ b/docs/assertions-module/5-ptd2.html
@@ -94,7 +94,7 @@ adjusted for an inline definition (if that's the kind of definition this is).
-voidParsingIDTypeData::parse(id_type_data *idtd, wordingXW, wording *OW) {
+voidParsingIDTypeData::parse(id_type_data *idtd, wordingXW) {intsay_flag = FALSE; is this going to be a "say" phrase?if (Wordings::nonempty(XW))
@@ -104,6 +104,7 @@ adjusted for an inline definition (if that's the kind of definition this is).
if (Wordings::nonempty(XW))XW = ParsingIDTypeData::phtd_parse_doodads(idtd, XW, &say_flag); and doodads from the back
+wordingOW = EMPTY_WORDING; the options wordingintcw = -1; word number of first commaFind the first comma outside of parentheses, if any exists1.1;if (cw >= 0) {
@@ -111,12 +112,13 @@ adjusted for an inline definition (if that's the kind of definition this is).
Does this comma presage phrase options?1.2;if (comma_presages_options) {if (say_flag) Issue a problem: say phrases aren't allowed options1.3;
- *OW = Wordings::from(XW, cw + 1);
+OW = Wordings::from(XW, cw + 1);XW = Wordings::up_to(XW, cw - 1); trim the preamble range to to the text before the comma } }idtd->registration_text = XW;ParsingIDTypeData::phtd_main_prototype(idtd);
+PhraseOptions::parse_declared_options(&(idtd->options_data), OW);}
§1.1. Find the first comma outside of parentheses, if any exists1.1 =
@@ -895,7 +897,7 @@ the hyphen, and this is sorely needed with complicated functional kinds.
}
diff --git a/docs/assertions-module/5-rf.html b/docs/assertions-module/5-rf.html
index 0057cc5e3..08b8aa424 100644
--- a/docs/assertions-module/5-rf.html
+++ b/docs/assertions-module/5-rf.html
@@ -1023,7 +1023,7 @@ any order would have done just as well.
}
diff --git a/docs/assertions-module/5-tpf.html b/docs/assertions-module/5-tpf.html
index 84521fdfe..06a98ac56 100644
--- a/docs/assertions-module/5-tpf.html
+++ b/docs/assertions-module/5-tpf.html
@@ -73,7 +73,7 @@ function togglePopup(material_id) {
§1. Introduction. This family handles definitions of "To..." phrases: Inform's equivalent of
function definitions. For example:
@@ -291,10 +291,8 @@ within rulebooks. That's a similar issue, but addressed differently elsewhere.
id_body *body = id->body_of_defn;Routines::prepare_for_requests(body);
-wordingXW = ToPhraseFamily::get_prototype_text(id);
-wordingOW = EMPTY_WORDING;
-ParsingIDTypeData::parse(&(id->body_of_defn->type_data), XW, &OW);
-Phrases::Options::parse_declared_options(&(id->body_of_defn->options_data), OW);
+ParsingIDTypeData::parse(&(id->body_of_defn->type_data),
+ToPhraseFamily::get_prototype_text(id));imperative_defn *previous_id = NULL;imperative_defn *current_id = first_in_logical_order;
@@ -581,7 +579,7 @@ own right, a functional-programming sort of device. For example:
CLASS_DEFINITION} constant_phrase;
-
The structure constant_phrase is accessed in 3/nuor, 3/dbtr, 3/rpr, 4/ass, 6/tc, 6/tbl, 6/eqt and here.
+
The structure constant_phrase is accessed in 3/nuor, 3/dbtr, 3/rpr, 4/ass, 5/po, 6/tc, 6/tbl, 6/eqt and here.
§13. Here we create a new named phrase ("doubling", say):
@@ -624,9 +622,8 @@ the following takes a patch-it-later approach.
if (cphr == NULL) returnNULL;if (global_pass_state.pass < 2) returnKinds::binary_con(CON_phrase, K_value, K_value);if (cphr->cphr_kind == NULL) {
-wordingOW = EMPTY_WORDING;id_type_dataidtd = IDTypeData::new();
-ParsingIDTypeData::parse(&idtd, cphr->associated_preamble_text, &OW);
+ParsingIDTypeData::parse(&idtd, cphr->associated_preamble_text);cphr->cphr_kind = IDTypeData::kind(&idtd); }returncphr->cphr_kind;
@@ -686,21 +683,8 @@ the following takes a patch-it-later approach.
returnbeginner;}
-
§18. Phrase option parsing. These indirections are provided so that the implementation of phrase options
-is confined to the current Chapter.
-
§3. In addition, there are some standing symbols used by all equations: the
constant "pi", for example. They're stored in this linked list:
diff --git a/docs/assertions-module/6-tc.html b/docs/assertions-module/6-tc.html
index a3a432446..211607595 100644
--- a/docs/assertions-module/6-tc.html
+++ b/docs/assertions-module/6-tc.html
@@ -115,7 +115,7 @@ in both tables.
CLASS_DEFINITION} table_column;
-
The structure table_column is accessed in 3/nuor, 3/dbtr, 3/rpr, 4/ass, 5/tpf, 6/tbl, 6/eqt and here.
+
The structure table_column is accessed in 3/nuor, 3/dbtr, 3/rpr, 4/ass, 5/tpf, 5/po, 6/tbl, 6/eqt and here.
§2. The predicate calculus engine often finds conditions equivalent to "if A
is a C listed in T", and we implement this as a binary predicate — see
Listed-In Relations. There is one such relation for each column, and
diff --git a/docs/assertions-module/index.html b/docs/assertions-module/index.html
index 2dc42aee6..17fd9b78c 100644
--- a/docs/assertions-module/index.html
+++ b/docs/assertions-module/index.html
@@ -285,6 +285,11 @@
Parsing Type Data
-
To parse the prototype text of a To... phrase into its type data.
+
-
+ To create and subsequently parse against the list of phrase options with which the user can choose to invoke a To phrase.
+
Rule Family -
diff --git a/docs/if-module/4-ap.html b/docs/if-module/4-ap.html
index 99a021e74..897049605 100644
--- a/docs/if-module/4-ap.html
+++ b/docs/if-module/4-ap.html
@@ -118,8 +118,8 @@ description of an action which may have happened in the past: for example,
PluginManager::plug(RULE_PLACEMENT_NOTIFY_PLUG, Actions::rule_placement_notify);PluginManager::plug(PRODUCTION_LINE_PLUG, ActionsPlugin::production_line);PluginManager::plug(COMPLETE_MODEL_PLUG, ActionsPlugin::complete_model);
-PluginManager::plug(COMPILE_TEST_HEAD_PLUG, Phrases::Context::actions_compile_test_head);
-PluginManager::plug(COMPILE_TEST_TAIL_PLUG, Phrases::Context::actions_compile_test_tail);
+PluginManager::plug(COMPILE_TEST_HEAD_PLUG, RTRules::actions_compile_test_head);
+PluginManager::plug(COMPILE_TEST_TAIL_PLUG, RTRules::actions_compile_test_tail);Vocabulary::set_flags(Vocabulary::entry_for_text(L"doing"), ACTION_PARTICIPLE_MC);Vocabulary::set_flags(Vocabulary::entry_for_text(L"asking"), ACTION_PARTICIPLE_MC);
diff --git a/docs/imperative-module/2-act.html b/docs/imperative-module/2-act.html
index 4db73169c..49b75ad80 100644
--- a/docs/imperative-module/2-act.html
+++ b/docs/imperative-module/2-act.html
@@ -92,7 +92,7 @@ and a shared set of variables, so this will not be a long section of code.
CLASS_DEFINITION} activity;
-
The structure activity is accessed in 2/rls, 2/rlb, 2/fao, 3/prcd, 3/po, 4/sv, 6/cii, 6/cp, 6/cste and here.
+
The structure activity is accessed in 2/rls, 2/rlb, 2/fao, 3/prcd, 4/sv, 6/cii, 6/cp, 6/cste and here.
§2. Whereas rulebooks can turn values into other values, activities are more like
void functions: they work on a value, but produce nothing.
§5. That awkward distinction between a rulebook_outcome and a named_rulebook_outcome
brings us edge cases if a rule has been written for use in one rulebook, but then
has been explicitly listed in another, or is more than one rulebook.
diff --git a/docs/imperative-module/2-rlb.html b/docs/imperative-module/2-rlb.html
index d58ba1171..6cae3770e 100644
--- a/docs/imperative-module/2-rlb.html
+++ b/docs/imperative-module/2-rlb.html
@@ -255,7 +255,7 @@ being analogous to a function \(X\to Y\).
returnFocusAndOutcome::get_outcome_kind(&(B->my_outcomes));}
-outcomes *Rulebooks::get_outcomes(rulebook *B) {
+outcomes *Rulebooks::get_outcomes(rulebook *B) {return &(B->my_outcomes);}
diff --git a/docs/imperative-module/2-rls.html b/docs/imperative-module/2-rls.html
index 059586457..006aeeedf 100644
--- a/docs/imperative-module/2-rls.html
+++ b/docs/imperative-module/2-rls.html
@@ -124,7 +124,7 @@ different dynamics altogether. In short, then: rules are not phrases.
CLASS_DEFINITION} rule;
-
The structure rule is accessed in 2/rlb, 2/fao, 2/act, 3/prcd, 3/po, 4/sv, 6/cii, 6/cp, 6/cste and here.
+
The structure rule is accessed in 2/rlb, 2/fao, 2/act, 3/prcd, 4/sv, 6/cii, 6/cp, 6/cste and here.
§2. Rules are created before their definitions can be parsed or compiled. A
typical rule like so:
§1. Runtime context data is the context in which a phrase is allowed to run,
though it's only used for rules. For example,
@@ -393,8 +393,8 @@ all of them fail to decide, we return 0.
if ((Wordings::nonempty(AL1W)) && (Wordings::empty(AL2W))) return1;if ((Wordings::empty(AL1W)) && (Wordings::nonempty(AL2W))) return -1;if (Wordings::nonempty(AL1W)) {
-intn1 = Phrases::Context::count_avl(rcd1->avl);
-intn2 = Phrases::Context::count_avl(rcd2->avl);
+intn1 = Phrases::Context::count_avl(rcd1->avl);
+intn2 = Phrases::Context::count_avl(rcd2->avl);if (n1 > n2) return1;if (n2 > n1) return -1; }
@@ -452,262 +452,13 @@ process.
Frames::make_current(phsf);Frames::set_stvol(phsf, R->variables_visible_in_definition);
-rcd->avl = Phrases::Context::parse_avl(rcd->activity_context);
+rcd->avl = Phrases::Context::parse_avl(rcd->activity_context);current_sentence = save_cs; } }}
-
§9. Compiling the firing test. Each rule compiles to a routine, and this routine is called whenever the
-opportunity might exist for the rule to fire. The structure of this is
-similar to:
-
The "test head" is the "if" line here, and the "test tail" is the "}". The
-return statement isn't necessarily reached, because even if the firing
-condition holds, the "..." code may decide to return in some other way.
-It provides only a default to cover rules which don't specify an outcome.
-
-
-
In general the test is more elaborate than a single "if", though not very
-much.
-
-
-
-intPhrases::Context::compile_test_head(id_body *idb, rule *R) {
-inter_name *identifier = IDCompilation::iname(idb);
-id_runtime_context_data *phrcd = &(idb->runtime_context_data);
-
-if (RTRules::compile_constraint(R) == TRUE) returnTRUE;
-
-inttests = 0;
-
-if (PluginCalls::compile_test_head(idb, R, &tests) == FALSE) {
-if (phrcd->ap) Compile an action test head9.4;
- }
-if (Wordings::nonempty(phrcd->activity_context))
-Compile an activity or explicit condition test head9.9;
-
-if ((tests > 0) || (idb->compilation_data.compile_with_run_time_debugging)) {
-Produce::inv_primitive(Emit::tree(), IF_BIP);
-Produce::down(Emit::tree());
-Produce::val_iname(Emit::tree(), K_number, Hierarchy::find(DEBUG_RULES_HL));
-Produce::code(Emit::tree());
-Produce::down(Emit::tree());
-Produce::inv_call_iname(Emit::tree(), Hierarchy::find(DB_RULE_HL));
-Produce::down(Emit::tree());
-Produce::val_iname(Emit::tree(), K_value, identifier);
-Produce::val(Emit::tree(), K_number, LITERAL_IVAL, (inter_ti) idb->allocation_id);
-Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 0);
-Produce::up(Emit::tree());
-Produce::up(Emit::tree());
-Produce::up(Emit::tree());
- }
-returnFALSE;
-}
-
-intPhrases::Context::actions_compile_test_head(id_body *idb, rule *R, int *tests) {
-id_runtime_context_data *phrcd = &(idb->runtime_context_data);
- #ifdefIF_MODULE
-if (phrcd->during_scene) Compile a scene test head9.2;
-if (phrcd->ap) Compile possibly testing actor action test head9.5
-elseif (phrcd->always_test_actor == TRUE) Compile an actor-is-player test head9.7;
- #endif
-returnTRUE;
-}
-
-intPhrases::Context::actions_compile_test_tail(id_body *idb, rule *R) {
-inter_name *identifier = IDCompilation::iname(idb);
-id_runtime_context_data *phrcd = &(idb->runtime_context_data);
- #ifdefIF_MODULE
-if (phrcd->ap) Compile an action test tail9.6
-elseif (phrcd->always_test_actor == TRUE) Compile an actor-is-player test tail9.8;
-if (phrcd->during_scene) Compile a scene test tail9.3;
- #endif
-returnTRUE;
-}
-
-
§9.1. This is almost the up-down reflection of the head, but note that it begins
-with the default outcome return (see above).
-
-
-
-voidPhrases::Context::compile_test_tail(id_body *idb, rule *R) {
-inter_name *identifier = IDCompilation::iname(idb);
-id_runtime_context_data *phrcd = &(idb->runtime_context_data);
-rulebook *rb = RuleFamily::get_rulebook(idb->head_of_defn);
-if (rb) RTRules::compile_default_outcome(Rulebooks::get_outcomes(rb));
-if (Wordings::nonempty(phrcd->activity_context))
-Compile an activity or explicit condition test tail9.1.1;
-if (PluginCalls::compile_test_tail(idb, R) == FALSE) {
-if (phrcd->ap) Compile an action test tail9.6;
- }
-}
-
-
§9.2. Scene test. Compile a scene test head9.2 =
-
§11.1. The optional operand handles "something" itself in productions (a) and (b)
+
§10.1. The optional operand handles "something" itself in productions (a) and (b)
in order to prevent it from being read as a description at production (c). This
prevents "something" from being read as "some thing", that is, it prevents
Inform from thinking that the operand value must have kind "thing".
@@ -790,7 +541,7 @@ values, of the kind to which the activity applies.
<s-type-expression-or-value>==> { TRUE, RP[1] }
-activity_list *Phrases::Context::parse_avl(wordingW) {
+activity_list *Phrases::Context::parse_avl(wordingW) {intsave_pac = parsing_al_conditions;parsing_al_conditions = TRUE;intrv = <run-time-context>(W);
@@ -895,7 +646,7 @@ values, of the kind to which the activity applies.
}
diff --git a/docs/imperative-module/4-lv.html b/docs/imperative-module/4-lv.html
index 66e21bfcd..d81c4808a 100644
--- a/docs/imperative-module/4-lv.html
+++ b/docs/imperative-module/4-lv.html
@@ -1368,7 +1368,7 @@ need in the compilation of any given routine:
}
diff --git a/docs/imperative-module/4-sv.html b/docs/imperative-module/4-sv.html
index 04489ee97..001f726bd 100644
--- a/docs/imperative-module/4-sv.html
+++ b/docs/imperative-module/4-sv.html
@@ -107,7 +107,7 @@ function togglePopup(material_id) {
CLASS_DEFINITION} stacked_variable_owner_list;
-
The structure stacked_variable is accessed in 2/rls, 2/fao, 2/act, 3/po, 6/cii, 6/cste and here.
The structure stacked_variable_list is accessed in 2/rlb, 2/act, 3/prcd, 4/lv, 4/sf, 5/dtd, 5/cdp, 6/inv, 6/pi, 6/cii, 6/cp, 6/cste and here.
The structure stacked_variable_owner is private to this section.
The structure stacked_variable_owner_list is accessed in 2/rlb, 2/act, 3/prcd, 4/lv, 4/sf, 5/dtd, 5/cdp, 6/inv, 6/pi, 6/cii, 6/cp, 6/cste and here.
+
The structure stacked_variable is accessed in 2/rls, 2/fao, 2/act, 6/cii, 6/cste and here.
The structure stacked_variable_list is accessed in 2/rlb, 2/act, 3/prcd, 4/lv, 4/sf, 5/dtd, 5/cdp, 6/inv, 6/pi, 6/cii, 6/cp, 6/cste and here.
The structure stacked_variable_owner is private to this section.
The structure stacked_variable_owner_list is accessed in 2/rlb, 2/act, 3/prcd, 4/lv, 4/sf, 5/dtd, 5/cdp, 6/inv, 6/pi, 6/cii, 6/cp, 6/cste and here.
§2.
diff --git a/docs/imperative-module/6-cii.html b/docs/imperative-module/6-cii.html
index b5acd08f1..d444f5644 100644
--- a/docs/imperative-module/6-cii.html
+++ b/docs/imperative-module/6-cii.html
@@ -364,7 +364,7 @@ charlatans" and what they "deserve". I'm a better person now.
-phod_being_parsed = &(idb->options_data);
+phod_being_parsed = &(idb->type_data.options_data);idb_being_parsed = idb;<inline-substitution>(BRW);intcurrent_opts = Invocations::get_phrase_options_bitmap(inv);
diff --git a/docs/imperative-module/6-cp.html b/docs/imperative-module/6-cp.html
index c6914b0b7..0f1623fdc 100644
--- a/docs/imperative-module/6-cp.html
+++ b/docs/imperative-module/6-cp.html
@@ -159,14 +159,14 @@ should always be supplied for "To..." phrases, but left null for rules.
current_sentence = code_at;
-if (Phrases::Context::compile_test_head(idb, R) == FALSE) {
+if (RTRules::compile_test_head(idb, R) == FALSE) {if (code_at) {VerifyTree::verify_structure_from(code_at);Routines::Compile::code_block_outer(1, code_at->down);VerifyTree::verify_structure_from(code_at); }current_sentence = code_at;
-Phrases::Context::compile_test_tail(idb, R);
+RTRules::compile_test_tail(idb, R);Compile a terminal return statement2.3.1; }
diff --git a/docs/imperative-module/6-inv.html b/docs/imperative-module/6-inv.html
index ebaabb150..07beedc99 100644
--- a/docs/imperative-module/6-inv.html
+++ b/docs/imperative-module/6-inv.html
@@ -493,7 +493,7 @@ variable-argument phrases like C's
-wordingInvocations::get_phrase_options(parse_node *inv) {
+wordingInvocations::get_phrase_options(parse_node *inv) {invocation_options *invo = Node::get_phrase_options_invoked(inv);if (invo == NULL) returnEMPTY_WORDING;returninvo->options_invoked_text;
@@ -510,7 +510,7 @@ When no options are set, the bitmap is always 0.
returninvo->options;}
-voidInvocations::set_phrase_options_bitmap(parse_node *inv, intfurther_bits) {
+voidInvocations::set_phrase_options_bitmap(parse_node *inv, intfurther_bits) {if (further_bits == 0) return;invocation_options *invo = Node::get_phrase_options_invoked(inv);if (invo == NULL) {
@@ -526,7 +526,7 @@ When no options are set, the bitmap is always 0.
-intInvocations::implies_newline(parse_node *inv) {
+intInvocations::implies_newline(parse_node *inv) {if (!(IDTypeData::is_a_say_phrase(Node::get_phrase_invoked(inv)))) returnFALSE;if (!(TEST_COMPILATION_MODE(IMPLY_NEWLINES_IN_SAY_CMODE))) returnFALSE;returnTRUE;
@@ -548,7 +548,7 @@ When no options are set, the bitmap is always 0.
-intInvocations::length_of_list(parse_node *invl) {
+intInvocations::length_of_list(parse_node *invl) {intL = 0;for (parse_node *p = invl; p; p = p->next_alternative) L++;returnL;
@@ -558,7 +558,7 @@ When no options are set, the bitmap is always 0.
-voidInvocations::log_list(parse_node *invl) {
+voidInvocations::log_list(parse_node *invl) {parse_node *inv;LOG("Invocation list (%d):\n", Invocations::length_of_list(invl));intn = 0;
diff --git a/docs/imperative-module/index.html b/docs/imperative-module/index.html
index 4ce99e84c..f71b07c15 100644
--- a/docs/imperative-module/index.html
+++ b/docs/imperative-module/index.html
@@ -136,11 +136,6 @@
Phrase Runtime Context Data -
To store the circumstances in which a rule phrase should fire.
-
-
- Phrase Options -
- To create and subsequently parse against the list of phrase options with which the user can choose to invoke a To phrase.
-intRTRules::compile_constraint(rule *R) {
+intRTRules::compile_constraint(rule *R) {if (R) {applicability_constraint *acl;LOOP_OVER_LINKED_LIST(acl, applicability_constraint, R->applicability_constraints) {
@@ -965,7 +965,7 @@ code are the real outcome of the code in this section.
returnNULL;}
-voidRTRules::compile_default_outcome(outcomes *outs) {
+voidRTRules::compile_default_outcome(outcomes *outs) {intrtrue = FALSE;rulebook_outcome *rbo = outs->default_named_outcome;if (rbo) {
@@ -1101,6 +1101,251 @@ code are the real outcome of the code in this section.
Routines::end(save);}
+
§15. Compiling the firing test. Each rule compiles to a routine, and this routine is called whenever the
+opportunity might exist for the rule to fire. The structure of this is
+similar to:
+
The "test head" is the "if" line here, and the "test tail" is the "}". The
+return statement isn't necessarily reached, because even if the firing
+condition holds, the "..." code may decide to return in some other way.
+It provides only a default to cover rules which don't specify an outcome.
+
+
+
In general the test is more elaborate than a single "if", though not very
+much.
+