diff --git a/docs/core-module/1-cp.html b/docs/core-module/1-cp.html
index 79922ad7b..83e1db157 100644
--- a/docs/core-module/1-cp.html
+++ b/docs/core-module/1-cp.html
@@ -340,7 +340,6 @@ We begin with core itself.
enumnoun_filter_token_CLASSenumparentage_here_inference_data_CLASSenumparentage_inference_data_CLASS
-enumparse_name_notice_CLASSenumparsing_data_CLASSenumparsing_pp_data_CLASSenumpart_of_inference_data_CLASS
@@ -376,7 +375,6 @@ We begin with core itself.
DECLARE_CLASS(noun_filter_token)DECLARE_CLASS(parentage_here_inference_data)DECLARE_CLASS(parentage_inference_data)
-DECLARE_CLASS(parse_name_notice)DECLARE_CLASS(parsing_data)DECLARE_CLASS(parsing_pp_data)DECLARE_CLASS(part_of_inference_data)
diff --git a/docs/if-module/4-act.html b/docs/if-module/4-act.html
index 9a976ebc1..33528c1b5 100644
--- a/docs/if-module/4-act.html
+++ b/docs/if-module/4-act.html
@@ -100,7 +100,7 @@ kind K_action_nameCLASS_DEFINITION} action_name;
-
The structure action_name is accessed in 4/ap, 4/as, 4/av, 4/ann, 4/anl, 4/nap, 4/gng, 5/cg, 5/cgl, 5/ts and here.
+
The structure action_name is accessed in 4/ap, 4/as, 4/av, 4/ann, 4/anl, 4/nap, 4/gng, 5/pp, 5/cg, 5/cgl, 5/ts and here.
§2. Note that we notify the K_action_name kind that a new enumerated value
for it exists; we don't need to record the reply (i.e. the number used as
this value at run-time) because it will be the same as the allocation ID
diff --git a/docs/if-module/4-nap.html b/docs/if-module/4-nap.html
index 33233ecf6..19cc5cb9c 100644
--- a/docs/if-module/4-nap.html
+++ b/docs/if-module/4-nap.html
@@ -93,7 +93,7 @@ this category if it matches one of the patterns.
CLASS_DEFINITION} named_action_pattern_entry;
-
The structure named_action_pattern is accessed in 4/anaa, 4/act, 4/ann, 4/anl, 4/gng, 5/cg, 5/cgl, 5/ts and here.
The structure named_action_pattern_entry is private to this section.
+
The structure named_action_pattern is accessed in 4/anaa, 4/act, 4/ann, 4/anl, 4/gng, 5/pp, 5/cg, 5/cgl, 5/ts and here.
The structure named_action_pattern_entry is private to this section.
§2. We are allowed to give names to certain kinds of behaviour by "characterising"
an action.
diff --git a/docs/if-module/5-cg.html b/docs/if-module/5-cg.html
index 9c3755927..d40320f96 100644
--- a/docs/if-module/5-cg.html
+++ b/docs/if-module/5-cg.html
@@ -144,7 +144,7 @@ form, so this is not as bloated a structure as it looks.
CLASS_DEFINITION} command_grammar;
-
The structure command_grammar is accessed in 4/act, 4/nap, 4/gng, 5/cgl, 5/ts and here.
+
The structure command_grammar is accessed in 4/act, 4/nap, 4/gng, 5/pp, 5/cgl, 5/ts and here.
§4. We begin as usual with a constructor and some debug log tracing.
command_grammar *CommandGrammars::for_subject(inference_subject *subj) {
-if (PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object != NULL)
-returnPARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object;
+if (PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject != NULL)
+returnPARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject;command_grammar *cg = CommandGrammars::cg_new(CG_IS_SUBJECT);
-PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object = cg;
+PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject = cg;cg->subj_understood = subj;returncg;}
diff --git a/docs/if-module/5-cgl.html b/docs/if-module/5-cgl.html
index cce13ea3c..df8f92114 100644
--- a/docs/if-module/5-cgl.html
+++ b/docs/if-module/5-cgl.html
@@ -140,7 +140,7 @@ removing it from action. That's a feature only seen in lines for
CLASS_DEFINITION} cg_line;
-
The structure cg_line is accessed in 4/ap, 4/act, 4/as, 4/nap, 4/gng, 5/us, 5/cg, 5/ts and here.
+
The structure cg_line is accessed in 4/ap, 4/act, 4/as, 4/nap, 4/gng, 5/pp, 5/us, 5/cg, 5/ts and here.
§2.
diff --git a/docs/if-module/5-pp.html b/docs/if-module/5-pp.html
index f998e2b2c..a271409fe 100644
--- a/docs/if-module/5-pp.html
+++ b/docs/if-module/5-pp.html
@@ -109,7 +109,6 @@ for generating that is a little delicate.
BENCH(Understand::traverse); }if (stage == INTER2_CSEQ) {
-BENCH(UnderstandGeneralTokens::write_parse_name_routines);BENCH(RTCommandGrammarLines::MistakeActionSub_routine);BENCH(CommandGrammars::prepare);BENCH(RTCommandGrammars::compile_conditions);
@@ -139,13 +138,15 @@ and in particular, to every object instance and every kind of object.
typedefstructparsing_data {
-structcommand_grammar *understand_as_this_object; grammar for parsing the name at run-time
+structcommand_grammar *understand_as_this_subject; grammar for parsing the name at run-time
+structparsing_compilation_datacompilation_data;CLASS_DEFINITION} parsing_data;parsing_data *ParsingPlugin::new_data(inference_subject *subj) {parsing_data *pd = CREATE(parsing_data);
-pd->understand_as_this_object = NULL;
+pd->understand_as_this_subject = NULL;
+pd->compilation_data = Name::new_compilation_data(subj);returnpd;}
@@ -154,7 +155,7 @@ and in particular, to every object instance and every kind of object.
returnFALSE;}
-
The structure parsing_data is accessed in 5/cg and here.
+
The structure parsing_data is accessed in 4/act, 4/nap, 4/gng, 5/cg, 5/cgl, 5/ts and here.
§4. We make use of a new kind of rvalue in this plugin: K_understanding. This
is created in Familiar Kinds (in kinds), not here, but we do have to provide
the following functions to handle its constant rvalues. These correspond to
@@ -215,7 +216,7 @@ the Inter command parser at runtime, whose data is typeless.
switch (<<r>>) {case0:if (Kinds::eq(<<rp>>, NonlocalVariables::kind(var))) {
-RTParsing::understood_variable(var);
+RTVariables::understood_variable(var);NonlocalVariables::allow_to_be_zero(var); }break;
@@ -240,7 +241,7 @@ and is in that sense (okay, ironically) "nameless".
property *ParsingPlugin::name_property(void) {if (P_name == NULL) {P_name = ValueProperties::new_nameless(I"name", K_text);
-Hierarchy::make_available(RTParsing::name_iname());
+Hierarchy::make_available(RTProperties::iname(P_name)); }returnP_name;}
@@ -294,7 +295,7 @@ get the name pr
Projects::get_language_of_play(Task::project())); }ValueProperties::assert(ParsingPlugin::name_property(), Instances::as_subject(I),
-RTParsing::name_property_array(I, W, PW, from_kind), CERTAIN_CE);
+Name::name_property_array(I, W, PW, from_kind), CERTAIN_CE); }
§4. Values for "understanding" refer to command grammar. We cache them as they
+occur in the source text because they can compile to a fairly large slice of
+code, and we don't want to repeat that:
+
+
+
+typedefstructcached_understanding {
+structwordingunderstanding_text; word range of the understanding text
+structinter_name *cu_iname; function to test this
+CLASS_DEFINITION
+} cached_understanding;
+
+voidCompileRvalues::compile_understanding(inter_ti *val1, inter_ti *val2, wordingW) {
+if (<subject-pronoun>(W)) {
+ *val1 = LITERAL_IVAL; *val2 = 0;
+ } else {
+cached_understanding *cu;
+LOOP_OVER(cu, cached_understanding)
+if (Wordings::match(cu->understanding_text, W)) {
+Emit::to_value_pair(val1, val2, cu->cu_iname);
+return;
+ }
+command_grammar *cg = Understand::consultation(W);
+inter_name *iname = RTCommandGrammars::consult_iname(cg);
+if (iname) {
+cu = CREATE(cached_understanding);
+cu->understanding_text = W;
+cu->cu_iname = iname;
+Emit::to_value_pair(val1, val2, iname);
+ }
+ }
+}
+
+
The structure cached_understanding is private to this section.
diff --git a/docs/runtime-module/2-cu.html b/docs/runtime-module/2-cu.html
index 7cf9995ea..471962da8 100644
--- a/docs/runtime-module/2-cu.html
+++ b/docs/runtime-module/2-cu.html
@@ -243,7 +243,7 @@ but that's now easy.
}
diff --git a/docs/runtime-module/2-dv.html b/docs/runtime-module/2-dv.html
index 82b4e1fb7..f80ec3c98 100644
--- a/docs/runtime-module/2-dv.html
+++ b/docs/runtime-module/2-dv.html
@@ -420,7 +420,7 @@ names are not.
diff --git a/docs/runtime-module/2-ea.html b/docs/runtime-module/2-ea.html
index 9159d6e82..0754ccd9c 100644
--- a/docs/runtime-module/2-ea.html
+++ b/docs/runtime-module/2-ea.html
@@ -92,7 +92,7 @@ enforced; it's fine to store arbitrary data with
-packaging_stateEmitArrays::begin(inter_name *name, kind *K) {
+packaging_stateEmitArrays::begin(inter_name *name, kind *K) {packaging_statesave = Packaging::enter_home_of(name);EmitArrays::begin_inner(name, K, FALSE);returnsave;
@@ -181,13 +181,13 @@ which would be a typesafe list in I7, so they can be absolutely any data,
EmitArrays::entry_inner(v1, v2);}
-voidEmitArrays::dword_entry(text_stream *content) {
+voidEmitArrays::dword_entry(text_stream *content) {inter_tiv1 = 0, v2 = 0;Produce::dword_value(Emit::tree(), &v1, &v2, content);EmitArrays::entry_inner(v1, v2);}
-voidEmitArrays::plural_dword_entry(text_stream *content) {
+voidEmitArrays::plural_dword_entry(text_stream *content) {inter_tiv1 = 0, v2 = 0;Produce::plural_dword_value(Emit::tree(), &v1, &v2, content);EmitArrays::entry_inner(v1, v2);
@@ -213,7 +213,7 @@ difference to compiled code.
-voidEmitArrays::end(packaging_statesave) {
+voidEmitArrays::end(packaging_statesave) {EmitArrays::end_inner();Packaging::exit(Emit::tree(), save);}
@@ -349,7 +349,7 @@ is completely emitted before another one is.
}
diff --git a/docs/runtime-module/2-ec.html b/docs/runtime-module/2-ec.html
index 18368a308..e6f7e03a5 100644
--- a/docs/runtime-module/2-ec.html
+++ b/docs/runtime-module/2-ec.html
@@ -108,10 +108,10 @@ instruction last emitted, not after it.
● EmitCode::up then returns us back to where we were.
diff --git a/docs/runtime-module/2-emt.html b/docs/runtime-module/2-emt.html
index 893c376ea..14cca5dfc 100644
--- a/docs/runtime-module/2-emt.html
+++ b/docs/runtime-module/2-emt.html
@@ -125,7 +125,7 @@ reference points. But as newly-created packages they are initially empty.
returnPackaging::enclosure(Emit::tree());}
-packaging_stateEmit::new_packaging_state(void) {
+packaging_stateEmit::new_packaging_state(void) {returnPackaging::stateless();}
@@ -157,7 +157,7 @@ what package it belongs to, the "context" referred to below:
Emit::stvp_inner(S, v1, v2, Inter::Bookmarks::package(Emit::at()));}
-voidEmit::to_value_pair(inter_ti *v1, inter_ti *v2, inter_name *iname) {
+voidEmit::to_value_pair(inter_ti *v1, inter_ti *v2, inter_name *iname) {Emit::stvp_inner(InterNames::to_symbol(iname), v1, v2, Inter::Bookmarks::package(Emit::at()));}
@@ -593,7 +593,7 @@ assimilating during linking.
}
diff --git a/docs/runtime-module/2-es.html b/docs/runtime-module/2-es.html
index 5227668e3..bc7dda20e 100644
--- a/docs/runtime-module/2-es.html
+++ b/docs/runtime-module/2-es.html
@@ -128,7 +128,7 @@ data, not merely the pointer to them, which is a "deep copy".
}
§1. Introduction. At runtime, the command parser handles noun phrases in two ways. Simple
+nouns for an object are handled by giving it a name property listing
+some dictionary words which could refer to it — see Name Properties.
+
+
+
More complex nouns are handled with Inter functions called "general parsing
+routines", or GPRs: the term is traditional and goes back to Inform 1 to 6.
+GPRs are used for parsing values of kinds other than objects, too; in
+particular, each notation for a literal value needs its own GPR — see
+Literal Patterns.
+
+
+
The GPRs compiled automatically by today's Inform follow the same conventions
+and specification, so the tutorials in the Inform 6 manual, the DM4, may help
+tp explain what we do in this section of code. No tutorials are needed today
+because in Inform 7 all of the many GPRs in a typical story file are compiled
+automatically, so that the story's author is not really aware of them at all.
+
+
+
To compile a GPR, Inform has to:
+
+
+
● work out where to put it, i.e., choose an inter_name;
+
● open a function body there;
+
● use a gpr_kit to give it local variables as needed;
+
● compile a "GPR head";
+
● compile code which actually looks at the stream of command words;
+
● compile a "GPR tail";
+
● and close the function body.
+
+
The "head" and "tail" parts of a GPR come in several sorts, compiled by functions
+below, and they need to match each other.
+
+
+
§2. GPR kits. Since GPRs are needed for several different purposes, we provide a general
+API for compiling them, based around the idea of a "GPR kit" — slogan, it's
+everything you need to compile your own GPR.
+
+
+
This is not an elegant structure. It simply keeps track of the many local
+variables needed inside GPRs, which tend to be large, wrangly functions:
+
§4. Then, if you then need a local variable in the GPR you're making, declare it
+and write its symbol to the appropriate field. But this is best done with the
+following convenience functions.
+
+
+
+voidGPRs::add_standard_vars(gpr_kit *kit) {
+kit->group_wn_s = LocalVariables::new_internal_as_symbol(I"group_wn");
+kit->v_s = LocalVariables::new_internal_as_symbol(I"v");
+kit->w_s = LocalVariables::new_internal_as_symbol(I"w");
+kit->rv_lv = LocalVariables::new_internal(I"rv");
+kit->rv_s = LocalVariables::declare(kit->rv_lv);
+}
+
+voidGPRs::add_instance_var(gpr_kit *kit) {
+kit->instance_s = LocalVariables::new_other_as_symbol(I"instance");
+}
+
+voidGPRs::add_range_vars(gpr_kit *kit) {
+kit->range_from_s = LocalVariables::new_internal_commented_as_symbol(I"range_from",
+I"call parameter: word number of snippet start");
+kit->range_words_s = LocalVariables::new_internal_commented_as_symbol(I"range_words",
+I"call parameter: snippet length");
+}
+
+voidGPRs::add_original_var(gpr_kit *kit) {
+kit->original_wn_s = LocalVariables::new_internal_as_symbol(I"original_wn");
+}
+
+voidGPRs::add_LP_vars(gpr_kit *kit) {
+kit->wpos_s = LocalVariables::new_internal_as_symbol(I"wpos");
+kit->mid_word_s = LocalVariables::new_internal_as_symbol(I"mid_word");
+kit->matched_number_s = LocalVariables::new_internal_as_symbol(I"matched_number");
+kit->cur_word_s = LocalVariables::new_internal_as_symbol(I"cur_word");
+kit->cur_len_s = LocalVariables::new_internal_as_symbol(I"cur_len");
+kit->cur_addr_s = LocalVariables::new_internal_as_symbol(I"cur_addr");
+kit->sgn_s = LocalVariables::new_internal_as_symbol(I"sgn");
+kit->tot_s = LocalVariables::new_internal_as_symbol(I"tot");
+kit->f_s = LocalVariables::new_internal_as_symbol(I"f");
+kit->x_s = LocalVariables::new_internal_as_symbol(I"x");
+}
+
+voidGPRs::add_parse_name_vars(gpr_kit *kit) {
+kit->original_wn_s = LocalVariables::new_internal_commented_as_symbol(I"original_wn",
+I"first word of text parsed");
+kit->group_wn_s = LocalVariables::new_internal_commented_as_symbol(I"group_wn",
+I"first word matched against A/B/C/... disjunction");
+kit->try_from_wn_s = LocalVariables::new_internal_commented_as_symbol(I"try_from_wn",
+I"position to try matching from");
+kit->n_s = LocalVariables::new_internal_commented_as_symbol(I"n",
+I"number of words matched");
+kit->f_s = LocalVariables::new_internal_commented_as_symbol(I"f",
+I"flag: sufficiently good match found to justify success");
+kit->w_s = LocalVariables::new_internal_commented_as_symbol(I"w",
+I"for use by individual grammar lines");
+kit->rv_lv = LocalVariables::new_internal(I"rv");
+kit->rv_s = LocalVariables::declare(kit->rv_lv);
+kit->g_s = LocalVariables::new_internal_commented_as_symbol(I"g",
+I"temporary: success flag for parsing visibles");
+kit->ss_s = LocalVariables::new_internal_commented_as_symbol(I"ss",
+I"temporary: saves 'self' in distinguishing visibles");
+kit->spn_s = LocalVariables::new_internal_commented_as_symbol(I"spn",
+I"temporary: saves 'parsed_number' in parsing visibles");
+kit->pass_s = LocalVariables::new_internal_commented_as_symbol(I"pass",
+I"pass counter (1 to 3)");
+kit->pass1_n_s = LocalVariables::new_internal_commented_as_symbol(I"pass1_n",
+I"value of n recorded during pass 1");
+kit->pass2_n_s = LocalVariables::new_internal_commented_as_symbol(I"pass2_n",
+I"value of n recorded during pass 2");
+}
+
diff --git a/docs/runtime-module/2-hrr.html b/docs/runtime-module/2-hrr.html
index 2ad509fc0..49d1956d0 100644
--- a/docs/runtime-module/2-hrr.html
+++ b/docs/runtime-module/2-hrr.html
@@ -706,7 +706,6 @@ that the compiler can refer to it.
enumNOUN_FILTER_FN_HLenumPARSE_NAMES_HAPenumPARSE_NAME_FN_HL
-enumPARSE_NAME_DASH_FN_HLenumSCOPE_FILTERS_HAPenumSCOPE_FILTER_FN_HLenumSLASH_TOKENS_HAP
@@ -725,6 +724,8 @@ that the compiler can refer to it.
enumVERB_DIRECTIVE_SLASH_HLenumVERB_DIRECTIVE_SPECIAL_HLenumVERB_DIRECTIVE_TOPIC_HL
+enumOBJECT_NOUNS_HAP
+enumNAME_ARRAY_HLenumCOMMANDS_HAPenumVERB_DECLARATION_ARRAY_HLenumMISTAKEACTION_HL
@@ -780,8 +781,6 @@ that the compiler can refer to it.
H_F_G(SCOPE_FILTER_FN_HL, I"filter_fn", I"Scope_Filter")H_ENDH_BEGIN_AP(PARSE_NAMES_HAP, I"parse_name", I"_parse_name")
-H_F_G(PARSE_NAME_FN_HL, I"parse_name_fn", I"Parse_Name_GV")
-H_F_G(PARSE_NAME_DASH_FN_HL, I"parse_name_fn", I"PN_for_S")H_ENDH_BEGIN_AP(SLASH_TOKENS_HAP, I"slash_token", I"_slash_token")H_F_G(SLASH_FN_HL, I"slash_fn", I"SlashGPR")
@@ -789,6 +788,10 @@ that the compiler can refer to it.
H_ENDH_BEGIN(HierarchyLocations::completion_submodule(I, grammar))
+H_BEGIN_AP(OBJECT_NOUNS_HAP, I"object_noun", I"_object_noun")
+H_F_G(NAME_ARRAY_HL, I"name_array", I"name_array")
+H_F_G(PARSE_NAME_FN_HL, I"parse_name_fn", I"parse_name")
+H_ENDH_BEGIN_AP(COMMANDS_HAP, I"command", I"_command")H_F_G(VERB_DECLARATION_ARRAY_HL, NULL, I"GV_Grammar")H_END
@@ -1614,7 +1617,7 @@ at which this array should be placed, by calling, e.g.,
@@ -1827,7 +1830,7 @@ point system, and for those:
}
diff --git a/docs/runtime-module/2-int.html b/docs/runtime-module/2-int.html
index cbc8a4353..3338f4b16 100644
--- a/docs/runtime-module/2-int.html
+++ b/docs/runtime-module/2-int.html
@@ -300,7 +300,7 @@ to reject it again with a problem message.
diff --git a/docs/runtime-module/2-ni.html b/docs/runtime-module/2-ni.html
index fd4ace5e3..48bdab9f7 100644
--- a/docs/runtime-module/2-ni.html
+++ b/docs/runtime-module/2-ni.html
@@ -145,7 +145,7 @@ mutate the name in order to achieve that uniqueness.
}
diff --git a/docs/runtime-module/2-sc.html b/docs/runtime-module/2-sc.html
index 2dbbfe80f..8305028c4 100644
--- a/docs/runtime-module/2-sc.html
+++ b/docs/runtime-module/2-sc.html
@@ -510,7 +510,7 @@ turn by turn.
diff --git a/docs/runtime-module/2-sv.html b/docs/runtime-module/2-sv.html
index 348eef5d3..32ec67fe0 100644
--- a/docs/runtime-module/2-sv.html
+++ b/docs/runtime-module/2-sv.html
@@ -168,7 +168,7 @@ need to come into being.
§6. And in particular that's how we handle sentences like "Maximum score translates
into Inter as "MAX_SCORE".":
diff --git a/docs/runtime-module/6-bd.html b/docs/runtime-module/6-bd.html
index 1556922c4..d4b666eb2 100644
--- a/docs/runtime-module/6-bd.html
+++ b/docs/runtime-module/6-bd.html
@@ -213,7 +213,7 @@ around it, in byte-accessible memory.
}
diff --git a/docs/runtime-module/7-prs.html b/docs/runtime-module/6-np.html
similarity index 53%
rename from docs/runtime-module/7-prs.html
rename to docs/runtime-module/6-np.html
index ae84e2f2a..346324f5c 100644
--- a/docs/runtime-module/7-prs.html
+++ b/docs/runtime-module/6-np.html
@@ -1,7 +1,7 @@
- Parsing
+ Name Properties
@@ -20,6 +20,11 @@ function togglePopup(material_id) {
+
+
+
+
@@ -67,41 +72,85 @@ function togglePopup(material_id) {
-
+
§1. In the runtime command parser, the names of objects are parsed as nouns using
+the values of two properties: name, a simple array of dictionary words, and
+parse_name, a GPR function. These properties can be assigned either to single
+instances of kinds of object, or to the kinds themselves, so we store their
+inames in data attached to an inference subject.
+
+
+
For a subject which is neither an object nor a kind of object, these names are
+forever null.
+
§2. The name property requires special care, partly over I6 eccentricities
-such as the way that single-letter dictionary words can be misinterpreted
-as characters (hence the double slash below), but also because something
-called "your ..." in the source text — "your nose", say — needs to
-be altered to "my ..." for purposes of parsing during play.
-
-
-
Note that name is additive in I6 terms, meaning that its values
-accumulate from class down to instance: but we prevent this, by only
-compiling name properties for instance objects directly. The practical
-consequence is that we have to imitate this inheritance when it comes
-to single-word grammar for things. Recall that a sentence like "Understand
-"cube" as the block" formally creates a grammar line which ought to
-be parsed as part of some elaborate parse_name property: but that for
-efficiency's sake, we notice that "cube" is only one word and so put
-it into the name property instead. And we need to perform the same trick
-for the kinds we inherit from.
+
§3. A single package holds the name and/or parse_name of a single subject.
§4. Note that a name is never given to a kind: only to an instance. This is
+unlike customary practice when writing Inform 6 code, and is one of the few
+ways in which I7-generated code does not mimic I6 practice in command parsing.1
+
+
+
We take special care to ensure that something called "your ..." in the source text
+— "your nose", say — is altered to "my ..." for purposes of parsing during play.
+
+
+
The test case PM_PluralsFromKind may be helpful here.
+
+
+
1 This is because we do not want to imitate the unusual feature of I6 which
+makes name an "additive" property, i.e., in which arrays accumulate as objects
+inherit from classes. The concept of additive properties does not exist in Inter.
+ ↩
+
+parse_node *Name::name_property_array(instance *I, wordingW, wordingPW,intfrom_kind) {
-package_request *PR =
-Hierarchy::package_within(INLINE_PROPERTIES_HAP, RTInstances::package(I));
-inter_name *name_array = Hierarchy::make_iname_in(INLINE_PROPERTY_HL, PR);
+inter_name *name_array = Name::get_name_array_iname(I->as_subject);packaging_statesave = EmitArrays::begin(name_array, K_value);LOOP_THROUGH_WORDING(j, W) {
@@ -115,7 +164,7 @@ for the kinds we inherit from.
EmitArrays::dword_entry(content);DISCARD_TEXT(content) }
-if (from_kind) see test case PM_PluralsFromKind
+if (from_kind)LOOP_THROUGH_WORDING(j, PW) {intadditional = TRUE;LOOP_THROUGH_WORDING(k, W)
@@ -129,17 +178,17 @@ for the kinds we inherit from.
} }
-if (PARSING_DATA(I)->understand_as_this_object)
+if (PARSING_DATA(I)->understand_as_this_subject)CommandGrammars::take_out_one_word_grammar(
-PARSING_DATA(I)->understand_as_this_object);
+PARSING_DATA(I)->understand_as_this_subject);inference_subject *infs;for (infs = KindSubjects::from_kind(Instances::to_kind(I));infs; infs = InferenceSubjects::narrowest_broader_subject(infs)) {if (PARSING_DATA_FOR_SUBJ(infs)) {
-if (PARSING_DATA_FOR_SUBJ(infs)->understand_as_this_object)
+if (PARSING_DATA_FOR_SUBJ(infs)->understand_as_this_subject)CommandGrammars::take_out_one_word_grammar(
-PARSING_DATA_FOR_SUBJ(infs)->understand_as_this_object);
+PARSING_DATA_FOR_SUBJ(infs)->understand_as_this_subject); } }
@@ -147,45 +196,9 @@ for the kinds we inherit from.
Produce::annotate_i(name_array, INLINE_ARRAY_IANN, 1);returnRvalues::from_iname(name_array);}
-
-inter_name *RTParsing::name_iname(void) {
-returnRTProperties::iname(ParsingPlugin::name_property());
-}
-
§3. We cache grammar occurring in the source text in conditions, and so forth:
-
-
-
-typedefstructcached_understanding {
-structwordingunderstanding_text; word range of the understanding text
-structinter_name *cu_iname; the runtime name for this Consult_Grammar_N routine
-CLASS_DEFINITION
-} cached_understanding;
-
-
-voidRTParsing::compile_understanding(inter_ti *val1, inter_ti *val2, wordingW) {
-if (<subject-pronoun>(W)) { *val1 = LITERAL_IVAL; *val2 = 0; }
-else {
-cached_understanding *cu;
-LOOP_OVER(cu, cached_understanding)
-if (Wordings::match(cu->understanding_text, W)) {
-Emit::to_value_pair(val1, val2, cu->cu_iname);
-return;
- }
-command_grammar *cg = Understand::consultation(W);
-inter_name *iname = UnderstandGeneralTokens::consult_iname(cg);
-if (iname) {
-cu = CREATE(cached_understanding);
-cu->understanding_text = W;
-cu->cu_iname = iname;
-Emit::to_value_pair(val1, val2, iname);
- }
- }
-}
-
-
The structure cached_understanding is private to this section.
diff --git a/docs/runtime-module/7-gpr.html b/docs/runtime-module/6-pnp.html
similarity index 65%
rename from docs/runtime-module/7-gpr.html
rename to docs/runtime-module/6-pnp.html
index b525a4ad8..6dcc841a2 100644
--- a/docs/runtime-module/7-gpr.html
+++ b/docs/runtime-module/6-pnp.html
@@ -1,7 +1,7 @@
- General Parsing Routines
+ Parse Name Properties
@@ -67,223 +67,146 @@ function togglePopup(material_id) {
-
+
The structure parse_name_notice is private to this section.
-
§2. In this section we compile GPRs, routines to handle Consult-like text,
-and also parse_name routines, which as we shall see come in two different
-forms. These routines share a basic protocol for dealing with the I6
-library, which makes things considerably easier. In each case, the
-routine is compiled as a head and then, subsequently, a tail: the user
-of the routines is expected to compile the actual grammar in between
-the two. Every head must be followed by exactly one tail of the same
-sort; every tail must be preceded by exactly one head of the same sort;
-but code to parse at wn may be placed in between.
+
§1. Introduction. A parse_name property can belong to any instance of a kind of object, or to
+any kind of object, but not to K_object itself. Its value must be a GPR
+(see General Parsing Routines) which matches as many words as possible from
+the command parser's stream of words, beginning at word number wn.
-
The GPRs compiled to parse literal values of given kinds of values
-(for instance, exotic verbal forms of numbers, or verbal names of
-the constants for new kinds of value, or literal patterns) are not
-compiled here: they are in Tokens Parsing Values.
+
The following returns the iname for the function to be used as the parse_name
+property of an inference subject subj, causing it to be compiled later; or
+else returns NULL is none is needed.
-
§3. Consult routines. These are used to parse an explicit range of words (such as traditionally
-found in the CONSULT command) at run time, and they are not I6 grammar
-tokens, and do not appear in Verb declarations: otherwise, such
-routines are very similar to GPRs.
+
The obvious reason it could be needed is if there is some syntax a player could
+type to refer to the subject. But in fact we also need to make a GPR as a
+"distinguisher" in a few cases where there is no such syntax, because of the
+way the runtime command parser uses parse_name functions to determine whether
+two objects can be distinguished by anything the player types. Recall that some
+properties are "visible", in that the player can use them adjectically in
+commands: for instance, if colour is a visible property of a car, then it can be
+called "green car" if in fact its colour is green, and so on. The command parser
+therefore calls parse_name functions at runtime to ask about distinguishability
+as well as for parsing, so that's another reason we might need one.
-
First, we need to look after a pointer to the CG used to hold the grammar
-being matched against the snippet of words.
+
The test case AwkwardParseNames may be helpful here.
§4. Parse name properties. One of the major services provided by I7, as compared with I6, is that it
-automatically compiles what would otherwise be laborious parse_name
-routines for its objects. This is messy, because the underlying I6 syntax
-is messy. The significant complication is that the I6 parser makes two
-quite different uses of parse_name: not just for parsing names, but
-also for determining whether two objects are visually distinguishable,
-something it needs to know in order to make plural objects work properly.
-
-
-
If an object has any actual grammar attached, say a collection of grammar
-lines belonging to GV3, we will compile the parse_name as an independent
-I6 routine with a name like Parse_Name_GV3. If not, a parse_name may
-still be needed, because of the distinguishability problem: if so then we
-will simply compile a parse_name routine inline, in the usual I6 way.
-
§5. The following routine produces one of three outcomes: either (i) the
-head of an I6 declaration of a free-standing routine to be used as a
-parse_name property, or (ii) the head of an I6 inline declaration of a
-parse_name property as a with clause for an Object directive, or
-
-
-
(iii) the empty output, in happy cases where neither parsing nor
-distinguishability need to be investigated. The routine returns a flag
-indicating if a tail need be compiled (i.e., in cases (i) or (ii) but not
-(iii)).
-
-
In cases (i) and (ii), the head is immediately followed by code which
-looks at the names of visible properties. Recall that a visible property
-is one which can be used to describe an object: for instance, if colour
-is a visible property of a car, then it can be called "green car" if
-and only if the current value of the colour of the car is "green", and
-so forth. In all such cases, we need to parse the text to look for the
-name of the current value.
-
-
-
But if a property can be used as part of the name, then it follows that
-two objects with the same grammar (and name words) cease to be
-indistinguishable when their values for this property differ. For instance,
-given two otherwise identical cars which can only be called "car", we
-can distinguish them with the names "red car" and "green car" if one
-is red and the other green. The parser needs to know this. It calls the
-parse_name routine with an I6 global called parser_action set to
-##TheSame in such a case, and we can return 0 to make no decision or
--2 to say that they are different.
-
-
-
Note that the parser checks this only if two or more objects share the same
-parse_name routine: which will in I7 happen only if they each inherit it
-from the I6 class of a common kind. Because parse_name is not additive in
-I6, this can only occur if the objects, and any intervening classes for
-intervening kinds, define no parse_name of their own.
-
-
-
We will test distinguishability only for kinds which have permissions for
-visible properties: kinds because no other parse_name values can ever
-be duplicated in instance objects, and visible properties because these
-are the only ways to tell apart instances which have no grammar of their
-own. (If either had grammar of its own, it would also have its own
-parse_name routine.) For all other kinds, we return a make-no-decision
-value in response to a ##TheSame request: this ensures that the I6
-parser looks at the name properties of the objects instead, and in
-the absence of either I7-level grammar lines or visible properties, that
-will be the correct decision.
+
§2. This GPR never matches anything, so is very simple to compile.
§4. The head. Either way, then, the head and the tail are mostly the same. Here is the head.
+
+
+
Most of the function lives inside a loop making three passes, with pass running
+from 1 to 3. In these passes, we will check:
+
+
+
(1) (words in name property) (visible property names) (words in name property)
+(longer grammar) (words in name property)
(2) (visible property names) (longer grammar) (words in name property)
(3) (longer grammar) (words in name property)
-
The longer match is taken: but note that a match of visible property names
-alone is rejected unless at least one property has been declared sufficient
-to identify the object all by itself. Longer grammar means grammar lines
-containing 2 or more words, since all single-fixed-word grammar lines for
-CGs destined to be parse_names is stripped out and converted into the
-name property.
+
Whichever is the longest match over these three passes will be the one taken:
+but note that a match of visible property names alone is rejected unless at least
+one property has been declared sufficient to identify the object all by itself.
-
There are clearly other possibilities and the above system is something of
-a pragmatic compromise (in that to check other cases would be slower and
-more complex). I suspect we will return to this.
+
"Longer grammar" means grammar lines containing 2 or more words, since all
+single-fixed-word grammar lines for CGs destined to be parse_names is stripped
+out and converted into the name property.
§4.2. If the command parser is giving us the opportunity to say whether objects
+with this parse_name function are distinguishable, it will do that by
+having set parser_action to ##TheSame. Here we return "make no decision"
+to that, which disclaims responsibility, and forces the command parser to look
+directly at the name properties of the objects instead.
+
§7. The head and tail routines can only be understood by knowing that the
-following code is used to reset the grammar-line parser after each failure
-of a CGL to parse.
+
§5. The middle. That concludes the head. The middle of the parse_name function is then made
+up of attempts to parse the grammar lines for this subject, one after another,
+until one of them works (if it ever does). That code is compiled in
+Command Grammar Lines, not here, but it calls the following function to
+compile code which will safely restore the situation after each failure of a line.
§8. The interesting point about the tail of the parse_name routine is that
-it ends on the ] "close routine" character, in mid-source line. This is
-because the routine may be being used inside an Object directive, and
-would therefore need to be followed by a comma, or in free-standing I6 code,
-in which case it would need to be followed by a semi-colon.
+
§6.1. The indefinite loop is iterated only by an explicit CONTINUE_BIP instruction.
+If execution reaches the end of the loop body, the loop ends at once, because:
+
§7. We generate code suitable for inclusion in a parse_name routine which
either tests distinguishability then parses, or else just parses, the
visible properties of a given subject (which may be a kind or instance).
Sometimes we allow visibility to be inherited from a permission given
@@ -755,90 +730,71 @@ specific object.
§10. Common handling for distinguishing and parsing. The top-level considering routines parcel up work and hand it over to
-the distinguishing routines if phase is 1, and the parsing routines
-if phase is 2. Note that if there are no sometimes-visible-properties
-then the correct behaviour is to call none of the routines below this
-level, and to compile nothing to the file.
+
§8. Distinguishing visible properties. We distinguish two objects P1 and P2 based on the following criteria:
-
(i) if any property is currently visible for P1 but not P2 or vice versa,
-then they are distinguishable; (ii) if any value property is visible
-but P1 and P2 have different values for it, then they are distinguishable;
-
(iii) if any either/or property is visible but P1 has it and P2 hasn't,
-or vice versa, then they are distinguishable; and otherwise we revert to
-the I6 parser's standard algorithm, which looks at the name property.
+
(1) if any property is currently visible for P1 but not P2 or vice versa,
+then they are distinguishable;
+
(2) if any value property is visible but P1 and P2 have different values for
+it, then they are distinguishable;
+
(3) if any either/or property is visible but P1 has it and P2 hasn't,
+or vice versa, then they are distinguishable;
+
§13. Parsing visible properties. Here, unlike in distinguishing visible properties, it is unambiguous that
+
§10. Parsing visible properties. Here, unlike in distinguishing visible properties, it is unambiguous that
self refers to the object being parsed: there is therefore no need to
alter the value of self to make any visibility condition work correctly.
diff --git a/docs/runtime-module/6-tm.html b/docs/runtime-module/6-tm.html
index d3ffe2939..e23c82500 100644
--- a/docs/runtime-module/6-tm.html
+++ b/docs/runtime-module/6-tm.html
@@ -136,7 +136,7 @@ given direction D, which appears here in the guise of its instance }
diff --git a/docs/runtime-module/6-tp.html b/docs/runtime-module/6-tp.html
index 6dcc25e8c..14b868f52 100644
--- a/docs/runtime-module/6-tp.html
+++ b/docs/runtime-module/6-tp.html
@@ -124,7 +124,7 @@ the function ChangePlayer}
diff --git a/docs/runtime-module/7-ap.html b/docs/runtime-module/7-ap.html
index 71caeebd9..23ee45817 100644
--- a/docs/runtime-module/7-ap.html
+++ b/docs/runtime-module/7-ap.html
@@ -871,7 +871,7 @@ and in this case we therefore ignore }
The structure cg_compilation_data is accessed in 7/gpr and here.
+
The structure cg_compilation_data is accessed in 6/pnp and here.
§2. Phases III and IV: Sort and Compile Grammar. At this highest level phases III and IV are intermingled, in that Phase III
always precedes Phase IV for any given list of grammar lines, but each CG
goes through both Phase III and IV before the next begins Phase III. So it
@@ -285,22 +285,22 @@ specified for all things. (This mimics I6 class-to-instance inheritance.)
§8. These are used to parse an explicit range of words (such as traditionally
+found in the CONSULT command) at run time, and they are not I6 grammar
+tokens, and do not appear in Verb declarations: otherwise, such
+routines are very similar to GPRs.
+
+
+
First, we need to look after a pointer to the CG used to hold the grammar
+being matched against the snippet of words.
+
diff --git a/docs/runtime-module/index.html b/docs/runtime-module/index.html
index eb9ad30b1..44c60318f 100644
--- a/docs/runtime-module/index.html
+++ b/docs/runtime-module/index.html
@@ -163,6 +163,11 @@
Short Names -
To compile the "short name" and "capitalised short name" properties.
+
Command Grammars -
@@ -438,11 +448,6 @@
Tokens Parsing Values -
In the argot of Inform 6, GPR stands for General Parsing Routine, and I7 makes heavy use of GPR tokens to achieve its ends. This section is where the necessary I6 routines are compiled.
-
-
- General Parsing Routines -
- To compile I6 general parsing routines (GPRs) and/or |parse_name| properties as required by the I7 grammar.