From 87fe04d58bc5ff4bb0a074d646173337cf34708c Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Sat, 22 May 2021 22:40:05 +0100 Subject: [PATCH] Reorganised parsing properties of objects --- docs/core-module/1-cp.html | 2 - docs/if-module/4-act.html | 2 +- docs/if-module/4-nap.html | 2 +- docs/if-module/5-cg.html | 8 +- docs/if-module/5-cgl.html | 2 +- docs/if-module/5-pp.html | 17 +- docs/imperative-module/2-cr.html | 38 +- docs/runtime-module/2-cu.html | 2 +- docs/runtime-module/2-dv.html | 2 +- docs/runtime-module/2-ea.html | 10 +- docs/runtime-module/2-ec.html | 38 +- docs/runtime-module/2-emt.html | 6 +- docs/runtime-module/2-es.html | 2 +- docs/runtime-module/2-gpr.html | 266 ++++ docs/runtime-module/2-hnae.html | 2 +- docs/runtime-module/2-hrr.html | 25 +- docs/runtime-module/2-int.html | 2 +- docs/runtime-module/2-kd.html | 2 +- docs/runtime-module/2-ni.html | 2 +- docs/runtime-module/2-sc.html | 2 +- docs/runtime-module/2-sn.html | 2 +- docs/runtime-module/2-sv.html | 2 +- docs/runtime-module/2-th.html | 2 +- docs/runtime-module/3-gm.html | 2 +- docs/runtime-module/5-ins.html | 2 +- docs/runtime-module/5-kc.html | 12 +- docs/runtime-module/5-lp.html | 8 +- docs/runtime-module/5-prp.html | 4 +- docs/runtime-module/5-tbl.html | 2 +- docs/runtime-module/5-vrb.html | 6 +- docs/runtime-module/6-bd.html | 2 +- docs/runtime-module/{7-prs.html => 6-np.html} | 151 +- .../runtime-module/{7-gpr.html => 6-pnp.html} | 1089 +++++++-------- docs/runtime-module/6-tm.html | 2 +- docs/runtime-module/6-tp.html | 2 +- docs/runtime-module/7-ap.html | 2 +- docs/runtime-module/7-cg.html | 69 +- docs/runtime-module/7-cgl.html | 10 +- docs/runtime-module/7-epv.html | 4 +- docs/runtime-module/7-gng.html | 2 +- docs/runtime-module/7-ic.html | 2 +- docs/runtime-module/7-nft.html | 2 +- docs/runtime-module/7-tpv.html | 160 +-- docs/runtime-module/index.html | 25 +- inform7/Figures/memory-diagnostics.txt | 91 +- inform7/Figures/timings-diagnostics.txt | 37 +- .../Chapter 1/Class Predeclarations.w | 2 - .../if-module/Chapter 5/Command Grammars.w | 6 +- inform7/if-module/Chapter 5/Parsing Plugin.w | 15 +- .../Chapter 2/Compile Rvalues.w | 36 +- .../Chapter 2/General Parsing Routines.w | 177 +++ inform7/runtime-module/Chapter 2/Hierarchy.w | 11 +- .../Chapter 5/Literal Patterns.w | 8 +- inform7/runtime-module/Chapter 5/Tables.w | 2 +- inform7/runtime-module/Chapter 5/Variables.w | 4 + .../Chapter 6/Name Properties.w | 115 ++ .../Chapter 6/Parse Name Properties.w | 1136 +++++++++++++++ .../Chapter 7/Command Grammar Lines.w | 8 +- .../Chapter 7/Command Grammars.w | 61 +- .../Chapter 7/General Parsing Routines.w | 1223 ----------------- inform7/runtime-module/Chapter 7/Parsing.w | 112 -- .../Chapter 7/Tokens Parsing Values.w | 155 +-- inform7/runtime-module/Contents.w | 5 +- 63 files changed, 2709 insertions(+), 2491 deletions(-) create mode 100644 docs/runtime-module/2-gpr.html rename docs/runtime-module/{7-prs.html => 6-np.html} (53%) rename docs/runtime-module/{7-gpr.html => 6-pnp.html} (65%) create mode 100644 inform7/runtime-module/Chapter 2/General Parsing Routines.w create mode 100644 inform7/runtime-module/Chapter 6/Name Properties.w create mode 100644 inform7/runtime-module/Chapter 6/Parse Name Properties.w delete mode 100644 inform7/runtime-module/Chapter 7/General Parsing Routines.w delete mode 100644 inform7/runtime-module/Chapter 7/Parsing.w 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. enum noun_filter_token_CLASS enum parentage_here_inference_data_CLASS enum parentage_inference_data_CLASS -enum parse_name_notice_CLASS enum parsing_data_CLASS enum parsing_pp_data_CLASS enum part_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_name CLASS_DEFINITION } action_name; - +

§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; -

+

§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; - +

§4. We begin as usual with a constructor and some debug log tracing.

@@ -398,10 +398,10 @@ in any case for those.

 command_grammar *CommandGrammars::for_subject(inference_subject *subj) {
-    if (PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object != NULL)
-        return PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object;
+    if (PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject != NULL)
+        return PARSING_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;
     return cg;
 }
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;
 
- +

§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.
 
 typedef struct parsing_data {
-    struct command_grammar *understand_as_this_object;  grammar for parsing the name at run-time
+    struct command_grammar *understand_as_this_subject;  grammar for parsing the name at run-time
+    struct parsing_compilation_data compilation_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);
     return pd;
 }
 
@@ -154,7 +155,7 @@ and in particular, to every object instance and every kind of object.
     return FALSE;
 }
 
- +

§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>>) { case 0: 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)); } return P_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); }

@@ -306,7 +307,7 @@ where grammar has specified a need. (By default, this will not happen.)

-    inter_name *S = UnderstandGeneralTokens::compile_parse_name_property(subj);
+    inter_name *S = ParseName::compile_if_needed(subj);
     if (S)
         ValueProperties::assert(P_parse_name, subj,
             Rvalues::from_iname(S), CERTAIN_CE);
diff --git a/docs/imperative-module/2-cr.html b/docs/imperative-module/2-cr.html
index 9e76a4572..3b33325bd 100644
--- a/docs/imperative-module/2-cr.html
+++ b/docs/imperative-module/2-cr.html
@@ -249,18 +249,16 @@ kinds of value:
         CompileRvalues::text(VH, value);
         return;
     }
-    #ifdef IF_MODULE
     if ((K_understanding) && (Kinds::eq(kind_of_constant, K_understanding))) {
         if (Wordings::empty(Node::get_text(value)))
             internal_error("Text no longer available for CONSTANT/UNDERSTANDING");
         inter_ti v1 = 0, v2 = 0;
-        RTParsing::compile_understanding(&v1, &v2, Node::get_text(value));
+        CompileRvalues::compile_understanding(&v1, &v2, Node::get_text(value));
         if (Holsters::non_void_context(VH)) {
             Holsters::holster_pair(VH, v1, v2);
         }
         return;
     }
-    #endif
     if (Kinds::eq(kind_of_constant, K_use_option)) {
         use_option *uo = Rvalues::to_use_option(value);
         Emit::holster_iname(VH, RTUseOptions::uo_iname(uo));
@@ -463,6 +461,40 @@ compiler, rather than parsed from the source.)
     Emit::holster_iname(VH, val_iname);
 
+

§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: +

+ +
+typedef struct cached_understanding {
+    struct wording understanding_text;  word range of the understanding text
+    struct inter_name *cu_iname;  function to test this
+    CLASS_DEFINITION
+} cached_understanding;
+
+void CompileRvalues::compile_understanding(inter_ti *val1, inter_ti *val2, wording W) {
+    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);
+        }
+    }
+}
+
+ 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_state EmitArrays::begin(inter_name *name, kind *K) {
+packaging_state EmitArrays::begin(inter_name *name, kind *K) {
     packaging_state save = Packaging::enter_home_of(name);
     EmitArrays::begin_inner(name, K, FALSE);
     return save;
@@ -181,13 +181,13 @@ which would be a typesafe list in I7, so they can be absolutely any data,
     EmitArrays::entry_inner(v1, v2);
 }
 
-void EmitArrays::dword_entry(text_stream *content) {
+void EmitArrays::dword_entry(text_stream *content) {
     inter_ti v1 = 0, v2 = 0;
     Produce::dword_value(Emit::tree(), &v1, &v2, content);
     EmitArrays::entry_inner(v1, v2);
 }
 
-void EmitArrays::plural_dword_entry(text_stream *content) {
+void EmitArrays::plural_dword_entry(text_stream *content) {
     inter_ti v1 = 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.
 

-void EmitArrays::end(packaging_state save) {
+void EmitArrays::end(packaging_state save) {
     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.
  • -void EmitCode::up(void) {
    +void EmitCode::up(void) {
         Produce::up(Emit::tree());
     }
    -void EmitCode::down(void) {
    +void EmitCode::down(void) {
         Produce::down(Emit::tree());
     }
     
    @@ -127,7 +127,7 @@ have made, net:

    §5. Structural.

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

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

    -void EmitCode::val_number(inter_ti N) {
    +void EmitCode::val_number(inter_ti N) {
         Produce::val(Emit::tree(), K_number, LITERAL_IVAL, N);
     }
     
    -void EmitCode::val_true(void) {
    +void EmitCode::val_true(void) {
         Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 1);
     }
     
    -void EmitCode::val_false(void) {
    +void EmitCode::val_false(void) {
         Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 0);
     }
     
    -void EmitCode::val_iname(kind *K, inter_name *iname) {
    +void EmitCode::val_iname(kind *K, inter_name *iname) {
         Produce::val_iname(Emit::tree(), K, iname);
     }
     
    -void EmitCode::val_text(text_stream *text) {
    +void EmitCode::val_text(text_stream *text) {
         Produce::val_text(Emit::tree(), text);
     }
     
    -void EmitCode::val_dword(text_stream *text) {
    +void EmitCode::val_dword(text_stream *text) {
         Produce::val_dword(Emit::tree(), text);
     }
     
    @@ -185,7 +185,7 @@ start of a function.
         Produce::val_nothing(Emit::tree());
     }
     
    -void EmitCode::val_symbol(kind *K, inter_symbol *S) {
    +void EmitCode::val_symbol(kind *K, inter_symbol *S) {
         Produce::val_symbol(Emit::tree(), K, S);
     }
     
    @@ -249,11 +249,11 @@ in such cases, this function must exist in the kits somewhere.

    -void EmitCode::ref_iname(kind *K, inter_name *iname) {
    +void EmitCode::ref_iname(kind *K, inter_name *iname) {
         Produce::ref_iname(Emit::tree(), K, iname);
     }
     
    -void EmitCode::ref_symbol(kind *K, inter_symbol *S) {
    +void EmitCode::ref_symbol(kind *K, inter_symbol *S) {
         Produce::ref_symbol(Emit::tree(), K, S);
     }
     
    @@ -261,11 +261,11 @@ in such cases, this function must exist in the kits somewhere.

    -void EmitCode::inv(inter_ti bip) {
    +void EmitCode::inv(inter_ti bip) {
         Produce::inv_primitive(Emit::tree(), bip);
     }
     
    -void EmitCode::call(inter_name *fn_iname) {
    +void EmitCode::call(inter_name *fn_iname) {
         Produce::inv_call_iname(Emit::tree(), fn_iname);
     }
     
    @@ -304,20 +304,20 @@ advance:
     

    -inter_symbol *EmitCode::reserve_label(text_stream *identifier) {
    +inter_symbol *EmitCode::reserve_label(text_stream *identifier) {
         return Produce::reserve_label(Emit::tree(), identifier);
     }
     
    -void EmitCode::place_label(inter_symbol *lab_s) {
    +void EmitCode::place_label(inter_symbol *lab_s) {
         Produce::place_label(Emit::tree(), lab_s);
     }
     
    -void EmitCode::lab(inter_symbol *L) {
    +void EmitCode::lab(inter_symbol *L) {
         Produce::lab(Emit::tree(), L);
     }
     
    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. return Packaging::enclosure(Emit::tree()); } -packaging_state Emit::new_packaging_state(void) { +packaging_state Emit::new_packaging_state(void) { return Packaging::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())); } -void Emit::to_value_pair(inter_ti *v1, inter_ti *v2, inter_name *iname) { +void Emit::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". }
    diff --git a/docs/runtime-module/2-gpr.html b/docs/runtime-module/2-gpr.html new file mode 100644 index 000000000..b8f835a3f --- /dev/null +++ b/docs/runtime-module/2-gpr.html @@ -0,0 +1,266 @@ + + + + General Parsing Routines + + + + + + + + + + + + + + + + + + +
    + + +

    To compile "general parsing routines", or GPRs, which are runtime functions used to match noun phrases in the command parser.

    + +
    + +

    §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: +

    + +
    +typedef struct gpr_kit {
    +    inter_symbol *cur_addr_s;
    +    inter_symbol *cur_len_s;
    +    inter_symbol *cur_word_s;
    +    inter_symbol *f_s;
    +    inter_symbol *g_s;
    +    inter_symbol *group_wn_s;
    +    inter_symbol *instance_s;
    +    inter_symbol *matched_number_s;
    +    inter_symbol *mid_word_s;
    +    inter_symbol *n_s;
    +    inter_symbol *original_wn_s;
    +    inter_symbol *pass_s;
    +    inter_symbol *pass1_n_s;
    +    inter_symbol *pass2_n_s;
    +    inter_symbol *range_from_s;
    +    inter_symbol *range_words_s;
    +    inter_symbol *rv_s;
    +    local_variable *rv_lv;
    +    inter_symbol *sgn_s;
    +    inter_symbol *spn_s;
    +    inter_symbol *ss_s;
    +    inter_symbol *tot_s;
    +    inter_symbol *try_from_wn_s;
    +    inter_symbol *v_s;
    +    inter_symbol *w_s;
    +    inter_symbol *wpos_s;
    +    inter_symbol *x_s;
    +} gpr_kit;
    +
    +
    • The structure gpr_kit is accessed in 5/lp, 6/pnp, 7/cg, 7/cgl, 7/tpv and here.
    +

    §3. The idea is to create a new kit which is initially empty: +

    + +
    +gpr_kit GPRs::new_kit(void) {
    +    gpr_kit kit;
    +    kit.cur_addr_s = NULL;
    +    kit.cur_len_s = NULL;
    +    kit.cur_word_s = NULL;
    +    kit.f_s = NULL;
    +    kit.g_s = NULL;
    +    kit.group_wn_s = NULL;
    +    kit.instance_s = NULL;
    +    kit.matched_number_s = NULL;
    +    kit.mid_word_s = NULL;
    +    kit.n_s = NULL;
    +    kit.original_wn_s = NULL;
    +    kit.pass_s = NULL;
    +    kit.pass1_n_s = NULL;
    +    kit.pass2_n_s = NULL;
    +    kit.range_from_s = NULL;
    +    kit.range_words_s = NULL;
    +    kit.rv_s = NULL;
    +    kit.rv_lv = NULL;
    +    kit.sgn_s = NULL;
    +    kit.spn_s = NULL;
    +    kit.ss_s = NULL;
    +    kit.tot_s = NULL;
    +    kit.try_from_wn_s = NULL;
    +    kit.v_s = NULL;
    +    kit.w_s = NULL;
    +    kit.wpos_s = NULL;
    +    kit.x_s = NULL;
    +    return kit;
    +}
    +
    +

    §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. +

    + +
    +void GPRs::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);
    +}
    +
    +void GPRs::add_instance_var(gpr_kit *kit) {
    +    kit->instance_s = LocalVariables::new_other_as_symbol(I"instance");
    +}
    +
    +void GPRs::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");
    +}
    +
    +void GPRs::add_original_var(gpr_kit *kit) {
    +    kit->original_wn_s = LocalVariables::new_internal_as_symbol(I"original_wn");
    +}
    +
    +void GPRs::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");
    +}
    +
    +void GPRs::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-hnae.html b/docs/runtime-module/2-hnae.html index 6bae15325..40b074450 100644 --- a/docs/runtime-module/2-hnae.html +++ b/docs/runtime-module/2-hnae.html @@ -130,7 +130,7 @@ ever change our minds about that. }
    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. enum NOUN_FILTER_FN_HL enum PARSE_NAMES_HAP enum PARSE_NAME_FN_HL -enum PARSE_NAME_DASH_FN_HL enum SCOPE_FILTERS_HAP enum SCOPE_FILTER_FN_HL enum SLASH_TOKENS_HAP @@ -725,6 +724,8 @@ that the compiler can refer to it. enum VERB_DIRECTIVE_SLASH_HL enum VERB_DIRECTIVE_SPECIAL_HL enum VERB_DIRECTIVE_TOPIC_HL +enum OBJECT_NOUNS_HAP +enum NAME_ARRAY_HL enum COMMANDS_HAP enum VERB_DECLARATION_ARRAY_HL enum MISTAKEACTION_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_END H_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_END H_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_END H_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_END H_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.,
    -inter_name *Hierarchy::find(int id) {
    +inter_name *Hierarchy::find(int id) {
         return HierarchyLocations::find(Emit::tree(), id);
     }
     
    @@ -1637,7 +1640,7 @@ package holding it. (P

    -inter_name *Hierarchy::make_iname_in(int id, package_request *P) {
    +inter_name *Hierarchy::make_iname_in(int id, package_request *P) {
         return HierarchyLocations::find_in_package(Emit::tree(), id, P, EMPTY_WORDING,
             NULL, -1, NULL);
     }
    @@ -1739,11 +1742,11 @@ such _kind pack
     

    -package_request *Hierarchy::local_package(int hap_id) {
    +package_request *Hierarchy::local_package(int hap_id) {
         return Hierarchy::local_package_to(hap_id, current_sentence);
     }
     
    -package_request *Hierarchy::local_package_to(int hap_id, parse_node *at) {
    +package_request *Hierarchy::local_package_to(int hap_id, parse_node *at) {
         return HierarchyLocations::attach_new_package(Emit::tree(),
             CompilationUnits::find(at), NULL, hap_id);
     }
    @@ -1753,11 +1756,11 @@ compilation unit is meant: that's why it's "synoptic".
     

    -package_request *Hierarchy::synoptic_package(int hap_id) {
    +package_request *Hierarchy::synoptic_package(int hap_id) {
         return HierarchyLocations::attach_new_package(Emit::tree(), NULL, NULL, hap_id);
     }
     
    -package_request *Hierarchy::completion_package(int hap_id) {
    +package_request *Hierarchy::completion_package(int hap_id) {
         return HierarchyLocations::attach_new_package(Emit::tree(), NULL, NULL, hap_id);
     }
     
    @@ -1780,7 +1783,7 @@ will automatically trip, in order to enforce the layout rules.

    -package_request *Hierarchy::package_within(int hap_id, package_request *super) {
    +package_request *Hierarchy::package_within(int hap_id, package_request *super) {
         return HierarchyLocations::attach_new_package(Emit::tree(), NULL, super, hap_id);
     }
     
    @@ -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.
    • This code is used in §4.
    diff --git a/docs/runtime-module/2-kd.html b/docs/runtime-module/2-kd.html index deea13fb8..abff49bf6 100644 --- a/docs/runtime-module/2-kd.html +++ b/docs/runtime-module/2-kd.html @@ -333,7 +333,7 @@ source text.
    • This code is used in §9.
    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.
    • This code is used in §6.2.
    diff --git a/docs/runtime-module/2-sn.html b/docs/runtime-module/2-sn.html index de9368986..dc919931b 100644 --- a/docs/runtime-module/2-sn.html +++ b/docs/runtime-module/2-sn.html @@ -232,7 +232,7 @@ short name, and FALSE<
    • This code is used in §4.
    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.
    • This code is used in §1.
    diff --git a/docs/runtime-module/2-th.html b/docs/runtime-module/2-th.html index e1ca76f2f..332136111 100644 --- a/docs/runtime-module/2-th.html +++ b/docs/runtime-module/2-th.html @@ -216,7 +216,7 @@ in Flex (in BasicInformK } diff --git a/docs/runtime-module/3-gm.html b/docs/runtime-module/3-gm.html index a089e4926..018caa5c6 100644 --- a/docs/runtime-module/3-gm.html +++ b/docs/runtime-module/3-gm.html @@ -190,7 +190,7 @@ in the VM can be added to it without it becoming negative. } diff --git a/docs/runtime-module/5-ins.html b/docs/runtime-module/5-ins.html index fdd08751e..53d208569 100644 --- a/docs/runtime-module/5-ins.html +++ b/docs/runtime-module/5-ins.html @@ -96,7 +96,7 @@ function togglePopup(material_id) { return I->icd.instance_iname; } -package_request *RTInstances::package(instance *I) { +package_request *RTInstances::package(instance *I) { return I->icd.instance_package; } diff --git a/docs/runtime-module/5-kc.html b/docs/runtime-module/5-kc.html index d4814f8fb..14e0dcf54 100644 --- a/docs/runtime-module/5-kc.html +++ b/docs/runtime-module/5-kc.html @@ -190,7 +190,7 @@ of the kind which the constructor makes:

    -inter_name *RTKindConstructors::get_kind_GPR_iname(kind *K) {
    +inter_name *RTKindConstructors::get_kind_GPR_iname(kind *K) {
         if (K == NULL) return NULL;
         kind_constructor *kc = Kinds::get_construct(K);
         if (kc->compilation_data.kind_GPR_iname == NULL) {
    @@ -201,7 +201,7 @@ of the kind which the constructor makes:
         return kc->compilation_data.kind_GPR_iname;
     }
     
    -inter_name *RTKindConstructors::get_instance_GPR_iname(kind *K) {
    +inter_name *RTKindConstructors::get_instance_GPR_iname(kind *K) {
         if (K == NULL) return NULL;
         kind_constructor *kc = Kinds::get_construct(K);
         if (kc->compilation_data.instance_GPR_iname == NULL) {
    @@ -346,14 +346,14 @@ of the kind which the constructor makes:
         return K->construct->compilation_data.debug_print_fn_iname;
     }
     
    -inter_name *RTKindConstructors::get_explicit_I6_GPR_iname(kind *K) {
    +inter_name *RTKindConstructors::get_explicit_I6_GPR_iname(kind *K) {
         if (K == NULL) internal_error("RTKindConstructors::get_explicit_I6_GPR on null kind");
         if (Str::len(K->construct->explicit_GPR_identifier) > 0)
             return Produce::find_by_name(Emit::tree(), K->construct->explicit_GPR_identifier);
         return NULL;
     }
     
    -inter_name *RTKindConstructors::get_distinguisher_iname(kind *K) {
    +inter_name *RTKindConstructors::get_distinguisher_iname(kind *K) {
         text_stream *N = Kinds::Behaviour::get_distinguisher(K);
         if (N == NULL) return NULL;
         return Produce::find_by_name(Emit::tree(), N);
    @@ -392,7 +392,7 @@ not, it returns NULL
     
     
    -int RTKindConstructors::offers_I6_GPR(kind *K) {
    +int RTKindConstructors::offers_I6_GPR(kind *K) {
         if (K == NULL) return FALSE;
         return KindConstructors::offers_I6_GPR(K->construct);
     }
    @@ -432,7 +432,7 @@ parsing names of objects, but not as a grammar token in its own right.
         return K->construct->recognition_routine;
     }
     
    -inter_name *RTKindConstructors::get_recognition_only_GPR_as_iname(kind *K) {
    +inter_name *RTKindConstructors::get_recognition_only_GPR_as_iname(kind *K) {
         text_stream *N = RTKindConstructors::get_recognition_only_GPR(K);
         if (N == NULL) return NULL;
         return Produce::find_by_name(Emit::tree(), N);
    diff --git a/docs/runtime-module/5-lp.html b/docs/runtime-module/5-lp.html
    index 51e8c0d6f..f544e9ac7 100644
    --- a/docs/runtime-module/5-lp.html
    +++ b/docs/runtime-module/5-lp.html
    @@ -402,10 +402,10 @@ sets the parsed_number
     
         inter_name *iname = RTLiteralPatterns::parse_fn_iname(lp);
         packaging_state save = Functions::begin(iname);
    -    gpr_kit gprk = UnderstandValueTokens::new_kit();
    -    UnderstandValueTokens::add_original(&gprk);
    -    UnderstandValueTokens::add_standard_set(&gprk);
    -    UnderstandValueTokens::add_lp_vars(&gprk);
    +    gpr_kit gprk = GPRs::new_kit();
    +    GPRs::add_original_var(&gprk);
    +    GPRs::add_standard_vars(&gprk);
    +    GPRs::add_LP_vars(&gprk);
         inter_symbol *succeeded_label = EmitCode::reserve_label(I".Succeeded");
         inter_symbol *failed_label = EmitCode::reserve_label(I".Failed");
         Match the literal pattern4.2.1;
    diff --git a/docs/runtime-module/5-prp.html b/docs/runtime-module/5-prp.html
    index c4a3c904a..a867791bc 100644
    --- a/docs/runtime-module/5-prp.html
    +++ b/docs/runtime-module/5-prp.html
    @@ -121,7 +121,7 @@ package already supplied:
         return prn->compilation_data.prop_package;
     }
     
    -inter_name *RTProperties::iname(property *prn) {
    +inter_name *RTProperties::iname(property *prn) {
         if (prn == NULL) internal_error("tried to find iname for null property");
         if ((Properties::is_either_or(prn)) && (prn->compilation_data.store_in_negation))
             return RTProperties::iname(EitherOrProperties::get_negation(prn));
    @@ -183,7 +183,7 @@ kit, we'll have to use that one.
     

    -int RTProperties::stored_in_negation(property *prn) {
    +int RTProperties::stored_in_negation(property *prn) {
         if ((prn == NULL) || (prn->either_or_data == NULL))
             internal_error("non-EO property");
         return prn->compilation_data.store_in_negation;
    diff --git a/docs/runtime-module/5-tbl.html b/docs/runtime-module/5-tbl.html
    index ca0c1b8ea..4b7a5b6ff 100644
    --- a/docs/runtime-module/5-tbl.html
    +++ b/docs/runtime-module/5-tbl.html
    @@ -311,7 +311,7 @@ used to define new kinds; in this case it doesn't matter what we write, but
             if (bits & TB_COLUMN_TOPIC) {
                 inter_ti v1 = 0, v2 = 0;
                 wording W = Node::get_text(cell);
    -            RTParsing::compile_understanding(&v1, &v2, W);
    +            CompileRvalues::compile_understanding(&v1, &v2, W);
                 EmitArrays::generic_entry(v1, v2);
             } else {
             #endif
    diff --git a/docs/runtime-module/5-vrb.html b/docs/runtime-module/5-vrb.html
    index 81e821e8b..0622068a9 100644
    --- a/docs/runtime-module/5-vrb.html
    +++ b/docs/runtime-module/5-vrb.html
    @@ -175,9 +175,13 @@ constant or a global variable in Inter:
     

    -void RTVariables::store_in_this_iname(nonlocal_variable *nlv, inter_name *iname) {
    +void RTVariables::store_in_this_iname(nonlocal_variable *nlv, inter_name *iname) {
         RTVariables::set_NVE(nlv, RTVariables::nve_from_iname(iname));
     }
    +
    +void RTVariables::understood_variable(nonlocal_variable *nlv) {
    +    RTVariables::store_in_this_iname(nlv, Hierarchy::find(PARSED_NUMBER_HL));
    +}
     

    §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.

    + +

    §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. +

    -void RTParsing::understood_variable(nonlocal_variable *var) {
    -    RTVariables::store_in_this_iname(var, Hierarchy::find(PARSED_NUMBER_HL));
    +typedef struct parsing_compilation_data {
    +    struct package_request *parsing_package;
    +    struct inter_name *name_array_iname;
    +    struct inter_name *parse_name_fn_iname;
    +} parsing_compilation_data;
    +
    +
    • The structure parsing_compilation_data is private to this section.
    +

    §2. I will be / PCD: +

    + +
    +parsing_compilation_data Name::new_compilation_data(inference_subject *subj) {
    +    parsing_compilation_data pcd;
    +    pcd.parsing_package = NULL;
    +    pcd.name_array_iname = NULL;
    +    pcd.parse_name_fn_iname = NULL;
    +    return pcd;
     }
     
    -

    §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.

    -parse_node *RTParsing::name_property_array(instance *I, wording W, wording PW,
    +package_request *Name::package(inference_subject *subj) {
    +    if (PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parsing_package == NULL)
    +        PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parsing_package =
    +            Hierarchy::completion_package(OBJECT_NOUNS_HAP);
    +    return PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parsing_package;
    +}
    +
    +inter_name *Name::get_name_array_iname(inference_subject *subj) {
    +    if (PARSING_DATA_FOR_SUBJ(subj)->compilation_data.name_array_iname == NULL)
    +        PARSING_DATA_FOR_SUBJ(subj)->compilation_data.name_array_iname =
    +            Hierarchy::make_iname_in(NAME_ARRAY_HL, Name::package(subj));
    +    return PARSING_DATA_FOR_SUBJ(subj)->compilation_data.name_array_iname;
    +}
    +
    +inter_name *Name::get_parse_name_fn_iname(inference_subject *subj) {
    +    if (PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parse_name_fn_iname == NULL)
    +        PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parse_name_fn_iname =
    +            Hierarchy::make_iname_in(PARSE_NAME_FN_HL, Name::package(subj));
    +    return PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parse_name_fn_iname;
    +}
    +
    +

    §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, wording W, wording PW,
         int from_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_state save = 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) {
                 int additional = 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);
         return Rvalues::from_iname(name_array);
     }
    -
    -inter_name *RTParsing::name_iname(void) {
    -    return RTProperties::iname(ParsingPlugin::name_property());
    -}
     
    -

    §3. We cache grammar occurring in the source text in conditions, and so forth: -

    - -
    -typedef struct cached_understanding {
    -    struct wording understanding_text;  word range of the understanding text
    -    struct inter_name *cu_iname;  the runtime name for this Consult_Grammar_N routine
    -    CLASS_DEFINITION
    -} cached_understanding;
    -
    -
    -void RTParsing::compile_understanding(inter_ti *val1, inter_ti *val2, wording W) {
    -    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) {
    - + -

    To compile I6 general parsing routines (GPRs) and/or |parse_name| properties as required by the I7 grammar.

    + +

    Functions which are values of the parse_name property for objects.

    -
    +
    -

    §1. Definitions.

    - -
    -typedef struct parse_name_notice {
    -    struct inter_name *pnn_iname;
    -    struct inference_subject *parse_subject;
    -    CLASS_DEFINITION
    -} parse_name_notice;
    -
    -
    • 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.

    -inter_name *UnderstandGeneralTokens::consult_iname(command_grammar *cg) {
    -    if (cg == NULL) return NULL;
    -    if (cg->compilation_data.cg_consult_iname == NULL) {
    -        current_sentence = cg->where_cg_created;
    -        package_request *PR = Hierarchy::local_package(CONSULT_TOKENS_HAP);
    -        cg->compilation_data.cg_consult_iname = Hierarchy::make_iname_in(CONSULT_FN_HL, PR);
    -    }
    -    return cg->compilation_data.cg_consult_iname;
    -}
    -
    -

    §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. -

    - -
    -inter_name *UnderstandGeneralTokens::get_gv_parse_name(command_grammar *cg) {
    -    if (cg->compilation_data.cg_parse_name_iname == NULL) {
    -        package_request *PR = Hierarchy::local_package_to(PARSE_NAMES_HAP, cg->where_cg_created);
    -        cg->compilation_data.cg_parse_name_iname = Hierarchy::make_iname_in(PARSE_NAME_FN_HL, PR);
    -    }
    -    return cg->compilation_data.cg_parse_name_iname;
    -}
    -
    -inter_name *UnderstandGeneralTokens::compile_parse_name_property(inference_subject *subj) {
    -    inter_name *symb = NULL;
    -    command_grammar *cg = PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object;
    +inter_name *ParseName::compile_if_needed(inference_subject *subj) {
    +    inter_name *iname = Name::get_parse_name_fn_iname(subj);
    +    command_grammar *cg = PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject;
         if (CommandGrammars::is_empty(cg) == FALSE) {
    -        symb = UnderstandGeneralTokens::get_gv_parse_name(cg);
    -    } else {
    -        if (Visibility::any_property_visible_to_subject(subj, FALSE)) {
    -            parse_name_notice *notice = CREATE(parse_name_notice);
    -            package_request *PR = Hierarchy::local_package_to(PARSE_NAMES_HAP, subj->infs_created_at);
    -            notice->pnn_iname = Hierarchy::make_iname_in(PARSE_NAME_DASH_FN_HL, PR);
    -            notice->parse_subject = subj;
    -            symb = notice->pnn_iname;
    -        }
    +        text_stream *desc = Str::new();
    +        wording W = InferenceSubjects::get_name_text(subj);
    +        WRITE_TO(desc, "grammar-parsing GPR for '%W'", W);
    +        Sequence::queue(&ParseName::parser_agent,
    +            STORE_POINTER_inference_subject(subj), desc);
    +        return iname;
         }
    -    return symb;
    -}
    -
    -void UnderstandGeneralTokens::write_parse_name_routines(void) {
    -    parse_name_notice *notice;
    -    LOOP_OVER(notice, parse_name_notice) {
    -        gpr_kit gprk = UnderstandValueTokens::new_kit();
    -        packaging_state save = Emit::new_packaging_state();
    -        if (UnderstandGeneralTokens::compile_parse_name_head(&save, &gprk,
    -            notice->parse_subject, NULL, notice->pnn_iname)) {
    -            UnderstandGeneralTokens::compile_parse_name_tail(&gprk);
    -            Functions::end(save);
    -        }
    +    if (Visibility::any_property_visible_to_subject(subj, FALSE)) {
    +        text_stream *desc = Str::new();
    +        wording W = InferenceSubjects::get_name_text(subj);
    +        WRITE_TO(desc, "distinguish-only GPR for '%W'", W);
    +        Sequence::queue(&ParseName::distinguisher_agent,
    +            STORE_POINTER_inference_subject(subj), desc);
    +        return iname;
         }
    +    return NULL;
     }
     
    -

    §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.

    -int UnderstandGeneralTokens::compile_parse_name_head(packaging_state *save,
    -    gpr_kit *gprk, inference_subject *subj,
    -    command_grammar *cg, inter_name *rname) {
    -    int test_distinguishability = FALSE, sometimes_has_visible_properties = FALSE;
    -    inter_name *N = NULL;
    -
    -    if (subj == NULL) internal_error("compiling parse_name head for null subj");
    -
    -    if (cg) {
    -        sometimes_has_visible_properties =
    -            Visibility::any_property_visible_to_subject(subj, TRUE);
    -        N = UnderstandGeneralTokens::get_gv_parse_name(cg);
    -    } else {
    -        if (Visibility::any_property_visible_to_subject(subj, FALSE)
    -            == FALSE) return FALSE;
    -    }
    -
    -    if (KindSubjects::to_kind(subj)) test_distinguishability = TRUE;
    -
    -    inter_name *compile_to = rname;
    -    if (compile_to == NULL) compile_to = N;
    -    if (compile_to == NULL) internal_error("no parse name routine name given");
    -
    -    *save = Functions::begin(compile_to);
    -
    -    UnderstandValueTokens::add_parse_name_vars(gprk);
    -
    -    UnderstandGeneralTokens::top_of_head(gprk, N, subj,
    -        test_distinguishability, sometimes_has_visible_properties, rname);
    -    return TRUE;
    +void ParseName::distinguisher_agent(compilation_subtask *t) {
    +    inference_subject *subj = RETRIEVE_POINTER_inference_subject(t->data);
    +    gpr_kit kit = GPRs::new_kit();
    +    packaging_state save = Functions::begin(Name::get_parse_name_fn_iname(subj));
    +    ParseName::compile_head(&kit, subj, FALSE);
    +    ParseName::compile_tail(&kit);
    +    Functions::end(save);
     }
     
    -

    §6. The following multi-pass approach checks the possible patterns: +

    §3. This one can be much more elaborate, but is still simple to compile because +all of the work is delegated:

    -
    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 }
    diff --git a/docs/runtime-module/7-cg.html b/docs/runtime-module/7-cg.html index 2c2df8001..1e9b9105e 100644 --- a/docs/runtime-module/7-cg.html +++ b/docs/runtime-module/7-cg.html @@ -122,7 +122,7 @@ function togglePopup(material_id) { global_compilation_settings.no_verb_verb_exists = TRUE; } -
    • 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.)

    -void RTCommandGrammars::cg_compile_parse_name_lines(gpr_kit *gprk, command_grammar *cg) {
    +void RTCommandGrammars::cg_compile_parse_name_lines(gpr_kit *gprk, command_grammar *cg) {
         inference_subject *subj = cg->subj_understood;
     
    -    if (PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object != cg)
    +    if (PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject != cg)
             internal_error("link between subject and CG broken");
     
         LOGIF(GRAMMAR, "Parse_name content for $j:\n", subj);
    -    RTCommandGrammars::cg_compile_lines(gprk, PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object);
    +    RTCommandGrammars::cg_compile_lines(gprk, PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject);
     
         inference_subject *infs;
         for (infs = InferenceSubjects::narrowest_broader_subject(subj);
             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) {
                     LOGIF(GRAMMAR, "And parse_name content inherited from $j:\n", infs);
    -                RTCommandGrammars::cg_compile_lines(gprk, PARSING_DATA_FOR_SUBJ(infs)->understand_as_this_object);
    +                RTCommandGrammars::cg_compile_lines(gprk, PARSING_DATA_FOR_SUBJ(infs)->understand_as_this_subject);
                 }
         }
     }
    @@ -341,7 +341,7 @@ next priority, and so on up the hierarchy.
         RTCommandGrammarLines::reset_labels();
         switch(cg->cg_is) {
             case CG_IS_COMMAND: {
    -            package_request *PR = Hierarchy::synoptic_package(COMMANDS_HAP);
    +            package_request *PR = Hierarchy::completion_package(COMMANDS_HAP);
                 inter_name *array_iname = Hierarchy::make_iname_in(VERB_DECLARATION_ARRAY_HL, PR);
                 packaging_state save = RTCommandGrammars::cg_compile_Verb_directive_header(cg, array_iname);
                 RTCommandGrammars::cg_compile_lines(NULL, cg);
    @@ -349,11 +349,11 @@ next priority, and so on up the hierarchy.
                 break;
             }
             case CG_IS_TOKEN: {
    -            gpr_kit gprk = UnderstandValueTokens::new_kit();
    +            gpr_kit gprk = GPRs::new_kit();
                 if (cg->compilation_data.cg_token_iname == NULL) internal_error("cg token not ready");
                 packaging_state save = Functions::begin(cg->compilation_data.cg_token_iname);
    -            UnderstandValueTokens::add_original(&gprk);
    -            UnderstandValueTokens::add_standard_set(&gprk);
    +            GPRs::add_original_var(&gprk);
    +            GPRs::add_standard_vars(&gprk);
                 EmitCode::inv(STORE_BIP);
                 EmitCode::down();
                     EmitCode::ref_symbol(K_value, gprk.original_wn_s);
    @@ -373,12 +373,12 @@ next priority, and so on up the hierarchy.
                 break;
             }
             case CG_IS_CONSULT: {
    -            gpr_kit gprk = UnderstandValueTokens::new_kit();
    -            inter_name *iname = UnderstandGeneralTokens::consult_iname(cg);
    +            gpr_kit gprk = GPRs::new_kit();
    +            inter_name *iname = RTCommandGrammars::consult_iname(cg);
                 packaging_state save = Functions::begin(iname);
    -            UnderstandValueTokens::add_range_calls(&gprk);
    -            UnderstandValueTokens::add_original(&gprk);
    -            UnderstandValueTokens::add_standard_set(&gprk);
    +            GPRs::add_range_vars(&gprk);
    +            GPRs::add_original_var(&gprk);
    +            GPRs::add_standard_vars(&gprk);
                 EmitCode::inv(STORE_BIP);
                 EmitCode::down();
                     EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL));
    @@ -402,25 +402,17 @@ next priority, and so on up the hierarchy.
                 Functions::end(save);
                 break;
             }
    -        case CG_IS_SUBJECT: {
    -            gpr_kit gprk = UnderstandValueTokens::new_kit();
    -            packaging_state save = Emit::new_packaging_state();
    -            if (UnderstandGeneralTokens::compile_parse_name_head(&save, &gprk, cg->subj_understood, cg, NULL)) {
    -                RTCommandGrammars::cg_compile_parse_name_lines(&gprk, cg);
    -                UnderstandGeneralTokens::compile_parse_name_tail(&gprk);
    -                Functions::end(save);
    -            }
    +        case CG_IS_SUBJECT:
                 break;
    -        }
             case CG_IS_VALUE:
                 internal_error("iv");
                 break;
             case CG_IS_PROPERTY_NAME: {
    -            gpr_kit gprk = UnderstandValueTokens::new_kit();
    +            gpr_kit gprk = GPRs::new_kit();
                 if (cg->compilation_data.cg_prn_iname == NULL) internal_error("PRN PN not ready");
                 packaging_state save = Functions::begin(cg->compilation_data.cg_prn_iname);
    -            UnderstandValueTokens::add_original(&gprk);
    -            UnderstandValueTokens::add_standard_set(&gprk);
    +            GPRs::add_original_var(&gprk);
    +            GPRs::add_standard_vars(&gprk);
                 EmitCode::inv(STORE_BIP);
                 EmitCode::down();
                     EmitCode::ref_symbol(K_value, gprk.original_wn_s);
    @@ -456,8 +448,29 @@ next priority, and so on up the hierarchy.
         CompileValues::to_code_val(gty->term[0].what);
     }
     
    +

    §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. +

    + +
    +inter_name *RTCommandGrammars::consult_iname(command_grammar *cg) {
    +    if (cg == NULL) return NULL;
    +    if (cg->compilation_data.cg_consult_iname == NULL) {
    +        current_sentence = cg->where_cg_created;
    +        package_request *PR = Hierarchy::local_package(CONSULT_TOKENS_HAP);
    +        cg->compilation_data.cg_consult_iname = Hierarchy::make_iname_in(CONSULT_FN_HL, PR);
    +    }
    +    return cg->compilation_data.cg_consult_iname;
    +}
    +
    diff --git a/docs/runtime-module/7-cgl.html b/docs/runtime-module/7-cgl.html index dc170501e..9725c6aaa 100644 --- a/docs/runtime-module/7-cgl.html +++ b/docs/runtime-module/7-cgl.html @@ -509,7 +509,7 @@ command CGs) have not yet been type-checked, whereas all others have. EmitCode::up(); break; case CG_IS_SUBJECT: - UnderstandGeneralTokens::after_gl_failed(gprk, fail_label, cgl->pluralised); + ParseName::compile_reset_code_after_failed_line(gprk, fail_label, cgl->pluralised); break; case CG_IS_VALUE: EmitCode::inv(STORE_BIP); @@ -710,9 +710,9 @@ command CGs) have not yet been type-checked, whereas all others have. slash_gpr *sgpr; LOOP_OVER(sgpr, slash_gpr) { packaging_state save = Functions::begin(sgpr->sgpr_iname); - gpr_kit gprk = UnderstandValueTokens::new_kit(); - UnderstandValueTokens::add_original(&gprk); - UnderstandValueTokens::add_standard_set(&gprk); + gpr_kit gprk = GPRs::new_kit(); + GPRs::add_original_var(&gprk); + GPRs::add_standard_vars(&gprk); RTCommandGrammarLines::compile_token_line(&gprk, TRUE, sgpr->first_choice, sgpr->last_choice, CG_IS_TOKEN, FALSE, NULL, NULL, gprk.group_wn_s, NULL); EmitCode::inv(RETURN_BIP); @@ -1635,7 +1635,7 @@ nothing else. diff --git a/docs/runtime-module/7-epv.html b/docs/runtime-module/7-epv.html index acb9acb04..e0fd3544d 100644 --- a/docs/runtime-module/7-epv.html +++ b/docs/runtime-module/7-epv.html @@ -325,7 +325,7 @@ the following.

    -void RTPropertyValues::emit_iname_has_property(kind *K, inter_name *N, property *prn) {
    +void RTPropertyValues::emit_iname_has_property(kind *K, inter_name *N, property *prn) {
         RTPropertyValues::emit_has_property(K, InterNames::to_symbol(N), prn);
     }
     void RTPropertyValues::emit_has_property(kind *K, inter_symbol *S, property *prn) {
    @@ -529,7 +529,7 @@ and it seems best to reject the extra complexity needed.
     }
     
    diff --git a/docs/runtime-module/7-gng.html b/docs/runtime-module/7-gng.html index eb1a4aebf..1e307e0ac 100644 --- a/docs/runtime-module/7-gng.html +++ b/docs/runtime-module/7-gng.html @@ -135,7 +135,7 @@ } diff --git a/docs/runtime-module/7-ic.html b/docs/runtime-module/7-ic.html index 134f57d75..c9a9545c2 100644 --- a/docs/runtime-module/7-ic.html +++ b/docs/runtime-module/7-ic.html @@ -502,7 +502,7 @@ constants, and use the Link constants to progress; we stop at } diff --git a/docs/runtime-module/7-nft.html b/docs/runtime-module/7-nft.html index 022a902a8..84caf6cad 100644 --- a/docs/runtime-module/7-nft.html +++ b/docs/runtime-module/7-nft.html @@ -352,7 +352,7 @@ that's why.) } diff --git a/docs/runtime-module/7-tpv.html b/docs/runtime-module/7-tpv.html index 2ecfbebd1..da5666d40 100644 --- a/docs/runtime-module/7-tpv.html +++ b/docs/runtime-module/7-tpv.html @@ -75,124 +75,13 @@ function togglePopup(material_id) {

    §1.

    -typedef struct gpr_kit {
    -    inter_symbol *cur_addr_s;
    -    inter_symbol *cur_len_s;
    -    inter_symbol *cur_word_s;
    -    inter_symbol *f_s;
    -    inter_symbol *g_s;
    -    inter_symbol *group_wn_s;
    -    inter_symbol *instance_s;
    -    inter_symbol *matched_number_s;
    -    inter_symbol *mid_word_s;
    -    inter_symbol *n_s;
    -    inter_symbol *original_wn_s;
    -    inter_symbol *pass_s;
    -    inter_symbol *pass1_n_s;
    -    inter_symbol *pass2_n_s;
    -    inter_symbol *range_from_s;
    -    inter_symbol *range_words_s;
    -    inter_symbol *rv_s;
    -    local_variable *rv_lv;
    -    inter_symbol *sgn_s;
    -    inter_symbol *spn_s;
    -    inter_symbol *ss_s;
    -    inter_symbol *tot_s;
    -    inter_symbol *try_from_wn_s;
    -    inter_symbol *v_s;
    -    inter_symbol *w_s;
    -    inter_symbol *wpos_s;
    -    inter_symbol *x_s;
    -} gpr_kit;
     
    -gpr_kit UnderstandValueTokens::new_kit(void) {
    -    gpr_kit gprk;
    -    gprk.cur_addr_s = NULL;
    -    gprk.cur_len_s = NULL;
    -    gprk.cur_word_s = NULL;
    -    gprk.f_s = NULL;
    -    gprk.g_s = NULL;
    -    gprk.group_wn_s = NULL;
    -    gprk.instance_s = NULL;
    -    gprk.matched_number_s = NULL;
    -    gprk.mid_word_s = NULL;
    -    gprk.n_s = NULL;
    -    gprk.original_wn_s = NULL;
    -    gprk.pass_s = NULL;
    -    gprk.pass1_n_s = NULL;
    -    gprk.pass2_n_s = NULL;
    -    gprk.range_from_s = NULL;
    -    gprk.range_words_s = NULL;
    -    gprk.rv_s = NULL;
    -    gprk.rv_lv = NULL;
    -    gprk.sgn_s = NULL;
    -    gprk.spn_s = NULL;
    -    gprk.ss_s = NULL;
    -    gprk.tot_s = NULL;
    -    gprk.try_from_wn_s = NULL;
    -    gprk.v_s = NULL;
    -    gprk.w_s = NULL;
    -    gprk.wpos_s = NULL;
    -    gprk.x_s = NULL;
    -    return gprk;
    -}
    -
    -void UnderstandValueTokens::add_instance_call(gpr_kit *gprk) {
    -    gprk->instance_s = LocalVariables::new_other_as_symbol(I"instance");
    -}
    -
    -void UnderstandValueTokens::add_range_calls(gpr_kit *gprk) {
    -    gprk->range_from_s = LocalVariables::new_internal_commented_as_symbol(I"range_from", I"call parameter: word number of snippet start");
    -    gprk->range_words_s = LocalVariables::new_internal_commented_as_symbol(I"range_words", I"call parameter: snippet length");
    -}
    -
    -void UnderstandValueTokens::add_original(gpr_kit *gprk) {
    -    gprk->original_wn_s = LocalVariables::new_internal_as_symbol(I"original_wn");
    -}
    -
    -void UnderstandValueTokens::add_standard_set(gpr_kit *gprk) {
    -    gprk->group_wn_s = LocalVariables::new_internal_as_symbol(I"group_wn");
    -    gprk->v_s = LocalVariables::new_internal_as_symbol(I"v");
    -    gprk->w_s = LocalVariables::new_internal_as_symbol(I"w");
    -    gprk->rv_lv = LocalVariables::new_internal(I"rv");
    -    gprk->rv_s = LocalVariables::declare(gprk->rv_lv);
    -}
    -
    -void UnderstandValueTokens::add_lp_vars(gpr_kit *gprk) {
    -    gprk->wpos_s = LocalVariables::new_internal_as_symbol(I"wpos");
    -    gprk->mid_word_s = LocalVariables::new_internal_as_symbol(I"mid_word");
    -    gprk->matched_number_s = LocalVariables::new_internal_as_symbol(I"matched_number");
    -    gprk->cur_word_s = LocalVariables::new_internal_as_symbol(I"cur_word");
    -    gprk->cur_len_s = LocalVariables::new_internal_as_symbol(I"cur_len");
    -    gprk->cur_addr_s = LocalVariables::new_internal_as_symbol(I"cur_addr");
    -    gprk->sgn_s = LocalVariables::new_internal_as_symbol(I"sgn");
    -    gprk->tot_s = LocalVariables::new_internal_as_symbol(I"tot");
    -    gprk->f_s = LocalVariables::new_internal_as_symbol(I"f");
    -    gprk->x_s = LocalVariables::new_internal_as_symbol(I"x");
    -}
    -
    -void UnderstandValueTokens::add_parse_name_vars(gpr_kit *gprk) {
    -    gprk->original_wn_s = LocalVariables::new_internal_commented_as_symbol(I"original_wn", I"first word of text parsed");
    -    gprk->group_wn_s = LocalVariables::new_internal_commented_as_symbol(I"group_wn", I"first word matched against A/B/C/... disjunction");
    -    gprk->try_from_wn_s = LocalVariables::new_internal_commented_as_symbol(I"try_from_wn", I"position to try matching from");
    -    gprk->n_s = LocalVariables::new_internal_commented_as_symbol(I"n", I"number of words matched");
    -    gprk->f_s = LocalVariables::new_internal_commented_as_symbol(I"f", I"flag: sufficiently good match found to justify success");
    -    gprk->w_s = LocalVariables::new_internal_commented_as_symbol(I"w", I"for use by individual grammar lines");
    -    gprk->rv_lv = LocalVariables::new_internal(I"rv");
    -    gprk->rv_s = LocalVariables::declare(gprk->rv_lv);
    -    gprk->g_s = LocalVariables::new_internal_commented_as_symbol(I"g", I"temporary: success flag for parsing visibles");
    -    gprk->ss_s = LocalVariables::new_internal_commented_as_symbol(I"ss", I"temporary: saves 'self' in distinguishing visibles");
    -    gprk->spn_s = LocalVariables::new_internal_commented_as_symbol(I"spn", I"temporary: saves 'parsed_number' in parsing visibles");
    -    gprk->pass_s = LocalVariables::new_internal_commented_as_symbol(I"pass", I"pass counter (1 to 3)");
    -    gprk->pass1_n_s = LocalVariables::new_internal_commented_as_symbol(I"pass1_n", I"value of n recorded during pass 1");
    -    gprk->pass2_n_s = LocalVariables::new_internal_commented_as_symbol(I"pass2_n", I"value of n recorded during pass 2");
    -}
     
     void UnderstandValueTokens::number(void) {
         inter_name *iname = Hierarchy::find(DECIMAL_TOKEN_INNER_HL);
         packaging_state save = Functions::begin(iname);
    -    gpr_kit gprk = UnderstandValueTokens::new_kit();
    -    UnderstandValueTokens::add_original(&gprk);
    +    gpr_kit gprk = GPRs::new_kit();
    +    GPRs::add_original_var(&gprk);
         command_grammar *cg = CommandGrammars::get_parsing_grammar(K_number);
         if (cg) RTCommandGrammars::compile_iv(&gprk, cg);
         EmitCode::inv(RETURN_BIP);
    @@ -206,8 +95,8 @@ function togglePopup(material_id) {
     void UnderstandValueTokens::time(void) {
         inter_name *iname = Hierarchy::find(TIME_TOKEN_INNER_HL);
         packaging_state save = Functions::begin(iname);
    -    gpr_kit gprk = UnderstandValueTokens::new_kit();
    -    UnderstandValueTokens::add_original(&gprk);
    +    gpr_kit gprk = GPRs::new_kit();
    +    GPRs::add_original_var(&gprk);
         kind *K = TimesOfDay::kind();
         if (K) {
             command_grammar *cg = CommandGrammars::get_parsing_grammar(K);
    @@ -224,8 +113,8 @@ function togglePopup(material_id) {
     void UnderstandValueTokens::truth_state(void) {
         inter_name *iname = Hierarchy::find(TRUTH_STATE_TOKEN_INNER_HL);
         packaging_state save = Functions::begin(iname);
    -    gpr_kit gprk = UnderstandValueTokens::new_kit();
    -    UnderstandValueTokens::add_original(&gprk);
    +    gpr_kit gprk = GPRs::new_kit();
    +    GPRs::add_original_var(&gprk);
         command_grammar *cg = CommandGrammars::get_parsing_grammar(K_truth_state);
         if (cg) RTCommandGrammars::compile_iv(&gprk, cg);
         EmitCode::inv(RETURN_BIP);
    @@ -236,7 +125,7 @@ function togglePopup(material_id) {
         Hierarchy::make_available(iname);
     }
     
    -void UnderstandValueTokens::agent(compilation_subtask *t) {
    +void UnderstandValueTokens::agent(compilation_subtask *t) {
         kind *K = RETRIEVE_POINTER_kind(t->data);
             if ((Kinds::Behaviour::is_an_enumeration(K)) ||
                 (Kinds::Behaviour::is_quasinumerical(K))) {
    @@ -250,20 +139,20 @@ function togglePopup(material_id) {
                     need_lf_vars = TRUE;
                     break;
                 }
    -            gpr_kit gprk = UnderstandValueTokens::new_kit();
    -            UnderstandValueTokens::add_original(&gprk);
    -            UnderstandValueTokens::add_standard_set(&gprk);
    -            if (need_lf_vars) UnderstandValueTokens::add_lp_vars(&gprk);
    +            gpr_kit gprk = GPRs::new_kit();
    +            GPRs::add_original_var(&gprk);
    +            GPRs::add_standard_vars(&gprk);
    +            if (need_lf_vars) GPRs::add_LP_vars(&gprk);
                 Compile body of kind GPR1.1;
                 Functions::end(save);
     
                 if (Kinds::Behaviour::is_an_enumeration(K)) {
                     inter_name *iname = RTKindConstructors::get_instance_GPR_iname(K);
                     packaging_state save = Functions::begin(iname);
    -                gpr_kit gprk = UnderstandValueTokens::new_kit();
    -                UnderstandValueTokens::add_instance_call(&gprk);
    -                UnderstandValueTokens::add_original(&gprk);
    -                UnderstandValueTokens::add_standard_set(&gprk);
    +                gpr_kit gprk = GPRs::new_kit();
    +                GPRs::add_instance_var(&gprk);
    +                GPRs::add_original_var(&gprk);
    +                GPRs::add_standard_vars(&gprk);
                     GV_IS_VALUE_instance_mode = TRUE;
                     Compile body of kind GPR1.1;
                     GV_IS_VALUE_instance_mode = FALSE;
    @@ -288,20 +177,20 @@ function togglePopup(material_id) {
                     need_lf_vars = TRUE;
                     break;
                 }
    -            gpr_kit gprk = UnderstandValueTokens::new_kit();
    -            UnderstandValueTokens::add_original(&gprk);
    -            UnderstandValueTokens::add_standard_set(&gprk);
    -            if (need_lf_vars) UnderstandValueTokens::add_lp_vars(&gprk);
    +            gpr_kit gprk = GPRs::new_kit();
    +            GPRs::add_original_var(&gprk);
    +            GPRs::add_standard_vars(&gprk);
    +            if (need_lf_vars) GPRs::add_LP_vars(&gprk);
                 Compile body of kind GPR1.1;
                 Functions::end(save);
     
                 if (Kinds::Behaviour::is_an_enumeration(K)) {
                     inter_name *iname = RTKindConstructors::get_instance_GPR_iname(K);
                     packaging_state save = Functions::begin(iname);
    -                gpr_kit gprk = UnderstandValueTokens::new_kit();
    -                UnderstandValueTokens::add_instance_call(&gprk);
    -                UnderstandValueTokens::add_original(&gprk);
    -                UnderstandValueTokens::add_standard_set(&gprk);
    +                gpr_kit gprk = GPRs::new_kit();
    +                GPRs::add_instance_var(&gprk);
    +                GPRs::add_original_var(&gprk);
    +                GPRs::add_standard_vars(&gprk);
                     GV_IS_VALUE_instance_mode = TRUE;
                     Compile body of kind GPR1.1;
                     GV_IS_VALUE_instance_mode = FALSE;
    @@ -311,7 +200,6 @@ function togglePopup(material_id) {
         }
     }
     
    -
    • The structure gpr_kit is accessed in 5/lp, 7/cg, 7/cgl, 7/gpr and here.

    §1.1. Compile body of kind GPR1.1 =

    @@ -441,7 +329,7 @@ function togglePopup(material_id) {
    • This code is used in §1.1 (three times).
    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.

    +
  • +

    + General Parsing Routines - + To compile "general parsing routines", or GPRs, which are runtime functions used to match noun phrases in the command parser.

    +
  • @@ -387,6 +392,16 @@ The Map - The runtime representation of the spatial map for works of interactive fiction: that is, how the rooms and doors connect up.

  • +
  • +

    + Name Properties - +

    +
  • +
  • +

    + Parse Name Properties - + Functions which are values of the parse_name property for objects.

    +
  • @@ -413,11 +428,6 @@ Going - Tweaks to compiling APs for the going action.

  • -
  • -

    - Parsing - -

    -
  • 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.

    -
  • diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt index a09c4f71d..77899bfcd 100644 --- a/inform7/Figures/memory-diagnostics.txt +++ b/inform7/Figures/memory-diagnostics.txt @@ -1,13 +1,13 @@ -Total memory consumption was 300514K = 293 MB +Total memory consumption was 302324K = 295 MB -63.6% was used for 1482362 objects, in 318728 frames in 239 x 800K = 191200K = 186 MB: +63.7% was used for 1493449 objects, in 319536 frames in 241 x 800K = 192800K = 188 MB: - 9.3% inter_tree_node_array 40 x 8192 = 327680 objects, 28837120 bytes - 6.0% text_stream_array 3327 x 100 = 332700 objects, 18737664 bytes - 5.3% linked_list 29321 objects, 16419760 bytes + 9.5% inter_tree_node_array 41 x 8192 = 335872 objects, 29558048 bytes + 6.0% text_stream_array 3337 x 100 = 333700 objects, 18793984 bytes + 5.3% linked_list 29309 objects, 16413040 bytes 3.3% parse_node 129367 objects, 10349360 bytes 2.7% inter_symbol_array 87 x 1024 = 89088 objects, 8555232 bytes - 2.4% verb_conjugation 160 objects, 7425280 bytes + 2.3% verb_conjugation 160 objects, 7425280 bytes 1.7% parse_node_annotation_array 345 x 500 = 172500 objects, 5531040 bytes 1.0% pcalc_prop_array 24 x 1000 = 24000 objects, 3264768 bytes 1.0% map_data 670 objects, 3178480 bytes @@ -17,29 +17,29 @@ Total memory consumption was 300514K = 293 MB 0.4% inter_name_array 31 x 1000 = 31000 objects, 1488992 bytes 0.4% match_trie_array 10 x 1000 = 10000 objects, 1360320 bytes 0.4% i6_schema_array 21 x 100 = 2100 objects, 1260672 bytes - 0.3% inter_package 15064 objects, 1084608 bytes + 0.3% inter_package 15262 objects, 1098864 bytes 0.3% id_body 940 objects, 1075360 bytes - 0.3% inter_name_generator_array 25 x 1000 = 25000 objects, 1000800 bytes + 0.3% inter_name_generator_array 26 x 1000 = 26000 objects, 1040832 bytes 0.3% adjective_meaning 202 objects, 1000304 bytes + 0.3% inter_symbols_table 15262 objects, 976768 bytes 0.3% excerpt_meaning 3098 objects, 966576 bytes - 0.3% inter_symbols_table 15064 objects, 964096 bytes - 0.3% dictionary 19927 objects, 956496 bytes + 0.3% dictionary 20125 objects, 966000 bytes 0.2% production 3871 objects, 898072 bytes - 0.2% dict_entry_array 272 x 100 = 27200 objects, 879104 bytes + 0.2% dict_entry_array 273 x 100 = 27300 objects, 882336 bytes 0.2% ptoken 8379 objects, 871416 bytes 0.2% grammatical_usage 3610 objects, 866400 bytes + 0.2% package_request 9836 objects, 865568 bytes 0.2% individual_form 2560 objects, 860160 bytes - 0.2% package_request 9638 objects, 848144 bytes 0.2% inter_schema_node 8663 objects, 831648 bytes 0.2% unary_predicate_array 16 x 1000 = 16000 objects, 640512 bytes 0.1% local_variable_array 47 x 100 = 4700 objects, 452704 bytes - 0.1% verb_usage 1128 objects, 388032 bytes 0.1% scan_directory 94 objects, 388032 bytes + 0.1% verb_usage 1128 objects, 388032 bytes 0.1% rule 469 objects, 363944 bytes 0.1% verb_form 386 objects, 345856 bytes ---- noun 2379 objects, 285480 bytes ---- inference_subject 665 objects, 260680 bytes - ---- compilation_subtask 2590 objects, 207200 bytes + ---- compilation_subtask 2606 objects, 208480 bytes ---- inter_annotation_array 1 x 8192 objects, 196640 bytes ---- binary_predicate 321 objects, 169488 bytes ---- linguistic_stock_item 3315 objects, 159120 bytes @@ -54,7 +54,7 @@ Total memory consumption was 300514K = 293 MB ---- anl_entry_array 2 x 1000 = 2000 objects, 96064 bytes ---- noun_usage 2401 objects, 96040 bytes ---- preposition 273 objects, 87360 bytes - ---- inter_tree 6 objects, 84480 bytes + ---- inter_tree 6 objects, 84528 bytes ---- lexical_cluster 2516 objects, 80512 bytes ---- pcalc_term_array 2 x 1000 = 2000 objects, 80064 bytes ---- kind_variable_declaration 1652 objects, 79296 bytes @@ -64,8 +64,8 @@ Total memory consumption was 300514K = 293 MB ---- spatial_data 670 objects, 64320 bytes ---- kind_macro_definition 9 objects, 62280 bytes ---- booking 860 objects, 61920 bytes - ---- scenes_rcd_data 1880 objects, 60160 bytes ---- actions_rcd_data 1880 objects, 60160 bytes + ---- scenes_rcd_data 1880 objects, 60160 bytes ---- command_grammar 130 objects, 58240 bytes ---- table 7 objects, 56672 bytes ---- kind_constructor 77 objects, 56056 bytes @@ -81,6 +81,7 @@ Total memory consumption was 300514K = 293 MB ---- activity_list_array 1 x 1000 objects, 40032 bytes ---- to_family_data 496 objects, 39680 bytes ---- shared_variable_access_list_array 12 x 100 = 1200 objects, 38784 bytes + ---- parsing_data 670 objects, 37520 bytes ---- production_list 616 objects, 34496 bytes ---- regions_data 670 objects, 32160 bytes ---- HTML_tag_array 1 x 1000 objects, 32032 bytes @@ -91,7 +92,6 @@ Total memory consumption was 300514K = 293 MB ---- action_pattern_array 7 x 100 = 700 objects, 28224 bytes ---- counting_data 670 objects, 26800 bytes ---- shared_variable_set_array 6 x 100 = 600 objects, 24192 bytes - ---- parsing_data 670 objects, 21440 bytes ---- backdrops_data 670 objects, 21440 bytes ---- action_name 90 objects, 20160 bytes ---- nonlocal_variable 93 objects, 20088 bytes @@ -110,7 +110,7 @@ Total memory consumption was 300514K = 293 MB ---- booking_list 407 objects, 13024 bytes ---- adjective_iname_holder 320 objects, 12800 bytes ---- pathname 292 objects, 11680 bytes - ---- stopwatch_timer 109 objects, 8720 bytes + ---- stopwatch_timer 108 objects, 8640 bytes ---- filename 208 objects, 8320 bytes ---- uniqueness_count 325 objects, 7800 bytes ---- equation_node 68 objects, 7616 bytes @@ -119,7 +119,7 @@ Total memory consumption was 300514K = 293 MB ---- determiner 22 objects, 7216 bytes ---- verb 108 objects, 6048 bytes ---- text_literal_holder 144 objects, 5760 bytes - ---- hierarchy_attachment_point 53 objects, 5088 bytes + ---- hierarchy_attachment_point 54 objects, 5184 bytes ---- inbuild_work 78 objects, 4992 bytes ---- explicit_action_array 1 x 100 objects, 4832 bytes ---- value_property_data 84 objects, 4704 bytes @@ -135,20 +135,20 @@ Total memory consumption was 300514K = 293 MB ---- property_setting_bp_data 84 objects, 3360 bytes ---- method_set 102 objects, 3264 bytes ---- submodule_request 81 objects, 3240 bytes - ---- kind_constructor_comparison_schema_array 1 x 100 objects, 3232 bytes ---- instance_usage_array 1 x 200 objects, 3232 bytes - ---- compatibility_specification 66 objects, 3168 bytes + ---- kind_constructor_comparison_schema_array 1 x 100 objects, 3232 bytes ---- definition 44 objects, 3168 bytes + ---- compatibility_specification 66 objects, 3168 bytes ---- inform_extension 19 objects, 3040 bytes ---- property_of_value_storage 93 objects, 2976 bytes ---- either_or_property_data 62 objects, 2976 bytes ---- use_option 29 objects, 2552 bytes ---- parentage_inference_data 79 objects, 2528 bytes ---- part_of_inference_data 79 objects, 2528 bytes - ---- kind_constructor_casting_rule_array 1 x 100 objects, 2432 bytes ---- kind_constructor_instance_array 1 x 100 objects, 2432 bytes - ---- inter_construct 30 objects, 2400 bytes + ---- kind_constructor_casting_rule_array 1 x 100 objects, 2432 bytes ---- equation_symbol 30 objects, 2400 bytes + ---- inter_construct 30 objects, 2400 bytes ---- semver_range 22 objects, 2288 bytes ---- scene 1 object, 2096 bytes ---- pronoun_usage 42 objects, 1680 bytes @@ -159,8 +159,8 @@ Total memory consumption was 300514K = 293 MB ---- noun_filter_token 22 objects, 1408 bytes ---- inter_annotation_form 35 objects, 1400 bytes ---- special_meaning_holder 33 objects, 1320 bytes - ---- constant_phrase 20 objects, 1280 bytes ---- build_script 40 objects, 1280 bytes + ---- constant_phrase 20 objects, 1280 bytes ---- table_column 16 objects, 1280 bytes ---- invocation_options_array 1 x 100 objects, 1224 bytes ---- direction_inference_data 30 objects, 1200 bytes @@ -171,8 +171,8 @@ Total memory consumption was 300514K = 293 MB ---- submodule_identity 29 objects, 928 bytes ---- pipeline_stage 19 objects, 912 bytes ---- inbuild_requirement 22 objects, 880 bytes - ---- control_structure_phrase 12 objects, 864 bytes ---- code_generation 1 object, 864 bytes + ---- control_structure_phrase 12 objects, 864 bytes ---- cached_understanding 21 objects, 840 bytes ---- phrase_option_array 1 x 100 objects, 824 bytes ---- target_vm 6 objects, 816 bytes @@ -180,45 +180,45 @@ Total memory consumption was 300514K = 293 MB ---- inter_data_type 14 objects, 784 bytes ---- tree_inventory_item 19 objects, 760 bytes ---- inform_language 6 objects, 672 bytes - ---- relation_guard 5 objects, 640 bytes - ---- inter_warehouse_room 10 objects, 640 bytes ---- I6T_intervention 8 objects, 640 bytes + ---- inter_warehouse_room 10 objects, 640 bytes + ---- relation_guard 5 objects, 640 bytes ---- inbuild_search_result 15 objects, 600 bytes ---- internal_test 14 objects, 560 bytes ---- rulebook_outcome 17 objects, 544 bytes ---- small_word_set 11 objects, 528 bytes - ---- inform_kit 5 objects, 520 bytes ---- implication 13 objects, 520 bytes + ---- inform_kit 5 objects, 520 bytes ---- inference_family 11 objects, 440 bytes - ---- equation 4 objects, 416 bytes ---- i6_memory_setting 13 objects, 416 bytes + ---- equation 4 objects, 416 bytes ---- module_package 10 objects, 400 bytes ---- article_usage 8 objects, 384 bytes ---- bp_family 12 objects, 384 bytes ---- source_file 5 objects, 360 bytes ---- inbuild_genre 7 objects, 336 bytes - ---- pronoun 8 objects, 320 bytes ---- grammatical_category 8 objects, 320 bytes + ---- pronoun 8 objects, 320 bytes ---- door_dir_notice 5 objects, 320 bytes - ---- build_step 4 objects, 288 bytes ---- up_family 9 objects, 288 bytes - ---- door_to_notice 5 objects, 280 bytes + ---- build_step 4 objects, 288 bytes ---- explicit_bp_data 5 objects, 280 bytes + ---- door_to_notice 5 objects, 280 bytes ---- inform_pipeline 4 objects, 256 bytes ---- tree_inventory 1 object, 240 bytes ---- verb_usage_tier 5 objects, 240 bytes ---- adjective_meaning_family 7 objects, 224 bytes ---- test_scenario 1 object, 216 bytes ---- release_instructions 1 object, 208 bytes - ---- compilation_unit 5 objects, 200 bytes ---- build_skill 5 objects, 200 bytes - ---- plural_dictionary_entry 4 objects, 192 bytes + ---- compilation_unit 5 objects, 200 bytes ---- kit_dependency 4 objects, 192 bytes + ---- plural_dictionary_entry 4 objects, 192 bytes ---- inform_project 1 object, 176 bytes - ---- code_generation_target 4 objects, 160 bytes - ---- inference_subject_family 5 objects, 160 bytes ---- imperative_defn_family 4 objects, 160 bytes ---- inter_architecture 4 objects, 160 bytes + ---- inference_subject_family 5 objects, 160 bytes + ---- code_generation_target 4 objects, 160 bytes ---- link_instruction 4 objects, 160 bytes ---- codegen_pipeline 1 object, 128 bytes ---- element_activation 4 objects, 128 bytes @@ -228,26 +228,25 @@ Total memory consumption was 300514K = 293 MB ---- compile_task_data 1 object, 80 bytes ---- article 2 objects, 80 bytes ---- group_together_function 2 objects, 80 bytes - ---- build_methodology 1 object, 56 bytes ---- figures_data 1 object, 56 bytes ---- inter_warehouse 1 object, 56 bytes + ---- build_methodology 1 object, 56 bytes ---- HTML_file_state 1 object, 48 bytes ---- star_invention 1 object, 48 bytes - ---- kind_template_definition 1 object, 40 bytes ---- by_function_bp_data 1 object, 40 bytes - ---- parse_name_notice 1 object, 40 bytes ---- loop_over_scope 1 object, 40 bytes + ---- kind_template_definition 1 object, 40 bytes -36.3% was used for memory not allocated for objects: +36.2% was used for memory not allocated for objects: - 16.9% text stream storage 52287408 bytes in 344443 claims - 3.6% dictionary storage 11126272 bytes in 19927 claims - ---- sorting 720 bytes in 3 claims + 16.9% text stream storage 52372384 bytes in 345461 claims + 3.6% dictionary storage 11231232 bytes in 20125 claims + ---- sorting 712 bytes in 3 claims 2.3% source text 7200000 bytes in 3 claims - 3.5% source text details 10800000 bytes in 2 claims + 3.4% source text details 10800000 bytes in 2 claims ---- linguistic stock array 81920 bytes in 2 claims ---- small word set array 105600 bytes in 22 claims - 0.8% inter symbols storage 2618624 bytes in 15946 claims + 0.8% inter symbols storage 2643968 bytes in 16144 claims 5.4% inter bytecode storage 16802796 bytes in 14 claims 2.8% inter links storage 8866944 bytes in 265 claims ---- inter tree location list storage 150528 bytes in 25 claims @@ -257,5 +256,5 @@ Total memory consumption was 300514K = 293 MB ---- code generation workspace for objects 9648 bytes in 9 claims ---- emitter array storage 154432 bytes in 2037 claims -20.2% was overhead - 62338184 bytes = 60877K = 59 MB +20.3% was overhead - 63091552 bytes = 61612K = 60 MB diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt index 97daabfc5..a2ddf4c4e 100644 --- a/inform7/Figures/timings-diagnostics.txt +++ b/inform7/Figures/timings-diagnostics.txt @@ -1,25 +1,24 @@ 100.0% in inform7 run - 56.0% in compilation to Inter - 37.4% in //Sequence::undertake_queued_tasks// - 5.9% in //InferenceSubjects::emit_all// - 3.5% in //MajorNodes::pre_pass// + 56.1% in compilation to Inter + 37.8% in //Sequence::undertake_queued_tasks// + 5.6% in //InferenceSubjects::emit_all// + 3.4% in //MajorNodes::pre_pass// 2.9% in //MajorNodes::pass_1// - 1.6% in //ImperativeDefinitions::assess_all// - 0.4% in //ImperativeDefinitions::compile_first_block// - 0.4% in //MajorNodes::pass_2// - 0.4% in //RTKindConstructors::compile// - 0.4% in //World::stage_V// + 1.5% in //ImperativeDefinitions::assess_all// + 0.5% in //MajorNodes::pass_2// + 0.5% in //RTKindConstructors::compile// + 0.5% in //World::stage_V// + 0.3% in //ImperativeDefinitions::compile_first_block// 0.3% in //Sequence::undertake_queued_tasks// - 0.1% in //RTCommandGrammars::compile_all// 0.1% in //Task::make_built_in_kind_constructors// 0.1% in //World::stages_II_and_III// - 1.8% not specifically accounted for - 41.8% in running Inter pipeline - 10.6% in inter step 7/14: consolidate-text - 10.2% in step preparation - 9.0% in inter step 2/14: link - 6.9% in inter step 14/14: generate inform6 -> auto.inf - 0.8% in inter step 10/14: make-identifiers-unique + 2.2% not specifically accounted for + 41.5% in running Inter pipeline + 10.8% in step preparation + 10.4% in inter step 7/14: consolidate-text + 8.9% in inter step 2/14: link + 7.0% in inter step 14/14: generate inform6 -> auto.inf + 0.6% in inter step 10/14: make-identifiers-unique 0.3% in inter step 11/14: reconcile-verbs 0.3% in inter step 13/14: eliminate-redundant-operations 0.3% in inter step 6/14: assimilate @@ -28,6 +27,6 @@ 0.1% in inter step 5/14: resolve-conditional-compilation 0.1% in inter step 8/14: resolve-external-symbols 0.1% in inter step 9/14: inspect-plugs - 2.3% not specifically accounted for - 1.7% in supervisor + 1.7% not specifically accounted for + 1.8% in supervisor 0.4% not specifically accounted for diff --git a/inform7/core-module/Chapter 1/Class Predeclarations.w b/inform7/core-module/Chapter 1/Class Predeclarations.w index b5a125a72..36ff33012 100644 --- a/inform7/core-module/Chapter 1/Class Predeclarations.w +++ b/inform7/core-module/Chapter 1/Class Predeclarations.w @@ -270,7 +270,6 @@ DECLARE_CLASS(rubric_holder) @e noun_filter_token_CLASS @e parentage_here_inference_data_CLASS @e parentage_inference_data_CLASS -@e parse_name_notice_CLASS @e parsing_data_CLASS @e parsing_pp_data_CLASS @e part_of_inference_data_CLASS @@ -307,7 +306,6 @@ DECLARE_CLASS(named_action_pattern_entry) 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/inform7/if-module/Chapter 5/Command Grammars.w b/inform7/if-module/Chapter 5/Command Grammars.w index 2d8c0b0b3..e928a6b99 100644 --- a/inform7/if-module/Chapter 5/Command Grammars.w +++ b/inform7/if-module/Chapter 5/Command Grammars.w @@ -302,10 +302,10 @@ in any case for those. = command_grammar *CommandGrammars::for_subject(inference_subject *subj) { - if (PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object != NULL) - return PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object; + if (PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject != NULL) + return PARSING_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; return cg; } diff --git a/inform7/if-module/Chapter 5/Parsing Plugin.w b/inform7/if-module/Chapter 5/Parsing Plugin.w index d421bb96b..4f3db32a6 100644 --- a/inform7/if-module/Chapter 5/Parsing Plugin.w +++ b/inform7/if-module/Chapter 5/Parsing Plugin.w @@ -31,7 +31,6 @@ int ParsingPlugin::production_line(int stage, int debugging, BENCH(Understand::traverse); } if (stage == INTER2_CSEQ) { - BENCH(UnderstandGeneralTokens::write_parse_name_routines); BENCH(RTCommandGrammarLines::MistakeActionSub_routine); BENCH(CommandGrammars::prepare); BENCH(RTCommandGrammars::compile_conditions); @@ -60,13 +59,15 @@ and in particular, to every object instance and every kind of object. = typedef struct parsing_data { - struct command_grammar *understand_as_this_object; /* grammar for parsing the name at run-time */ + struct command_grammar *understand_as_this_subject; /* grammar for parsing the name at run-time */ + struct parsing_compilation_data compilation_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); return pd; } @@ -130,7 +131,7 @@ int ParsingPlugin::new_variable_notify(nonlocal_variable *var) { switch (<>) { case 0: if (Kinds::eq(<>, NonlocalVariables::kind(var))) { - RTParsing::understood_variable(var); + RTVariables::understood_variable(var); NonlocalVariables::allow_to_be_zero(var); } break; @@ -154,7 +155,7 @@ property *P_name = NULL; 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)); } return P_name; } @@ -203,14 +204,14 @@ int ParsingPlugin::complete_model(int stage) { 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); } @ We attach numbered parse name routines as properties for any object where grammar has specified a need. (By default, this will not happen.) @ = - inter_name *S = UnderstandGeneralTokens::compile_parse_name_property(subj); + inter_name *S = ParseName::compile_if_needed(subj); if (S) ValueProperties::assert(P_parse_name, subj, Rvalues::from_iname(S), CERTAIN_CE); diff --git a/inform7/imperative-module/Chapter 2/Compile Rvalues.w b/inform7/imperative-module/Chapter 2/Compile Rvalues.w index 31feec799..116cb7608 100644 --- a/inform7/imperative-module/Chapter 2/Compile Rvalues.w +++ b/inform7/imperative-module/Chapter 2/Compile Rvalues.w @@ -163,18 +163,16 @@ kinds of value: CompileRvalues::text(VH, value); return; } - #ifdef IF_MODULE if ((K_understanding) && (Kinds::eq(kind_of_constant, K_understanding))) { if (Wordings::empty(Node::get_text(value))) internal_error("Text no longer available for CONSTANT/UNDERSTANDING"); inter_ti v1 = 0, v2 = 0; - RTParsing::compile_understanding(&v1, &v2, Node::get_text(value)); + CompileRvalues::compile_understanding(&v1, &v2, Node::get_text(value)); if (Holsters::non_void_context(VH)) { Holsters::holster_pair(VH, v1, v2); } return; } - #endif if (Kinds::eq(kind_of_constant, K_use_option)) { use_option *uo = Rvalues::to_use_option(value); Emit::holster_iname(VH, RTUseOptions::uo_iname(uo)); @@ -342,3 +340,35 @@ compiler, rather than parsed from the source.) @ = inter_name *val_iname = TextLiterals::to_value(SW); Emit::holster_iname(VH, val_iname); + +@ 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: + += +typedef struct cached_understanding { + struct wording understanding_text; /* word range of the understanding text */ + struct inter_name *cu_iname; /* function to test this */ + CLASS_DEFINITION +} cached_understanding; + +void CompileRvalues::compile_understanding(inter_ti *val1, inter_ti *val2, wording W) { + if ((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); + } + } +} diff --git a/inform7/runtime-module/Chapter 2/General Parsing Routines.w b/inform7/runtime-module/Chapter 2/General Parsing Routines.w new file mode 100644 index 000000000..9e3f9aedc --- /dev/null +++ b/inform7/runtime-module/Chapter 2/General Parsing Routines.w @@ -0,0 +1,177 @@ +[GPRs::] General Parsing Routines. + +To compile "general parsing routines", or GPRs, which are runtime functions +used to match noun phrases in the command parser. + +@h 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. + +@h 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: + += +typedef struct gpr_kit { + inter_symbol *cur_addr_s; + inter_symbol *cur_len_s; + inter_symbol *cur_word_s; + inter_symbol *f_s; + inter_symbol *g_s; + inter_symbol *group_wn_s; + inter_symbol *instance_s; + inter_symbol *matched_number_s; + inter_symbol *mid_word_s; + inter_symbol *n_s; + inter_symbol *original_wn_s; + inter_symbol *pass_s; + inter_symbol *pass1_n_s; + inter_symbol *pass2_n_s; + inter_symbol *range_from_s; + inter_symbol *range_words_s; + inter_symbol *rv_s; + local_variable *rv_lv; + inter_symbol *sgn_s; + inter_symbol *spn_s; + inter_symbol *ss_s; + inter_symbol *tot_s; + inter_symbol *try_from_wn_s; + inter_symbol *v_s; + inter_symbol *w_s; + inter_symbol *wpos_s; + inter_symbol *x_s; +} gpr_kit; + +@ The idea is to create a new kit which is initially empty: + += +gpr_kit GPRs::new_kit(void) { + gpr_kit kit; + kit.cur_addr_s = NULL; + kit.cur_len_s = NULL; + kit.cur_word_s = NULL; + kit.f_s = NULL; + kit.g_s = NULL; + kit.group_wn_s = NULL; + kit.instance_s = NULL; + kit.matched_number_s = NULL; + kit.mid_word_s = NULL; + kit.n_s = NULL; + kit.original_wn_s = NULL; + kit.pass_s = NULL; + kit.pass1_n_s = NULL; + kit.pass2_n_s = NULL; + kit.range_from_s = NULL; + kit.range_words_s = NULL; + kit.rv_s = NULL; + kit.rv_lv = NULL; + kit.sgn_s = NULL; + kit.spn_s = NULL; + kit.ss_s = NULL; + kit.tot_s = NULL; + kit.try_from_wn_s = NULL; + kit.v_s = NULL; + kit.w_s = NULL; + kit.wpos_s = NULL; + kit.x_s = NULL; + return kit; +} + +@ 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. + += +void GPRs::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); +} + +void GPRs::add_instance_var(gpr_kit *kit) { + kit->instance_s = LocalVariables::new_other_as_symbol(I"instance"); +} + +void GPRs::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"); +} + +void GPRs::add_original_var(gpr_kit *kit) { + kit->original_wn_s = LocalVariables::new_internal_as_symbol(I"original_wn"); +} + +void GPRs::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"); +} + +void GPRs::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/inform7/runtime-module/Chapter 2/Hierarchy.w b/inform7/runtime-module/Chapter 2/Hierarchy.w index 5a9a6e1b9..461b5328b 100644 --- a/inform7/runtime-module/Chapter 2/Hierarchy.w +++ b/inform7/runtime-module/Chapter 2/Hierarchy.w @@ -571,7 +571,6 @@ void Hierarchy::establish(void) { @e NOUN_FILTER_FN_HL @e PARSE_NAMES_HAP @e PARSE_NAME_FN_HL -@e PARSE_NAME_DASH_FN_HL @e SCOPE_FILTERS_HAP @e SCOPE_FILTER_FN_HL @e SLASH_TOKENS_HAP @@ -591,6 +590,10 @@ void Hierarchy::establish(void) { @e VERB_DIRECTIVE_SLASH_HL @e VERB_DIRECTIVE_SPECIAL_HL @e VERB_DIRECTIVE_TOPIC_HL + +@e OBJECT_NOUNS_HAP +@e NAME_ARRAY_HL + @e COMMANDS_HAP @e VERB_DECLARATION_ARRAY_HL @e MISTAKEACTION_HL @@ -643,8 +646,6 @@ void Hierarchy::establish(void) { H_F_G(SCOPE_FILTER_FN_HL, I"filter_fn", I"Scope_Filter") H_END H_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_END H_BEGIN_AP(SLASH_TOKENS_HAP, I"slash_token", I"_slash_token") H_F_G(SLASH_FN_HL, I"slash_fn", I"SlashGPR") @@ -652,6 +653,10 @@ void Hierarchy::establish(void) { H_END H_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_END H_BEGIN_AP(COMMANDS_HAP, I"command", I"_command") H_F_G(VERB_DECLARATION_ARRAY_HL, NULL, I"GV_Grammar") H_END diff --git a/inform7/runtime-module/Chapter 5/Literal Patterns.w b/inform7/runtime-module/Chapter 5/Literal Patterns.w index b46c1170e..0fadd9361 100644 --- a/inform7/runtime-module/Chapter 5/Literal Patterns.w +++ b/inform7/runtime-module/Chapter 5/Literal Patterns.w @@ -300,10 +300,10 @@ sets the |parsed_number| global to the value matched. @ = inter_name *iname = RTLiteralPatterns::parse_fn_iname(lp); packaging_state save = Functions::begin(iname); - gpr_kit gprk = UnderstandValueTokens::new_kit(); - UnderstandValueTokens::add_original(&gprk); - UnderstandValueTokens::add_standard_set(&gprk); - UnderstandValueTokens::add_lp_vars(&gprk); + gpr_kit gprk = GPRs::new_kit(); + GPRs::add_original_var(&gprk); + GPRs::add_standard_vars(&gprk); + GPRs::add_LP_vars(&gprk); inter_symbol *succeeded_label = EmitCode::reserve_label(I".Succeeded"); inter_symbol *failed_label = EmitCode::reserve_label(I".Failed"); @; diff --git a/inform7/runtime-module/Chapter 5/Tables.w b/inform7/runtime-module/Chapter 5/Tables.w index 3ffc37449..c28563c93 100644 --- a/inform7/runtime-module/Chapter 5/Tables.w +++ b/inform7/runtime-module/Chapter 5/Tables.w @@ -204,7 +204,7 @@ used to define new kinds; in this case it doesn't matter what we write, but if (bits & TB_COLUMN_TOPIC) { inter_ti v1 = 0, v2 = 0; wording W = Node::get_text(cell); - RTParsing::compile_understanding(&v1, &v2, W); + CompileRvalues::compile_understanding(&v1, &v2, W); EmitArrays::generic_entry(v1, v2); } else { #endif diff --git a/inform7/runtime-module/Chapter 5/Variables.w b/inform7/runtime-module/Chapter 5/Variables.w index 3b2e5d533..fb7020dea 100644 --- a/inform7/runtime-module/Chapter 5/Variables.w +++ b/inform7/runtime-module/Chapter 5/Variables.w @@ -101,6 +101,10 @@ void RTVariables::store_in_this_iname(nonlocal_variable *nlv, inter_name *iname) RTVariables::set_NVE(nlv, RTVariables::nve_from_iname(iname)); } +void RTVariables::understood_variable(nonlocal_variable *nlv) { + RTVariables::store_in_this_iname(nlv, Hierarchy::find(PARSED_NUMBER_HL)); +} + @ And in particular that's how we handle sentences like "Maximum score translates into Inter as "MAX_SCORE".": diff --git a/inform7/runtime-module/Chapter 6/Name Properties.w b/inform7/runtime-module/Chapter 6/Name Properties.w new file mode 100644 index 000000000..0b8df1474 --- /dev/null +++ b/inform7/runtime-module/Chapter 6/Name Properties.w @@ -0,0 +1,115 @@ +[Name::] Name Properties. + +@ 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. + += +typedef struct parsing_compilation_data { + struct package_request *parsing_package; + struct inter_name *name_array_iname; + struct inter_name *parse_name_fn_iname; +} parsing_compilation_data; + +@ I will be / PCD: + += +parsing_compilation_data Name::new_compilation_data(inference_subject *subj) { + parsing_compilation_data pcd; + pcd.parsing_package = NULL; + pcd.name_array_iname = NULL; + pcd.parse_name_fn_iname = NULL; + return pcd; +} + +@ A single package holds the |name| and/or |parse_name| of a single subject. + += +package_request *Name::package(inference_subject *subj) { + if (PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parsing_package == NULL) + PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parsing_package = + Hierarchy::completion_package(OBJECT_NOUNS_HAP); + return PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parsing_package; +} + +inter_name *Name::get_name_array_iname(inference_subject *subj) { + if (PARSING_DATA_FOR_SUBJ(subj)->compilation_data.name_array_iname == NULL) + PARSING_DATA_FOR_SUBJ(subj)->compilation_data.name_array_iname = + Hierarchy::make_iname_in(NAME_ARRAY_HL, Name::package(subj)); + return PARSING_DATA_FOR_SUBJ(subj)->compilation_data.name_array_iname; +} + +inter_name *Name::get_parse_name_fn_iname(inference_subject *subj) { + if (PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parse_name_fn_iname == NULL) + PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parse_name_fn_iname = + Hierarchy::make_iname_in(PARSE_NAME_FN_HL, Name::package(subj)); + return PARSING_DATA_FOR_SUBJ(subj)->compilation_data.parse_name_fn_iname; +} + +@ 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, wording W, wording PW, + int from_kind) { + inter_name *name_array = Name::get_name_array_iname(I->as_subject); + packaging_state save = EmitArrays::begin(name_array, K_value); + + LOOP_THROUGH_WORDING(j, W) { + vocabulary_entry *ve = Lexer::word(j); + ve = PreformUtilities::find_corresponding_word(ve, + , + ); + wchar_t *p = Vocabulary::get_exemplar(ve, FALSE); + TEMPORARY_TEXT(content) + WRITE_TO(content, "%w", p); + EmitArrays::dword_entry(content); + DISCARD_TEXT(content) + } + if (from_kind) + LOOP_THROUGH_WORDING(j, PW) { + int additional = TRUE; + LOOP_THROUGH_WORDING(k, W) + if (compare_word(j, Lexer::word(k))) + additional = FALSE; + if (additional) { + TEMPORARY_TEXT(content) + WRITE_TO(content, "%w", Lexer::word_text(j)); + EmitArrays::plural_dword_entry(content); + DISCARD_TEXT(content) + } + } + + if (PARSING_DATA(I)->understand_as_this_subject) + CommandGrammars::take_out_one_word_grammar( + 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_subject) + CommandGrammars::take_out_one_word_grammar( + PARSING_DATA_FOR_SUBJ(infs)->understand_as_this_subject); + } + } + + EmitArrays::end(save); + Produce::annotate_i(name_array, INLINE_ARRAY_IANN, 1); + return Rvalues::from_iname(name_array); +} diff --git a/inform7/runtime-module/Chapter 6/Parse Name Properties.w b/inform7/runtime-module/Chapter 6/Parse Name Properties.w new file mode 100644 index 000000000..cb9194817 --- /dev/null +++ b/inform7/runtime-module/Chapter 6/Parse Name Properties.w @@ -0,0 +1,1136 @@ +[ParseName::] Parse Name Properties. + +Functions which are values of the parse_name property for objects. + +@h 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 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. + +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. + +The test case |AwkwardParseNames| may be helpful here. + += +inter_name *ParseName::compile_if_needed(inference_subject *subj) { + inter_name *iname = Name::get_parse_name_fn_iname(subj); + command_grammar *cg = PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject; + if (CommandGrammars::is_empty(cg) == FALSE) { + text_stream *desc = Str::new(); + wording W = InferenceSubjects::get_name_text(subj); + WRITE_TO(desc, "grammar-parsing GPR for '%W'", W); + Sequence::queue(&ParseName::parser_agent, + STORE_POINTER_inference_subject(subj), desc); + return iname; + } + if (Visibility::any_property_visible_to_subject(subj, FALSE)) { + text_stream *desc = Str::new(); + wording W = InferenceSubjects::get_name_text(subj); + WRITE_TO(desc, "distinguish-only GPR for '%W'", W); + Sequence::queue(&ParseName::distinguisher_agent, + STORE_POINTER_inference_subject(subj), desc); + return iname; + } + return NULL; +} + +@ This GPR never matches anything, so is very simple to compile. + += +void ParseName::distinguisher_agent(compilation_subtask *t) { + inference_subject *subj = RETRIEVE_POINTER_inference_subject(t->data); + gpr_kit kit = GPRs::new_kit(); + packaging_state save = Functions::begin(Name::get_parse_name_fn_iname(subj)); + ParseName::compile_head(&kit, subj, FALSE); + ParseName::compile_tail(&kit); + Functions::end(save); +} + +@ This one can be much more elaborate, but is still simple to compile because +all of the work is delegated: + += +void ParseName::parser_agent(compilation_subtask *t) { + inference_subject *subj = RETRIEVE_POINTER_inference_subject(t->data); + command_grammar *cg = PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject; + gpr_kit kit = GPRs::new_kit(); + packaging_state save = Functions::begin(Name::get_parse_name_fn_iname(subj)); + ParseName::compile_head(&kit, subj, TRUE); + RTCommandGrammars::cg_compile_parse_name_lines(&kit, cg); + ParseName::compile_tail(&kit); + Functions::end(save); +} + +@h 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) + +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. + +"Longer grammar" means grammar lines containing 2 or more words, since all +single-fixed-word grammar lines for CGs destined to be |parse_name|s is stripped +out and converted into the |name| property. + += +void ParseName::compile_head(gpr_kit *kit, inference_subject *subj, int there_is_grammar) { + int test_distinguishability = FALSE; + if (KindSubjects::to_kind(subj)) test_distinguishability = TRUE; + + GPRs::add_parse_name_vars(kit); + @; + + @; + + @; + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->pass_s); + EmitCode::val_number(1); + EmitCode::up(); + EmitCode::inv(WHILE_BIP); + EmitCode::down(); + EmitCode::inv(LE_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->pass_s); + EmitCode::val_number(3); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + @; + @; +} + +@ = + EmitCode::inv(IFDEBUG_BIP); + EmitCode::down(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(GE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TRACE_HL)); + EmitCode::val_number(3); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(PRINT_BIP); + EmitCode::down(); + EmitCode::val_text(I"Parse_name called\n"); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + +@ 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. + +@ = + if ((there_is_grammar) && + (Visibility::any_property_visible_to_subject(subj, TRUE) == FALSE)) { + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ACTION_HL)); + EmitCode::val_iname(K_value, Hierarchy::find(THESAME_HL)); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(RETURN_BIP); + EmitCode::down(); + EmitCode::val_number(0); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + } + +@ = + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->try_from_wn_s); + EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->f_s); + EmitCode::val_false(); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->n_s); + EmitCode::val_number(0); + EmitCode::up(); + EmitCode::inv(WHILE_BIP); + EmitCode::down(); + EmitCode::val_number(1); + EmitCode::code(); + EmitCode::down(); + @; + +@ = + /* On pass 1 only, advance |wn| past name property words */ + /* (but do not do this for |##TheSame|, when |wn| is undefined) */ + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(AND_BIP); + EmitCode::down(); + EmitCode::inv(NE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ACTION_HL)); + EmitCode::val_iname(K_value, Hierarchy::find(THESAME_HL)); + EmitCode::up(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->pass_s); + EmitCode::val_number(1); + EmitCode::up(); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(WHILE_BIP); + EmitCode::down(); + EmitCode::call(Hierarchy::find(WORDINPROPERTY_HL)); + EmitCode::down(); + EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); + EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); + EmitCode::val_iname(K_value, RTProperties::iname(ParsingPlugin::name_property())); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->f_s); + EmitCode::val_true(); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + + EmitCode::inv(POSTDECREMENT_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->try_from_wn_s); + EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(OR_BIP); + EmitCode::down(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->pass_s); + EmitCode::val_number(1); + EmitCode::up(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->pass_s); + EmitCode::val_number(2); + EmitCode::up(); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + ParseName::consider_visible_properties(kit, subj, test_distinguishability); + EmitCode::up(); + EmitCode::up(); + + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(AND_BIP); + EmitCode::down(); + EmitCode::inv(NE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ACTION_HL)); + EmitCode::val_iname(K_value, Hierarchy::find(THESAME_HL)); + EmitCode::up(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->pass_s); + EmitCode::val_number(1); + EmitCode::up(); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(WHILE_BIP); + EmitCode::down(); + EmitCode::call(Hierarchy::find(WORDINPROPERTY_HL)); + EmitCode::down(); + EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); + EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); + EmitCode::val_iname(K_value, RTProperties::iname(ParsingPlugin::name_property())); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->f_s); + EmitCode::val_true(); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + + EmitCode::inv(POSTDECREMENT_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->try_from_wn_s); + EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + +@ = + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->original_wn_s); + EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::up(); + +@ = + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::val_symbol(K_value, kit->original_wn_s); + EmitCode::up(); + +@h 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. + += +void ParseName::compile_reset_code_after_failed_line(gpr_kit *kit, inter_symbol *label, + int pluralised) { + if (pluralised) { + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(PARSER_ACTION_HL)); + EmitCode::val_iname(K_value, Hierarchy::find(PLURALFOUND_HL)); + EmitCode::up(); + } + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->try_from_wn_s); + EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->f_s); + EmitCode::val_true(); + EmitCode::up(); + EmitCode::inv(CONTINUE_BIP); + + EmitCode::place_label(label); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::val_symbol(K_value, kit->try_from_wn_s); + EmitCode::up(); +} + +@h The tail. + += +void ParseName::compile_tail(gpr_kit *kit) { + @; + EmitCode::up(); + EmitCode::up(); + @; + EmitCode::inv(POSTINCREMENT_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->pass_s); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + @; + @; + @; + @; +} + +@ 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: + +@ = + EmitCode::inv(BREAK_BIP); + +@ This code runs at the end of each pass, then: + +@ = + EmitCode::inv(WHILE_BIP); + EmitCode::down(); + EmitCode::call(Hierarchy::find(WORDINPROPERTY_HL)); + EmitCode::down(); + EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); + EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); + EmitCode::val_iname(K_value, RTProperties::iname(ParsingPlugin::name_property())); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(POSTINCREMENT_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->n_s); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(OR_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->f_s); + EmitCode::inv(GT_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->n_s); + EmitCode::val_number(0); + EmitCode::up(); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->n_s); + EmitCode::inv(MINUS_BIP); + EmitCode::down(); + EmitCode::inv(PLUS_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->n_s); + EmitCode::val_symbol(K_value, kit->try_from_wn_s); + EmitCode::up(); + EmitCode::val_symbol(K_value, kit->original_wn_s); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->pass_s); + EmitCode::val_number(1); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->pass1_n_s); + EmitCode::val_symbol(K_value, kit->n_s); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->pass_s); + EmitCode::val_number(2); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->pass2_n_s); + EmitCode::val_symbol(K_value, kit->n_s); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + +@ = + EmitCode::inv(IFDEBUG_BIP); + EmitCode::down(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(GE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TRACE_HL)); + EmitCode::val_number(3); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(PRINT_BIP); + EmitCode::down(); + EmitCode::val_text(I"Pass 1: "); + EmitCode::up(); + EmitCode::inv(PRINTNUMBER_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->pass1_n_s); + EmitCode::up(); + EmitCode::inv(PRINT_BIP); + EmitCode::down(); + EmitCode::val_text(I" Pass 2: "); + EmitCode::up(); + EmitCode::inv(PRINTNUMBER_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->pass2_n_s); + EmitCode::up(); + EmitCode::inv(PRINT_BIP); + EmitCode::down(); + EmitCode::val_text(I" Pass 3: "); + EmitCode::up(); + EmitCode::inv(PRINTNUMBER_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->n_s); + EmitCode::up(); + EmitCode::inv(PRINT_BIP); + EmitCode::down(); + EmitCode::val_text(I"\n"); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + +@ = + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(GT_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->pass1_n_s); + EmitCode::val_symbol(K_value, kit->n_s); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->n_s); + EmitCode::val_symbol(K_value, kit->pass1_n_s); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(GT_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->pass2_n_s); + EmitCode::val_symbol(K_value, kit->n_s); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->n_s); + EmitCode::val_symbol(K_value, kit->pass2_n_s); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + +@ = + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::inv(PLUS_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->original_wn_s); + EmitCode::val_symbol(K_value, kit->n_s); + EmitCode::up(); + EmitCode::up(); + +@ = + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->n_s); + EmitCode::val_number(0); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(RETURN_BIP); + EmitCode::down(); + EmitCode::val_number((inter_ti) -1); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::call(Hierarchy::find(DETECTPLURALWORD_HL)); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->original_wn_s); + EmitCode::val_symbol(K_value, kit->n_s); + EmitCode::up(); + EmitCode::inv(RETURN_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->n_s); + EmitCode::up(); + +@ 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 +to a kind, sometimes we require that the permission be given to this +specific object. + += +void ParseName::consider_visible_properties(gpr_kit *kit, inference_subject *subj, + int test_distinguishability) { + int phase = 2; + if (test_distinguishability) phase = 1; + for (; phase<=2; phase++) { + property *pr; + int visible_properties_code_written = FALSE; + LOOP_OVER(pr, property) { + if ((Properties::is_either_or(pr)) && (RTProperties::stored_in_negation(pr))) continue; + property_permission *pp = + PropertyPermissions::find(subj, pr, TRUE); + if ((pp) && (Visibility::get_level(pp) > 0)) @; + } + if (visible_properties_code_written) { + if (phase == 1) + ParseName::finish_distinguishing_visible_properties(kit); + else + ParseName::finish_parsing_visible_properties(kit); + } + } +} + +@ = + if (visible_properties_code_written == FALSE) { + visible_properties_code_written = TRUE; + if (phase == 1) + ParseName::begin_distinguishing_visible_properties(kit); + else + ParseName::begin_parsing_visible_properties(kit); + } + + parse_node *visibility_condition = Visibility::get_condition(pp); + if (visibility_condition) { + if (phase == 1) + ParseName::test_distinguish_visible_property(kit, visibility_condition); + else + ParseName::test_parse_visible_property(kit, visibility_condition); + } + + if (phase == 1) + ParseName::distinguish_visible_property(kit, pr); + else + ParseName::parse_visible_property(kit, subj, pr, Visibility::get_level(pp)); + + if (visibility_condition) { + EmitCode::up(); EmitCode::up(); + } + +@h Distinguishing visible properties. +We distinguish two objects P1 and P2 based on the following criteria: +(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; +(4) and otherwise we disclaim the decision. + += +void ParseName::begin_distinguishing_visible_properties(gpr_kit *kit) { + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ACTION_HL)); + EmitCode::val_iname(K_value, Hierarchy::find(THESAME_HL)); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(IFDEBUG_BIP); + EmitCode::down(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(GE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TRACE_HL)); + EmitCode::val_number(4); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(PRINT_BIP); + EmitCode::down(); + EmitCode::val_text(I"p1, p2 = "); + EmitCode::up(); + EmitCode::inv(PRINTNUMBER_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ONE_HL)); + EmitCode::up(); + EmitCode::inv(PRINT_BIP); + EmitCode::down(); + EmitCode::val_text(I", "); + EmitCode::up(); + EmitCode::inv(PRINTNUMBER_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TWO_HL)); + EmitCode::up(); + EmitCode::inv(PRINT_BIP); + EmitCode::down(); + EmitCode::val_text(I"\n"); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->ss_s); + EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); + EmitCode::up(); +} + +void ParseName::test_distinguish_visible_property(gpr_kit *kit, parse_node *spec) { + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(SELF_HL)); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ONE_HL)); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->f_s); + CompileValues::to_code_val_of_kind(spec, K_truth_state); + EmitCode::up(); + + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(SELF_HL)); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TWO_HL)); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->g_s); + CompileValues::to_code_val_of_kind(spec, K_truth_state); + EmitCode::up(); + + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(NE_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->f_s); + EmitCode::val_symbol(K_value, kit->g_s); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + @; + EmitCode::up(); + EmitCode::up(); + + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->f_s); + EmitCode::code(); + EmitCode::down(); +} + +void ParseName::distinguish_visible_property(gpr_kit *kit, property *prn) { + TEMPORARY_TEXT(C) + WRITE_TO(C, "Distinguishing property %n", RTProperties::iname(prn)); + EmitCode::comment(C); + DISCARD_TEXT(C) + + if (Properties::is_either_or(prn)) { + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(AND_BIP); + EmitCode::down(); + RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(PARSER_ONE_HL), prn); + EmitCode::inv(NOT_BIP); + EmitCode::down(); + RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(PARSER_TWO_HL), prn); + EmitCode::up(); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + @; + EmitCode::up(); + EmitCode::up(); + + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(AND_BIP); + EmitCode::down(); + RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(PARSER_TWO_HL), prn); + EmitCode::inv(NOT_BIP); + EmitCode::down(); + RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(PARSER_ONE_HL), prn); + EmitCode::up(); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + @; + EmitCode::up(); + EmitCode::up(); + } else { + kind *K = ValueProperties::kind(prn); + inter_name *distinguisher = RTKindConstructors::get_distinguisher_iname(K); + EmitCode::inv(IF_BIP); + EmitCode::down(); + if (distinguisher) { + EmitCode::call(distinguisher); + EmitCode::down(); + EmitCode::inv(PROPERTYVALUE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ONE_HL)); + EmitCode::val_iname(K_value, RTProperties::iname(prn)); + EmitCode::up(); + EmitCode::inv(PROPERTYVALUE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TWO_HL)); + EmitCode::val_iname(K_value, RTProperties::iname(prn)); + EmitCode::up(); + EmitCode::up(); + } else { + EmitCode::inv(NE_BIP); + EmitCode::down(); + EmitCode::inv(PROPERTYVALUE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ONE_HL)); + EmitCode::val_iname(K_value, RTProperties::iname(prn)); + EmitCode::up(); + EmitCode::inv(PROPERTYVALUE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TWO_HL)); + EmitCode::val_iname(K_value, RTProperties::iname(prn)); + EmitCode::up(); + EmitCode::up(); + } + EmitCode::code(); + EmitCode::down(); + @; + EmitCode::up(); + EmitCode::up(); + } +} + +@ = + EmitCode::inv(RETURN_BIP); + EmitCode::down(); + EmitCode::val_number((inter_ti) -2); + EmitCode::up(); + +@ = +void ParseName::finish_distinguishing_visible_properties(gpr_kit *kit) { + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(SELF_HL)); + EmitCode::val_symbol(K_value, kit->ss_s); + EmitCode::up(); + EmitCode::inv(RETURN_BIP); + EmitCode::down(); + EmitCode::val_number(0); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); +} + +@h 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. + += +void ParseName::begin_parsing_visible_properties(gpr_kit *kit) { + EmitCode::comment(I"Match any number of visible property values"); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->try_from_wn_s); + EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->g_s); + EmitCode::val_true(); + EmitCode::up(); + EmitCode::inv(WHILE_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, kit->g_s); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->g_s); + EmitCode::val_false(); + EmitCode::up(); +} + +void ParseName::test_parse_visible_property(gpr_kit *kit, parse_node *spec) { + EmitCode::inv(IF_BIP); + EmitCode::down(); + CompileValues::to_code_val_of_kind(spec, K_truth_state); + EmitCode::code(); + EmitCode::down(); +} + +int unique_pvp_counter = 0; +void ParseName::parse_visible_property(gpr_kit *kit, + inference_subject *subj, property *prn, int visibility_level) { + TEMPORARY_TEXT(C) + WRITE_TO(C, "Parsing property %n", RTProperties::iname(prn)); + EmitCode::comment(C); + DISCARD_TEXT(C) + + if (Properties::is_either_or(prn)) { + TEMPORARY_TEXT(L) + WRITE_TO(L, ".pvp_pass_L_%d", unique_pvp_counter++); + inter_symbol *pass_label = EmitCode::reserve_label(L); + DISCARD_TEXT(L) + + ParseName::parse_visible_either_or( + kit, prn, visibility_level, pass_label); + property *prnbar = EitherOrProperties::get_negation(prn); + if (prnbar) + ParseName::parse_visible_either_or( + kit, prnbar, visibility_level, pass_label); + + EmitCode::place_label(pass_label); + } else { + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::val_symbol(K_value, kit->try_from_wn_s); + EmitCode::up(); + + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->spn_s); + EmitCode::val_iname(K_value, Hierarchy::find(PARSED_NUMBER_HL)); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->ss_s); + EmitCode::val_iname(K_value, Hierarchy::find(ETYPE_HL)); + EmitCode::up(); + + EmitCode::inv(IF_BIP); + EmitCode::down(); + kind *K = ValueProperties::kind(prn); + inter_name *recog_gpr = RTKindConstructors::get_recognition_only_GPR_as_iname(K); + if (recog_gpr) { + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::call(recog_gpr); + EmitCode::down(); + EmitCode::inv(PROPERTYVALUE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); + EmitCode::val_iname(K_value, RTProperties::iname(prn)); + EmitCode::up(); + EmitCode::up(); + EmitCode::val_iname(K_value, Hierarchy::find(GPR_PREPOSITION_HL)); + EmitCode::up(); + } else if (RTKindConstructors::offers_I6_GPR(K)) { + inter_name *i6_gpr_name = RTKindConstructors::get_explicit_I6_GPR_iname(K); + if (i6_gpr_name) { + EmitCode::inv(AND_BIP); + EmitCode::down(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::call(i6_gpr_name); + EmitCode::val_iname(K_value, Hierarchy::find(GPR_NUMBER_HL)); + EmitCode::up(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::inv(PROPERTYVALUE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); + EmitCode::val_iname(K_value, RTProperties::iname(prn)); + EmitCode::up(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSED_NUMBER_HL)); + EmitCode::up(); + EmitCode::up(); + } else if (Kinds::Behaviour::is_an_enumeration(K)) { + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::call(RTKindConstructors::get_instance_GPR_iname(K)); + EmitCode::down(); + EmitCode::inv(PROPERTYVALUE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); + EmitCode::val_iname(K_value, RTProperties::iname(prn)); + EmitCode::up(); + EmitCode::up(); + EmitCode::val_iname(K_value, Hierarchy::find(GPR_NUMBER_HL)); + EmitCode::up(); + } else { + EmitCode::inv(AND_BIP); + EmitCode::down(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::call(RTKindConstructors::get_kind_GPR_iname(K)); + EmitCode::val_iname(K_value, Hierarchy::find(GPR_NUMBER_HL)); + EmitCode::up(); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::inv(PROPERTYVALUE_BIP); + EmitCode::down(); + EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); + EmitCode::val_iname(K_value, RTProperties::iname(prn)); + EmitCode::up(); + EmitCode::val_iname(K_value, Hierarchy::find(PARSED_NUMBER_HL)); + EmitCode::up(); + EmitCode::up(); + } + } else internal_error("Unable to recognise kind of value in parsing"); + EmitCode::code(); + EmitCode::down(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->try_from_wn_s); + EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->g_s); + EmitCode::val_true(); + EmitCode::up(); + if (visibility_level == 2) { + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->f_s); + EmitCode::val_true(); + EmitCode::up(); + } + EmitCode::up(); + EmitCode::up(); + + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(PARSED_NUMBER_HL)); + EmitCode::val_symbol(K_value, kit->spn_s); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(ETYPE_HL)); + EmitCode::val_symbol(K_value, kit->ss_s); + EmitCode::up(); + } +} + +void ParseName::parse_visible_either_or(gpr_kit *kit, property *prn, int visibility_level, + inter_symbol *pass_l) { + command_grammar *cg = EitherOrProperties::get_parsing_grammar(prn); + @; + EmitCode::inv(IF_BIP); + EmitCode::down(); + wording W = prn->name; + int j = 0; LOOP_THROUGH_WORDING(i, W) j++; + int ands = 0; + if (j > 0) { EmitCode::inv(AND_BIP); EmitCode::down(); ands++; } + RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(SELF_HL), prn); + int k = 0; + LOOP_THROUGH_WORDING(i, W) { + if (k < j-1) { EmitCode::inv(AND_BIP); EmitCode::down(); ands++; } + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); + TEMPORARY_TEXT(N) + WRITE_TO(N, "%N", i); + EmitCode::val_dword(N); + DISCARD_TEXT(N) + EmitCode::up(); + k++; + } + + for (int a=0; a; + EmitCode::up(); + EmitCode::up(); + if (cg) { + if (cg->compilation_data.cg_prn_iname == NULL) internal_error("no PRN iname"); + @; + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(AND_BIP); + EmitCode::down(); + RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(SELF_HL), prn); + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::call(cg->compilation_data.cg_prn_iname); + EmitCode::val_iname(K_value, Hierarchy::find(GPR_PREPOSITION_HL)); + EmitCode::up(); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + @; + EmitCode::up(); + EmitCode::up(); + } +} + +@ = + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::val_symbol(K_value, kit->try_from_wn_s); + EmitCode::up(); + +@ = + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->try_from_wn_s); + EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::up(); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->g_s); + EmitCode::val_true(); + EmitCode::up(); + if (visibility_level == 2) { + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, kit->f_s); + EmitCode::val_true(); + EmitCode::up(); + } + if (pass_l) { + EmitCode::inv(JUMP_BIP); + EmitCode::down(); + EmitCode::lab(pass_l); + EmitCode::up(); + } + +@ = +void ParseName::finish_parsing_visible_properties(gpr_kit *kit) { + EmitCode::up(); + EmitCode::up(); + EmitCode::comment(I"try_from_wn is now advanced past any visible property values"); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); + EmitCode::val_symbol(K_value, kit->try_from_wn_s); + EmitCode::up(); +} diff --git a/inform7/runtime-module/Chapter 7/Command Grammar Lines.w b/inform7/runtime-module/Chapter 7/Command Grammar Lines.w index 9adcf7230..b3d502612 100644 --- a/inform7/runtime-module/Chapter 7/Command Grammar Lines.w +++ b/inform7/runtime-module/Chapter 7/Command Grammar Lines.w @@ -430,7 +430,7 @@ void RTCommandGrammarLines::compile_cg_line(gpr_kit *gprk, cg_line *cgl, int cg_ EmitCode::up(); break; case CG_IS_SUBJECT: - UnderstandGeneralTokens::after_gl_failed(gprk, fail_label, cgl->pluralised); + ParseName::compile_reset_code_after_failed_line(gprk, fail_label, cgl->pluralised); break; case CG_IS_VALUE: EmitCode::inv(STORE_BIP); @@ -620,9 +620,9 @@ void RTCommandGrammarLines::compile_slash_gprs(void) { slash_gpr *sgpr; LOOP_OVER(sgpr, slash_gpr) { packaging_state save = Functions::begin(sgpr->sgpr_iname); - gpr_kit gprk = UnderstandValueTokens::new_kit(); - UnderstandValueTokens::add_original(&gprk); - UnderstandValueTokens::add_standard_set(&gprk); + gpr_kit gprk = GPRs::new_kit(); + GPRs::add_original_var(&gprk); + GPRs::add_standard_vars(&gprk); RTCommandGrammarLines::compile_token_line(&gprk, TRUE, sgpr->first_choice, sgpr->last_choice, CG_IS_TOKEN, FALSE, NULL, NULL, gprk.group_wn_s, NULL); EmitCode::inv(RETURN_BIP); diff --git a/inform7/runtime-module/Chapter 7/Command Grammars.w b/inform7/runtime-module/Chapter 7/Command Grammars.w index 417f75cfd..c40e1cf8b 100644 --- a/inform7/runtime-module/Chapter 7/Command Grammars.w +++ b/inform7/runtime-module/Chapter 7/Command Grammars.w @@ -209,19 +209,19 @@ specified for all things. (This mimics I6 class-to-instance inheritance.) void RTCommandGrammars::cg_compile_parse_name_lines(gpr_kit *gprk, command_grammar *cg) { inference_subject *subj = cg->subj_understood; - if (PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object != cg) + if (PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject != cg) internal_error("link between subject and CG broken"); LOGIF(GRAMMAR, "Parse_name content for $j:\n", subj); - RTCommandGrammars::cg_compile_lines(gprk, PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object); + RTCommandGrammars::cg_compile_lines(gprk, PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_subject); inference_subject *infs; for (infs = InferenceSubjects::narrowest_broader_subject(subj); 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) { LOGIF(GRAMMAR, "And parse_name content inherited from $j:\n", infs); - RTCommandGrammars::cg_compile_lines(gprk, PARSING_DATA_FOR_SUBJ(infs)->understand_as_this_object); + RTCommandGrammars::cg_compile_lines(gprk, PARSING_DATA_FOR_SUBJ(infs)->understand_as_this_subject); } } } @@ -259,7 +259,7 @@ void RTCommandGrammars::compile(command_grammar *cg) { RTCommandGrammarLines::reset_labels(); switch(cg->cg_is) { case CG_IS_COMMAND: { - package_request *PR = Hierarchy::synoptic_package(COMMANDS_HAP); + package_request *PR = Hierarchy::completion_package(COMMANDS_HAP); inter_name *array_iname = Hierarchy::make_iname_in(VERB_DECLARATION_ARRAY_HL, PR); packaging_state save = RTCommandGrammars::cg_compile_Verb_directive_header(cg, array_iname); RTCommandGrammars::cg_compile_lines(NULL, cg); @@ -267,11 +267,11 @@ void RTCommandGrammars::compile(command_grammar *cg) { break; } case CG_IS_TOKEN: { - gpr_kit gprk = UnderstandValueTokens::new_kit(); + gpr_kit gprk = GPRs::new_kit(); if (cg->compilation_data.cg_token_iname == NULL) internal_error("cg token not ready"); packaging_state save = Functions::begin(cg->compilation_data.cg_token_iname); - UnderstandValueTokens::add_original(&gprk); - UnderstandValueTokens::add_standard_set(&gprk); + GPRs::add_original_var(&gprk); + GPRs::add_standard_vars(&gprk); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.original_wn_s); @@ -291,12 +291,12 @@ void RTCommandGrammars::compile(command_grammar *cg) { break; } case CG_IS_CONSULT: { - gpr_kit gprk = UnderstandValueTokens::new_kit(); - inter_name *iname = UnderstandGeneralTokens::consult_iname(cg); + gpr_kit gprk = GPRs::new_kit(); + inter_name *iname = RTCommandGrammars::consult_iname(cg); packaging_state save = Functions::begin(iname); - UnderstandValueTokens::add_range_calls(&gprk); - UnderstandValueTokens::add_original(&gprk); - UnderstandValueTokens::add_standard_set(&gprk); + GPRs::add_range_vars(&gprk); + GPRs::add_original_var(&gprk); + GPRs::add_standard_vars(&gprk); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); @@ -320,25 +320,17 @@ void RTCommandGrammars::compile(command_grammar *cg) { Functions::end(save); break; } - case CG_IS_SUBJECT: { - gpr_kit gprk = UnderstandValueTokens::new_kit(); - packaging_state save = Emit::new_packaging_state(); - if (UnderstandGeneralTokens::compile_parse_name_head(&save, &gprk, cg->subj_understood, cg, NULL)) { - RTCommandGrammars::cg_compile_parse_name_lines(&gprk, cg); - UnderstandGeneralTokens::compile_parse_name_tail(&gprk); - Functions::end(save); - } + case CG_IS_SUBJECT: break; - } case CG_IS_VALUE: internal_error("iv"); break; case CG_IS_PROPERTY_NAME: { - gpr_kit gprk = UnderstandValueTokens::new_kit(); + gpr_kit gprk = GPRs::new_kit(); if (cg->compilation_data.cg_prn_iname == NULL) internal_error("PRN PN not ready"); packaging_state save = Functions::begin(cg->compilation_data.cg_prn_iname); - UnderstandValueTokens::add_original(&gprk); - UnderstandValueTokens::add_standard_set(&gprk); + GPRs::add_original_var(&gprk); + GPRs::add_standard_vars(&gprk); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.original_wn_s); @@ -373,3 +365,22 @@ void RTCommandGrammars::compile_iv(gpr_kit *gprk, command_grammar *cg) { void RTCommandGrammars::emit_determination_type(determination_type *gty) { CompileValues::to_code_val(gty->term[0].what); } + +@ 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. + += +inter_name *RTCommandGrammars::consult_iname(command_grammar *cg) { + if (cg == NULL) return NULL; + if (cg->compilation_data.cg_consult_iname == NULL) { + current_sentence = cg->where_cg_created; + package_request *PR = Hierarchy::local_package(CONSULT_TOKENS_HAP); + cg->compilation_data.cg_consult_iname = Hierarchy::make_iname_in(CONSULT_FN_HL, PR); + } + return cg->compilation_data.cg_consult_iname; +} diff --git a/inform7/runtime-module/Chapter 7/General Parsing Routines.w b/inform7/runtime-module/Chapter 7/General Parsing Routines.w deleted file mode 100644 index d5aa75672..000000000 --- a/inform7/runtime-module/Chapter 7/General Parsing Routines.w +++ /dev/null @@ -1,1223 +0,0 @@ -[UnderstandGeneralTokens::] General Parsing Routines. - -To compile I6 general parsing routines (GPRs) and/or |parse_name| -properties as required by the I7 grammar. - -@h Definitions. - -= -typedef struct parse_name_notice { - struct inter_name *pnn_iname; - struct inference_subject *parse_subject; - CLASS_DEFINITION -} parse_name_notice; - -@ 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. - -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. - -@h 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. - -First, we need to look after a pointer to the CG used to hold the grammar -being matched against the snippet of words. - -= -inter_name *UnderstandGeneralTokens::consult_iname(command_grammar *cg) { - if (cg == NULL) return NULL; - if (cg->compilation_data.cg_consult_iname == NULL) { - current_sentence = cg->where_cg_created; - package_request *PR = Hierarchy::local_package(CONSULT_TOKENS_HAP); - cg->compilation_data.cg_consult_iname = Hierarchy::make_iname_in(CONSULT_FN_HL, PR); - } - return cg->compilation_data.cg_consult_iname; -} - -@h 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. - -= -inter_name *UnderstandGeneralTokens::get_gv_parse_name(command_grammar *cg) { - if (cg->compilation_data.cg_parse_name_iname == NULL) { - package_request *PR = Hierarchy::local_package_to(PARSE_NAMES_HAP, cg->where_cg_created); - cg->compilation_data.cg_parse_name_iname = Hierarchy::make_iname_in(PARSE_NAME_FN_HL, PR); - } - return cg->compilation_data.cg_parse_name_iname; -} - -inter_name *UnderstandGeneralTokens::compile_parse_name_property(inference_subject *subj) { - inter_name *symb = NULL; - command_grammar *cg = PARSING_DATA_FOR_SUBJ(subj)->understand_as_this_object; - if (CommandGrammars::is_empty(cg) == FALSE) { - symb = UnderstandGeneralTokens::get_gv_parse_name(cg); - } else { - if (Visibility::any_property_visible_to_subject(subj, FALSE)) { - parse_name_notice *notice = CREATE(parse_name_notice); - package_request *PR = Hierarchy::local_package_to(PARSE_NAMES_HAP, subj->infs_created_at); - notice->pnn_iname = Hierarchy::make_iname_in(PARSE_NAME_DASH_FN_HL, PR); - notice->parse_subject = subj; - symb = notice->pnn_iname; - } - } - return symb; -} - -void UnderstandGeneralTokens::write_parse_name_routines(void) { - parse_name_notice *notice; - LOOP_OVER(notice, parse_name_notice) { - gpr_kit gprk = UnderstandValueTokens::new_kit(); - packaging_state save = Emit::new_packaging_state(); - if (UnderstandGeneralTokens::compile_parse_name_head(&save, &gprk, - notice->parse_subject, NULL, notice->pnn_iname)) { - UnderstandGeneralTokens::compile_parse_name_tail(&gprk); - Functions::end(save); - } - } -} - -@ 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. - -= -int UnderstandGeneralTokens::compile_parse_name_head(packaging_state *save, - gpr_kit *gprk, inference_subject *subj, - command_grammar *cg, inter_name *rname) { - int test_distinguishability = FALSE, sometimes_has_visible_properties = FALSE; - inter_name *N = NULL; - - if (subj == NULL) internal_error("compiling parse_name head for null subj"); - - if (cg) { - sometimes_has_visible_properties = - Visibility::any_property_visible_to_subject(subj, TRUE); - N = UnderstandGeneralTokens::get_gv_parse_name(cg); - } else { - if (Visibility::any_property_visible_to_subject(subj, FALSE) - == FALSE) return FALSE; - } - - if (KindSubjects::to_kind(subj)) test_distinguishability = TRUE; - - inter_name *compile_to = rname; - if (compile_to == NULL) compile_to = N; - if (compile_to == NULL) internal_error("no parse name routine name given"); - - *save = Functions::begin(compile_to); - - UnderstandValueTokens::add_parse_name_vars(gprk); - - UnderstandGeneralTokens::top_of_head(gprk, N, subj, - test_distinguishability, sometimes_has_visible_properties, rname); - return TRUE; -} - -@ The following multi-pass approach checks the possible patterns: - -(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_name|s is stripped out and converted into the -|name| property. - -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. - -= -void UnderstandGeneralTokens::top_of_head(gpr_kit *gprk, inter_name *cg_iname, inference_subject *subj, - int test_distinguishability, int sometimes_has_visible_properties, inter_name *given_name) { - - EmitCode::inv(IFDEBUG_BIP); - EmitCode::down(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(GE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TRACE_HL)); - EmitCode::val_number(3); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(PRINT_BIP); - EmitCode::down(); - EmitCode::val_text(I"Parse_name called\n"); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - - if ((cg_iname) && (sometimes_has_visible_properties == FALSE)) { - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ACTION_HL)); - EmitCode::val_iname(K_value, Hierarchy::find(THESAME_HL)); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(RETURN_BIP); - EmitCode::down(); - EmitCode::val_number(0); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - } - @; - - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->pass_s); - EmitCode::val_number(1); - EmitCode::up(); - EmitCode::inv(WHILE_BIP); - EmitCode::down(); - EmitCode::inv(LE_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->pass_s); - EmitCode::val_number(3); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - @; - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->try_from_wn_s); - EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->f_s); - EmitCode::val_false(); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->n_s); - EmitCode::val_number(0); - EmitCode::up(); - EmitCode::inv(WHILE_BIP); - EmitCode::down(); - EmitCode::val_number(1); - EmitCode::code(); - EmitCode::down(); - - /* On pass 1 only, advance |wn| past name property words */ - /* (but do not do this for |##TheSame|, when |wn| is undefined) */ - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(AND_BIP); - EmitCode::down(); - EmitCode::inv(NE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ACTION_HL)); - EmitCode::val_iname(K_value, Hierarchy::find(THESAME_HL)); - EmitCode::up(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->pass_s); - EmitCode::val_number(1); - EmitCode::up(); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(WHILE_BIP); - EmitCode::down(); - EmitCode::call(Hierarchy::find(WORDINPROPERTY_HL)); - EmitCode::down(); - EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); - EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); - EmitCode::val_iname(K_value, RTParsing::name_iname()); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->f_s); - EmitCode::val_true(); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(POSTDECREMENT_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->try_from_wn_s); - EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(OR_BIP); - EmitCode::down(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->pass_s); - EmitCode::val_number(1); - EmitCode::up(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->pass_s); - EmitCode::val_number(2); - EmitCode::up(); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - UnderstandGeneralTokens::consider_visible_properties(gprk, subj, test_distinguishability); - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(AND_BIP); - EmitCode::down(); - EmitCode::inv(NE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ACTION_HL)); - EmitCode::val_iname(K_value, Hierarchy::find(THESAME_HL)); - EmitCode::up(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->pass_s); - EmitCode::val_number(1); - EmitCode::up(); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(WHILE_BIP); - EmitCode::down(); - EmitCode::call(Hierarchy::find(WORDINPROPERTY_HL)); - EmitCode::down(); - EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); - EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); - EmitCode::val_iname(K_value, RTParsing::name_iname()); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->f_s); - EmitCode::val_true(); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(POSTDECREMENT_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->try_from_wn_s); - EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); -} - -@ = - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->original_wn_s); - EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::up(); - -@ = - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::val_symbol(K_value, gprk->original_wn_s); - EmitCode::up(); - -@ 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. - -= -void UnderstandGeneralTokens::after_gl_failed(gpr_kit *gprk, inter_symbol *label, int pluralised) { - if (pluralised) { - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(PARSER_ACTION_HL)); - EmitCode::val_iname(K_value, Hierarchy::find(PLURALFOUND_HL)); - EmitCode::up(); - } - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->try_from_wn_s); - EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->f_s); - EmitCode::val_true(); - EmitCode::up(); - EmitCode::inv(CONTINUE_BIP); - - EmitCode::place_label(label); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::val_symbol(K_value, gprk->try_from_wn_s); - EmitCode::up(); -} - -@ 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. - -= -void UnderstandGeneralTokens::compile_parse_name_tail(gpr_kit *gprk) { - EmitCode::inv(BREAK_BIP); - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(WHILE_BIP); - EmitCode::down(); - EmitCode::call(Hierarchy::find(WORDINPROPERTY_HL)); - EmitCode::down(); - EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); - EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); - EmitCode::val_iname(K_value, RTParsing::name_iname()); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(POSTINCREMENT_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->n_s); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(OR_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->f_s); - EmitCode::inv(GT_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->n_s); - EmitCode::val_number(0); - EmitCode::up(); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->n_s); - EmitCode::inv(MINUS_BIP); - EmitCode::down(); - EmitCode::inv(PLUS_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->n_s); - EmitCode::val_symbol(K_value, gprk->try_from_wn_s); - EmitCode::up(); - EmitCode::val_symbol(K_value, gprk->original_wn_s); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->pass_s); - EmitCode::val_number(1); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->pass1_n_s); - EmitCode::val_symbol(K_value, gprk->n_s); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->pass_s); - EmitCode::val_number(2); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->pass2_n_s); - EmitCode::val_symbol(K_value, gprk->n_s); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::inv(POSTINCREMENT_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->pass_s); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(IFDEBUG_BIP); - EmitCode::down(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(GE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TRACE_HL)); - EmitCode::val_number(3); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(PRINT_BIP); - EmitCode::down(); - EmitCode::val_text(I"Pass 1: "); - EmitCode::up(); - EmitCode::inv(PRINTNUMBER_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->pass1_n_s); - EmitCode::up(); - EmitCode::inv(PRINT_BIP); - EmitCode::down(); - EmitCode::val_text(I" Pass 2: "); - EmitCode::up(); - EmitCode::inv(PRINTNUMBER_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->pass2_n_s); - EmitCode::up(); - EmitCode::inv(PRINT_BIP); - EmitCode::down(); - EmitCode::val_text(I" Pass 3: "); - EmitCode::up(); - EmitCode::inv(PRINTNUMBER_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->n_s); - EmitCode::up(); - EmitCode::inv(PRINT_BIP); - EmitCode::down(); - EmitCode::val_text(I"\n"); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(GT_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->pass1_n_s); - EmitCode::val_symbol(K_value, gprk->n_s); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->n_s); - EmitCode::val_symbol(K_value, gprk->pass1_n_s); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(GT_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->pass2_n_s); - EmitCode::val_symbol(K_value, gprk->n_s); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->n_s); - EmitCode::val_symbol(K_value, gprk->pass2_n_s); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::inv(PLUS_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->original_wn_s); - EmitCode::val_symbol(K_value, gprk->n_s); - EmitCode::up(); - EmitCode::up(); - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->n_s); - EmitCode::val_number(0); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(RETURN_BIP); - EmitCode::down(); - EmitCode::val_number((inter_ti) -1); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::call(Hierarchy::find(DETECTPLURALWORD_HL)); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->original_wn_s); - EmitCode::val_symbol(K_value, gprk->n_s); - EmitCode::up(); - EmitCode::inv(RETURN_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->n_s); - EmitCode::up(); -} - -@ 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 -to a kind, sometimes we require that the permission be given to this -specific object. - -= -void UnderstandGeneralTokens::consider_visible_properties(gpr_kit *gprk, inference_subject *subj, - int test_distinguishability) { - int phase = 2; - if (test_distinguishability) phase = 1; - for (; phase<=2; phase++) { - property *pr; - UnderstandGeneralTokens::start_considering_visible_properties(gprk, phase); - LOOP_OVER(pr, property) { - if ((Properties::is_either_or(pr)) && (RTProperties::stored_in_negation(pr))) continue; - property_permission *pp = - PropertyPermissions::find(subj, pr, TRUE); - if ((pp) && (Visibility::get_level(pp) > 0)) - UnderstandGeneralTokens::consider_visible_property(gprk, subj, pr, pp, phase); - } - UnderstandGeneralTokens::finish_considering_visible_properties(gprk, phase); - } -} - -@h 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. - -= -int visible_properties_code_written = FALSE; /* persistent state used only here */ - -void UnderstandGeneralTokens::start_considering_visible_properties(gpr_kit *gprk, int phase) { - visible_properties_code_written = FALSE; -} - -void UnderstandGeneralTokens::consider_visible_property(gpr_kit *gprk, inference_subject *subj, - property *pr, property_permission *pp, int phase) { - int conditional_vis = FALSE; - parse_node *spec; - - if (visible_properties_code_written == FALSE) { - visible_properties_code_written = TRUE; - if (phase == 1) - UnderstandGeneralTokens::begin_distinguishing_visible_properties(gprk); - else - UnderstandGeneralTokens::begin_parsing_visible_properties(gprk); - } - - spec = Visibility::get_condition(pp); - - if (spec) { - conditional_vis = TRUE; - if (phase == 1) - UnderstandGeneralTokens::test_distinguish_visible_property(gprk, spec); - else - UnderstandGeneralTokens::test_parse_visible_property(gprk, spec); - } - - if (phase == 1) - UnderstandGeneralTokens::distinguish_visible_property(gprk, pr); - else - UnderstandGeneralTokens::parse_visible_property(gprk, subj, pr, Visibility::get_level(pp)); - - if (conditional_vis) { EmitCode::up(); EmitCode::up(); } -} - -void UnderstandGeneralTokens::finish_considering_visible_properties(gpr_kit *gprk, int phase) { - if (visible_properties_code_written) { - if (phase == 1) - UnderstandGeneralTokens::finish_distinguishing_visible_properties(gprk); - else - UnderstandGeneralTokens::finish_parsing_visible_properties(gprk); - } -} - -@h 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. - -= -void UnderstandGeneralTokens::begin_distinguishing_visible_properties(gpr_kit *gprk) { - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ACTION_HL)); - EmitCode::val_iname(K_value, Hierarchy::find(THESAME_HL)); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(IFDEBUG_BIP); - EmitCode::down(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(GE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TRACE_HL)); - EmitCode::val_number(4); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(PRINT_BIP); - EmitCode::down(); - EmitCode::val_text(I"p1, p2 = "); - EmitCode::up(); - EmitCode::inv(PRINTNUMBER_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ONE_HL)); - EmitCode::up(); - EmitCode::inv(PRINT_BIP); - EmitCode::down(); - EmitCode::val_text(I", "); - EmitCode::up(); - EmitCode::inv(PRINTNUMBER_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TWO_HL)); - EmitCode::up(); - EmitCode::inv(PRINT_BIP); - EmitCode::down(); - EmitCode::val_text(I"\n"); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->ss_s); - EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); - EmitCode::up(); -} - -void UnderstandGeneralTokens::test_distinguish_visible_property(gpr_kit *gprk, parse_node *spec) { - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(SELF_HL)); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ONE_HL)); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->f_s); - CompileValues::to_code_val_of_kind(spec, K_truth_state); - EmitCode::up(); - - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(SELF_HL)); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TWO_HL)); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->g_s); - CompileValues::to_code_val_of_kind(spec, K_truth_state); - EmitCode::up(); - - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(NE_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->f_s); - EmitCode::val_symbol(K_value, gprk->g_s); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - @; - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->f_s); - EmitCode::code(); - EmitCode::down(); -} - -void UnderstandGeneralTokens::distinguish_visible_property(gpr_kit *gprk, property *prn) { - TEMPORARY_TEXT(C) - WRITE_TO(C, "Distinguishing property %n", RTProperties::iname(prn)); - EmitCode::comment(C); - DISCARD_TEXT(C) - - if (Properties::is_either_or(prn)) { - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(AND_BIP); - EmitCode::down(); - RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(PARSER_ONE_HL), prn); - EmitCode::inv(NOT_BIP); - EmitCode::down(); - RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(PARSER_TWO_HL), prn); - EmitCode::up(); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - @; - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(AND_BIP); - EmitCode::down(); - RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(PARSER_TWO_HL), prn); - EmitCode::inv(NOT_BIP); - EmitCode::down(); - RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(PARSER_ONE_HL), prn); - EmitCode::up(); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - @; - EmitCode::up(); - EmitCode::up(); - } else { - kind *K = ValueProperties::kind(prn); - inter_name *distinguisher = RTKindConstructors::get_distinguisher_iname(K); - EmitCode::inv(IF_BIP); - EmitCode::down(); - if (distinguisher) { - EmitCode::call(distinguisher); - EmitCode::down(); - EmitCode::inv(PROPERTYVALUE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ONE_HL)); - EmitCode::val_iname(K_value, RTProperties::iname(prn)); - EmitCode::up(); - EmitCode::inv(PROPERTYVALUE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TWO_HL)); - EmitCode::val_iname(K_value, RTProperties::iname(prn)); - EmitCode::up(); - EmitCode::up(); - } else { - EmitCode::inv(NE_BIP); - EmitCode::down(); - EmitCode::inv(PROPERTYVALUE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_ONE_HL)); - EmitCode::val_iname(K_value, RTProperties::iname(prn)); - EmitCode::up(); - EmitCode::inv(PROPERTYVALUE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TWO_HL)); - EmitCode::val_iname(K_value, RTProperties::iname(prn)); - EmitCode::up(); - EmitCode::up(); - } - EmitCode::code(); - EmitCode::down(); - @; - EmitCode::up(); - EmitCode::up(); - } -} - -@ = - EmitCode::inv(RETURN_BIP); - EmitCode::down(); - EmitCode::val_number((inter_ti) -2); - EmitCode::up(); - -@ = -void UnderstandGeneralTokens::finish_distinguishing_visible_properties(gpr_kit *gprk) { - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(SELF_HL)); - EmitCode::val_symbol(K_value, gprk->ss_s); - EmitCode::up(); - EmitCode::inv(RETURN_BIP); - EmitCode::down(); - EmitCode::val_number(0); - EmitCode::up(); - EmitCode::up(); - EmitCode::up(); -} - -@h 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. - -= -void UnderstandGeneralTokens::begin_parsing_visible_properties(gpr_kit *gprk) { - EmitCode::comment(I"Match any number of visible property values"); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->try_from_wn_s); - EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->g_s); - EmitCode::val_true(); - EmitCode::up(); - EmitCode::inv(WHILE_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, gprk->g_s); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->g_s); - EmitCode::val_false(); - EmitCode::up(); -} - -void UnderstandGeneralTokens::test_parse_visible_property(gpr_kit *gprk, parse_node *spec) { - EmitCode::inv(IF_BIP); - EmitCode::down(); - CompileValues::to_code_val_of_kind(spec, K_truth_state); - EmitCode::code(); - EmitCode::down(); -} - -int unique_pvp_counter = 0; -void UnderstandGeneralTokens::parse_visible_property(gpr_kit *gprk, - inference_subject *subj, property *prn, int visibility_level) { - TEMPORARY_TEXT(C) - WRITE_TO(C, "Parsing property %n", RTProperties::iname(prn)); - EmitCode::comment(C); - DISCARD_TEXT(C) - - if (Properties::is_either_or(prn)) { - TEMPORARY_TEXT(L) - WRITE_TO(L, ".pvp_pass_L_%d", unique_pvp_counter++); - inter_symbol *pass_label = EmitCode::reserve_label(L); - DISCARD_TEXT(L) - - UnderstandGeneralTokens::parse_visible_either_or( - gprk, prn, visibility_level, pass_label); - property *prnbar = EitherOrProperties::get_negation(prn); - if (prnbar) - UnderstandGeneralTokens::parse_visible_either_or( - gprk, prnbar, visibility_level, pass_label); - - EmitCode::place_label(pass_label); - } else { - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::val_symbol(K_value, gprk->try_from_wn_s); - EmitCode::up(); - - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->spn_s); - EmitCode::val_iname(K_value, Hierarchy::find(PARSED_NUMBER_HL)); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->ss_s); - EmitCode::val_iname(K_value, Hierarchy::find(ETYPE_HL)); - EmitCode::up(); - - EmitCode::inv(IF_BIP); - EmitCode::down(); - kind *K = ValueProperties::kind(prn); - inter_name *recog_gpr = RTKindConstructors::get_recognition_only_GPR_as_iname(K); - if (recog_gpr) { - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::call(recog_gpr); - EmitCode::down(); - EmitCode::inv(PROPERTYVALUE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); - EmitCode::val_iname(K_value, RTProperties::iname(prn)); - EmitCode::up(); - EmitCode::up(); - EmitCode::val_iname(K_value, Hierarchy::find(GPR_PREPOSITION_HL)); - EmitCode::up(); - } else if (RTKindConstructors::offers_I6_GPR(K)) { - inter_name *i6_gpr_name = RTKindConstructors::get_explicit_I6_GPR_iname(K); - if (i6_gpr_name) { - EmitCode::inv(AND_BIP); - EmitCode::down(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::call(i6_gpr_name); - EmitCode::val_iname(K_value, Hierarchy::find(GPR_NUMBER_HL)); - EmitCode::up(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::inv(PROPERTYVALUE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); - EmitCode::val_iname(K_value, RTProperties::iname(prn)); - EmitCode::up(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSED_NUMBER_HL)); - EmitCode::up(); - EmitCode::up(); - } else if (Kinds::Behaviour::is_an_enumeration(K)) { - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::call(RTKindConstructors::get_instance_GPR_iname(K)); - EmitCode::down(); - EmitCode::inv(PROPERTYVALUE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); - EmitCode::val_iname(K_value, RTProperties::iname(prn)); - EmitCode::up(); - EmitCode::up(); - EmitCode::val_iname(K_value, Hierarchy::find(GPR_NUMBER_HL)); - EmitCode::up(); - } else { - EmitCode::inv(AND_BIP); - EmitCode::down(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::call(RTKindConstructors::get_kind_GPR_iname(K)); - EmitCode::val_iname(K_value, Hierarchy::find(GPR_NUMBER_HL)); - EmitCode::up(); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::inv(PROPERTYVALUE_BIP); - EmitCode::down(); - EmitCode::val_iname(K_value, Hierarchy::find(SELF_HL)); - EmitCode::val_iname(K_value, RTProperties::iname(prn)); - EmitCode::up(); - EmitCode::val_iname(K_value, Hierarchy::find(PARSED_NUMBER_HL)); - EmitCode::up(); - EmitCode::up(); - } - } else internal_error("Unable to recognise kind of value in parsing"); - EmitCode::code(); - EmitCode::down(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->try_from_wn_s); - EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->g_s); - EmitCode::val_true(); - EmitCode::up(); - if (visibility_level == 2) { - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->f_s); - EmitCode::val_true(); - EmitCode::up(); - } - EmitCode::up(); - EmitCode::up(); - - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(PARSED_NUMBER_HL)); - EmitCode::val_symbol(K_value, gprk->spn_s); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(ETYPE_HL)); - EmitCode::val_symbol(K_value, gprk->ss_s); - EmitCode::up(); - } -} - -void UnderstandGeneralTokens::parse_visible_either_or(gpr_kit *gprk, property *prn, int visibility_level, - inter_symbol *pass_l) { - command_grammar *cg = EitherOrProperties::get_parsing_grammar(prn); - UnderstandGeneralTokens::pvp_test_begins_dash(gprk); - EmitCode::inv(IF_BIP); - EmitCode::down(); - wording W = prn->name; - int j = 0; LOOP_THROUGH_WORDING(i, W) j++; - int ands = 0; - if (j > 0) { EmitCode::inv(AND_BIP); EmitCode::down(); ands++; } - RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(SELF_HL), prn); - int k = 0; - LOOP_THROUGH_WORDING(i, W) { - if (k < j-1) { EmitCode::inv(AND_BIP); EmitCode::down(); ands++; } - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); - TEMPORARY_TEXT(N) - WRITE_TO(N, "%N", i); - EmitCode::val_dword(N); - DISCARD_TEXT(N) - EmitCode::up(); - k++; - } - - for (int a=0; acompilation_data.cg_prn_iname == NULL) internal_error("no PRN iname"); - UnderstandGeneralTokens::pvp_test_begins_dash(gprk); - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(AND_BIP); - EmitCode::down(); - RTPropertyValues::emit_iname_has_property(K_value, Hierarchy::find(SELF_HL), prn); - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::call(cg->compilation_data.cg_prn_iname); - EmitCode::val_iname(K_value, Hierarchy::find(GPR_PREPOSITION_HL)); - EmitCode::up(); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - UnderstandGeneralTokens::pvp_test_passes_dash(gprk, visibility_level, pass_l); - EmitCode::up(); - EmitCode::up(); - } -} - -void UnderstandGeneralTokens::pvp_test_begins_dash(gpr_kit *gprk) { - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::val_symbol(K_value, gprk->try_from_wn_s); - EmitCode::up(); -} - -void UnderstandGeneralTokens::pvp_test_passes_dash(gpr_kit *gprk, int visibility_level, inter_symbol *pass_l) { - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->try_from_wn_s); - EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::up(); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->g_s); - EmitCode::val_true(); - EmitCode::up(); - if (visibility_level == 2) { - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, gprk->f_s); - EmitCode::val_true(); - EmitCode::up(); - } - if (pass_l) { - EmitCode::inv(JUMP_BIP); - EmitCode::down(); - EmitCode::lab(pass_l); - EmitCode::up(); - } -} - -void UnderstandGeneralTokens::finish_parsing_visible_properties(gpr_kit *gprk) { - EmitCode::up(); - EmitCode::up(); - EmitCode::comment(I"try_from_wn is now advanced past any visible property values"); - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); - EmitCode::val_symbol(K_value, gprk->try_from_wn_s); - EmitCode::up(); -} diff --git a/inform7/runtime-module/Chapter 7/Parsing.w b/inform7/runtime-module/Chapter 7/Parsing.w deleted file mode 100644 index a92cfe2bc..000000000 --- a/inform7/runtime-module/Chapter 7/Parsing.w +++ /dev/null @@ -1,112 +0,0 @@ -[RTParsing::] Parsing. - -@ - -= -void RTParsing::understood_variable(nonlocal_variable *var) { - RTVariables::store_in_this_iname(var, Hierarchy::find(PARSED_NUMBER_HL)); -} - -@ 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. - -= -parse_node *RTParsing::name_property_array(instance *I, wording W, wording PW, - int from_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); - packaging_state save = EmitArrays::begin(name_array, K_value); - - LOOP_THROUGH_WORDING(j, W) { - vocabulary_entry *ve = Lexer::word(j); - ve = PreformUtilities::find_corresponding_word(ve, - , - ); - wchar_t *p = Vocabulary::get_exemplar(ve, FALSE); - TEMPORARY_TEXT(content) - WRITE_TO(content, "%w", p); - EmitArrays::dword_entry(content); - DISCARD_TEXT(content) - } - if (from_kind) /* see test case PM_PluralsFromKind */ - LOOP_THROUGH_WORDING(j, PW) { - int additional = TRUE; - LOOP_THROUGH_WORDING(k, W) - if (compare_word(j, Lexer::word(k))) - additional = FALSE; - if (additional) { - TEMPORARY_TEXT(content) - WRITE_TO(content, "%w", Lexer::word_text(j)); - EmitArrays::plural_dword_entry(content); - DISCARD_TEXT(content) - } - } - - if (PARSING_DATA(I)->understand_as_this_object) - CommandGrammars::take_out_one_word_grammar( - PARSING_DATA(I)->understand_as_this_object); - - 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) - CommandGrammars::take_out_one_word_grammar( - PARSING_DATA_FOR_SUBJ(infs)->understand_as_this_object); - } - } - - EmitArrays::end(save); - Produce::annotate_i(name_array, INLINE_ARRAY_IANN, 1); - return Rvalues::from_iname(name_array); -} - -inter_name *RTParsing::name_iname(void) { - return RTProperties::iname(ParsingPlugin::name_property()); -} - -@ We cache grammar occurring in the source text in conditions, and so forth: - -= -typedef struct cached_understanding { - struct wording understanding_text; /* word range of the understanding text */ - struct inter_name *cu_iname; /* the runtime name for this |Consult_Grammar_N| routine */ - CLASS_DEFINITION -} cached_understanding; - - -void RTParsing::compile_understanding(inter_ti *val1, inter_ti *val2, wording W) { - if ((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); - } - } -} - diff --git a/inform7/runtime-module/Chapter 7/Tokens Parsing Values.w b/inform7/runtime-module/Chapter 7/Tokens Parsing Values.w index 6fe7bb91f..0955dfcf4 100644 --- a/inform7/runtime-module/Chapter 7/Tokens Parsing Values.w +++ b/inform7/runtime-module/Chapter 7/Tokens Parsing Values.w @@ -5,124 +5,13 @@ and I7 makes heavy use of GPR tokens to achieve its ends. This section is where the necessary I6 routines are compiled. @ = -typedef struct gpr_kit { - inter_symbol *cur_addr_s; - inter_symbol *cur_len_s; - inter_symbol *cur_word_s; - inter_symbol *f_s; - inter_symbol *g_s; - inter_symbol *group_wn_s; - inter_symbol *instance_s; - inter_symbol *matched_number_s; - inter_symbol *mid_word_s; - inter_symbol *n_s; - inter_symbol *original_wn_s; - inter_symbol *pass_s; - inter_symbol *pass1_n_s; - inter_symbol *pass2_n_s; - inter_symbol *range_from_s; - inter_symbol *range_words_s; - inter_symbol *rv_s; - local_variable *rv_lv; - inter_symbol *sgn_s; - inter_symbol *spn_s; - inter_symbol *ss_s; - inter_symbol *tot_s; - inter_symbol *try_from_wn_s; - inter_symbol *v_s; - inter_symbol *w_s; - inter_symbol *wpos_s; - inter_symbol *x_s; -} gpr_kit; -gpr_kit UnderstandValueTokens::new_kit(void) { - gpr_kit gprk; - gprk.cur_addr_s = NULL; - gprk.cur_len_s = NULL; - gprk.cur_word_s = NULL; - gprk.f_s = NULL; - gprk.g_s = NULL; - gprk.group_wn_s = NULL; - gprk.instance_s = NULL; - gprk.matched_number_s = NULL; - gprk.mid_word_s = NULL; - gprk.n_s = NULL; - gprk.original_wn_s = NULL; - gprk.pass_s = NULL; - gprk.pass1_n_s = NULL; - gprk.pass2_n_s = NULL; - gprk.range_from_s = NULL; - gprk.range_words_s = NULL; - gprk.rv_s = NULL; - gprk.rv_lv = NULL; - gprk.sgn_s = NULL; - gprk.spn_s = NULL; - gprk.ss_s = NULL; - gprk.tot_s = NULL; - gprk.try_from_wn_s = NULL; - gprk.v_s = NULL; - gprk.w_s = NULL; - gprk.wpos_s = NULL; - gprk.x_s = NULL; - return gprk; -} - -void UnderstandValueTokens::add_instance_call(gpr_kit *gprk) { - gprk->instance_s = LocalVariables::new_other_as_symbol(I"instance"); -} - -void UnderstandValueTokens::add_range_calls(gpr_kit *gprk) { - gprk->range_from_s = LocalVariables::new_internal_commented_as_symbol(I"range_from", I"call parameter: word number of snippet start"); - gprk->range_words_s = LocalVariables::new_internal_commented_as_symbol(I"range_words", I"call parameter: snippet length"); -} - -void UnderstandValueTokens::add_original(gpr_kit *gprk) { - gprk->original_wn_s = LocalVariables::new_internal_as_symbol(I"original_wn"); -} - -void UnderstandValueTokens::add_standard_set(gpr_kit *gprk) { - gprk->group_wn_s = LocalVariables::new_internal_as_symbol(I"group_wn"); - gprk->v_s = LocalVariables::new_internal_as_symbol(I"v"); - gprk->w_s = LocalVariables::new_internal_as_symbol(I"w"); - gprk->rv_lv = LocalVariables::new_internal(I"rv"); - gprk->rv_s = LocalVariables::declare(gprk->rv_lv); -} - -void UnderstandValueTokens::add_lp_vars(gpr_kit *gprk) { - gprk->wpos_s = LocalVariables::new_internal_as_symbol(I"wpos"); - gprk->mid_word_s = LocalVariables::new_internal_as_symbol(I"mid_word"); - gprk->matched_number_s = LocalVariables::new_internal_as_symbol(I"matched_number"); - gprk->cur_word_s = LocalVariables::new_internal_as_symbol(I"cur_word"); - gprk->cur_len_s = LocalVariables::new_internal_as_symbol(I"cur_len"); - gprk->cur_addr_s = LocalVariables::new_internal_as_symbol(I"cur_addr"); - gprk->sgn_s = LocalVariables::new_internal_as_symbol(I"sgn"); - gprk->tot_s = LocalVariables::new_internal_as_symbol(I"tot"); - gprk->f_s = LocalVariables::new_internal_as_symbol(I"f"); - gprk->x_s = LocalVariables::new_internal_as_symbol(I"x"); -} - -void UnderstandValueTokens::add_parse_name_vars(gpr_kit *gprk) { - gprk->original_wn_s = LocalVariables::new_internal_commented_as_symbol(I"original_wn", I"first word of text parsed"); - gprk->group_wn_s = LocalVariables::new_internal_commented_as_symbol(I"group_wn", I"first word matched against A/B/C/... disjunction"); - gprk->try_from_wn_s = LocalVariables::new_internal_commented_as_symbol(I"try_from_wn", I"position to try matching from"); - gprk->n_s = LocalVariables::new_internal_commented_as_symbol(I"n", I"number of words matched"); - gprk->f_s = LocalVariables::new_internal_commented_as_symbol(I"f", I"flag: sufficiently good match found to justify success"); - gprk->w_s = LocalVariables::new_internal_commented_as_symbol(I"w", I"for use by individual grammar lines"); - gprk->rv_lv = LocalVariables::new_internal(I"rv"); - gprk->rv_s = LocalVariables::declare(gprk->rv_lv); - gprk->g_s = LocalVariables::new_internal_commented_as_symbol(I"g", I"temporary: success flag for parsing visibles"); - gprk->ss_s = LocalVariables::new_internal_commented_as_symbol(I"ss", I"temporary: saves 'self' in distinguishing visibles"); - gprk->spn_s = LocalVariables::new_internal_commented_as_symbol(I"spn", I"temporary: saves 'parsed_number' in parsing visibles"); - gprk->pass_s = LocalVariables::new_internal_commented_as_symbol(I"pass", I"pass counter (1 to 3)"); - gprk->pass1_n_s = LocalVariables::new_internal_commented_as_symbol(I"pass1_n", I"value of n recorded during pass 1"); - gprk->pass2_n_s = LocalVariables::new_internal_commented_as_symbol(I"pass2_n", I"value of n recorded during pass 2"); -} void UnderstandValueTokens::number(void) { inter_name *iname = Hierarchy::find(DECIMAL_TOKEN_INNER_HL); packaging_state save = Functions::begin(iname); - gpr_kit gprk = UnderstandValueTokens::new_kit(); - UnderstandValueTokens::add_original(&gprk); + gpr_kit gprk = GPRs::new_kit(); + GPRs::add_original_var(&gprk); command_grammar *cg = CommandGrammars::get_parsing_grammar(K_number); if (cg) RTCommandGrammars::compile_iv(&gprk, cg); EmitCode::inv(RETURN_BIP); @@ -136,8 +25,8 @@ void UnderstandValueTokens::number(void) { void UnderstandValueTokens::time(void) { inter_name *iname = Hierarchy::find(TIME_TOKEN_INNER_HL); packaging_state save = Functions::begin(iname); - gpr_kit gprk = UnderstandValueTokens::new_kit(); - UnderstandValueTokens::add_original(&gprk); + gpr_kit gprk = GPRs::new_kit(); + GPRs::add_original_var(&gprk); kind *K = TimesOfDay::kind(); if (K) { command_grammar *cg = CommandGrammars::get_parsing_grammar(K); @@ -154,8 +43,8 @@ void UnderstandValueTokens::time(void) { void UnderstandValueTokens::truth_state(void) { inter_name *iname = Hierarchy::find(TRUTH_STATE_TOKEN_INNER_HL); packaging_state save = Functions::begin(iname); - gpr_kit gprk = UnderstandValueTokens::new_kit(); - UnderstandValueTokens::add_original(&gprk); + gpr_kit gprk = GPRs::new_kit(); + GPRs::add_original_var(&gprk); command_grammar *cg = CommandGrammars::get_parsing_grammar(K_truth_state); if (cg) RTCommandGrammars::compile_iv(&gprk, cg); EmitCode::inv(RETURN_BIP); @@ -180,20 +69,20 @@ void UnderstandValueTokens::agent(compilation_subtask *t) { need_lf_vars = TRUE; break; } - gpr_kit gprk = UnderstandValueTokens::new_kit(); - UnderstandValueTokens::add_original(&gprk); - UnderstandValueTokens::add_standard_set(&gprk); - if (need_lf_vars) UnderstandValueTokens::add_lp_vars(&gprk); + gpr_kit gprk = GPRs::new_kit(); + GPRs::add_original_var(&gprk); + GPRs::add_standard_vars(&gprk); + if (need_lf_vars) GPRs::add_LP_vars(&gprk); @; Functions::end(save); if (Kinds::Behaviour::is_an_enumeration(K)) { inter_name *iname = RTKindConstructors::get_instance_GPR_iname(K); packaging_state save = Functions::begin(iname); - gpr_kit gprk = UnderstandValueTokens::new_kit(); - UnderstandValueTokens::add_instance_call(&gprk); - UnderstandValueTokens::add_original(&gprk); - UnderstandValueTokens::add_standard_set(&gprk); + gpr_kit gprk = GPRs::new_kit(); + GPRs::add_instance_var(&gprk); + GPRs::add_original_var(&gprk); + GPRs::add_standard_vars(&gprk); GV_IS_VALUE_instance_mode = TRUE; @; GV_IS_VALUE_instance_mode = FALSE; @@ -218,20 +107,20 @@ void UnderstandValueTokens::compile_type_gprs(void) { need_lf_vars = TRUE; break; } - gpr_kit gprk = UnderstandValueTokens::new_kit(); - UnderstandValueTokens::add_original(&gprk); - UnderstandValueTokens::add_standard_set(&gprk); - if (need_lf_vars) UnderstandValueTokens::add_lp_vars(&gprk); + gpr_kit gprk = GPRs::new_kit(); + GPRs::add_original_var(&gprk); + GPRs::add_standard_vars(&gprk); + if (need_lf_vars) GPRs::add_LP_vars(&gprk); @; Functions::end(save); if (Kinds::Behaviour::is_an_enumeration(K)) { inter_name *iname = RTKindConstructors::get_instance_GPR_iname(K); packaging_state save = Functions::begin(iname); - gpr_kit gprk = UnderstandValueTokens::new_kit(); - UnderstandValueTokens::add_instance_call(&gprk); - UnderstandValueTokens::add_original(&gprk); - UnderstandValueTokens::add_standard_set(&gprk); + gpr_kit gprk = GPRs::new_kit(); + GPRs::add_instance_var(&gprk); + GPRs::add_original_var(&gprk); + GPRs::add_standard_vars(&gprk); GV_IS_VALUE_instance_mode = TRUE; @; GV_IS_VALUE_instance_mode = FALSE; diff --git a/inform7/runtime-module/Contents.w b/inform7/runtime-module/Contents.w index 0d79d6713..f63079c90 100644 --- a/inform7/runtime-module/Contents.w +++ b/inform7/runtime-module/Contents.w @@ -26,6 +26,7 @@ Chapter 2: Emission Showme Command Here, Nowhere and Everywhere Short Names + General Parsing Routines Chapter 3: Basics Generic Module @@ -74,15 +75,15 @@ Chapter 6: Completion Resources Bibliographic Data The Player The Map + Name Properties + Parse Name Properties Chapter 7: Still Unsorted Emit Property Values Instance Counting Action Patterns Going - Parsing Command Grammars Command Grammar Lines Noun Filter Tokens Tokens Parsing Values - General Parsing Routines