The structure action_name is accessed in 4/ap, 4/as, 4/av, 4/ann, 4/anl, 4/nap, 5/cg, 5/cgl, 5/gpr and here.
+
The structure action_name is accessed in 4/ap, 4/as, 4/av, 4/ann, 4/anl, 4/nap, 5/cg, 5/cgl and here.
§2. Note that we notify the K_action_name kind that a new enumerated value
for it exists; we don't need to record the reply (i.e. the number used as
this value at run-time) because it will be the same as the allocation ID
diff --git a/docs/if-module/4-nap.html b/docs/if-module/4-nap.html
index 5cfd84608..ee8bc333f 100644
--- a/docs/if-module/4-nap.html
+++ b/docs/if-module/4-nap.html
@@ -93,7 +93,7 @@ this category if it matches one of the patterns.
CLASS_DEFINITION} named_action_pattern_entry;
-
The structure named_action_pattern is accessed in 4/anaa, 4/act, 4/ann, 4/anl, 5/cg, 5/cgl, 5/gpr and here.
The structure named_action_pattern_entry is private to this section.
+
The structure named_action_pattern is accessed in 4/anaa, 4/act, 4/ann, 4/anl, 5/cg, 5/cgl and here.
The structure named_action_pattern_entry is private to this section.
§2. We are allowed to give names to certain kinds of behaviour by "characterising"
an action.
diff --git a/docs/if-module/5-cg.html b/docs/if-module/5-cg.html
index 553fcd9e6..612fd4bb8 100644
--- a/docs/if-module/5-cg.html
+++ b/docs/if-module/5-cg.html
@@ -144,7 +144,7 @@ form, so this is not as bloated a structure as it looks.
CLASS_DEFINITION} command_grammar;
-
The structure command_grammar is accessed in 4/act, 4/nap, 5/cgl, 5/gpr and here.
+
The structure command_grammar is accessed in 4/act, 4/nap, 5/cgl and here.
§4. We begin as usual with a constructor and some debug log tracing.
@@ -447,7 +447,7 @@ different numbers, for example; the returncg;}
-command_grammar *CommandGrammars::get_parsing_grammar(kind *K) {
+command_grammar *CommandGrammars::get_parsing_grammar(kind *K) {if (K == NULL) returnNULL;if (Kinds::Behaviour::is_object(K)) internal_error("cannot get CG for K_object");returnK->construct->understand_as_values;
@@ -475,11 +475,11 @@ in which players consulted a biographical dictionary of the Meldrew family.
command_grammar *consultation_gv = NULL;
-voidCommandGrammars::prepare_consultation_cg(void) {
+voidCommandGrammars::prepare_consultation_cg(void) {consultation_gv = NULL;}
-command_grammar *CommandGrammars::get_consultation_cg(void) {
+command_grammar *CommandGrammars::get_consultation_cg(void) {if (consultation_gv == NULL) consultation_gv = CommandGrammars::cg_new(CG_IS_CONSULT);returnconsultation_gv;}
@@ -491,7 +491,7 @@ property value used adjectivally like this can be given a CG.
-command_grammar *CommandGrammars::for_prn(property *prn) {
+command_grammar *CommandGrammars::for_prn(property *prn) {if (EitherOrProperties::get_parsing_grammar(prn) != NULL)returnEitherOrProperties::get_parsing_grammar(prn);command_grammar *cg = CommandGrammars::cg_new(CG_IS_PROPERTY_NAME);
@@ -507,12 +507,12 @@ are not possible, but see CommandGramm
diff --git a/docs/if-module/5-cgl.html b/docs/if-module/5-cgl.html
index 18f780a52..0282a7b59 100644
--- a/docs/if-module/5-cgl.html
+++ b/docs/if-module/5-cgl.html
@@ -140,7 +140,7 @@ removing it from action. That's a feature only seen in lines for
CLASS_DEFINITION} cg_line;
-
The structure cg_line is accessed in 4/ap, 4/act, 4/as, 4/nap, 5/us, 5/cg, 5/gpr and here.
+
The structure cg_line is accessed in 4/ap, 4/act, 4/as, 4/nap, 5/us, 5/cg and here.
§2.
@@ -377,10 +377,10 @@ detected by the following function:
if ((cgl->tokens) && (cgl->tokens->next_token == NULL) && (cgl->tokens->slash_class == 0)
- && (CGTokens::is_literal(cgl->tokens))
+ && (CGTokens::is_literal(cgl->tokens)) && (cgl->pluralised == FALSE) && (CGLines::conditional(cgl) == FALSE))
-returnWordings::first_wn(CGTokens::text(cgl->tokens));
+returnWordings::first_wn(CGTokens::text(cgl->tokens));return -1;}
@@ -390,7 +390,7 @@ this purpose, so:
-voidCGLines::slash(command_grammar *cg) {
+voidCGLines::slash(command_grammar *cg) {LOOP_THROUGH_UNSORTED_CG_LINES(cgl, cg) {current_sentence = cgl->where_grammar_specified;Annotate the CG tokens with slash-class and slash-dash-dash15.1;
@@ -446,8 +446,9 @@ definition no effect, and disappears without trace in this process.
intalternatives_group = 0;cg_token *class_start = NULL;LOOP_THROUGH_CG_TOKENS(cgt, cgl) {
-if ((cgt->next_token) && (Wordings::length(CGTokens::text(cgt->next_token)) == 1) &&
- (Lexer::word(Wordings::first_wn(CGTokens::text(cgt->next_token))) == FORWARDSLASH_V)) {
+if ((cgt->next_token) && (Wordings::length(CGTokens::text(cgt->next_token)) == 1) &&
+ (Lexer::word(Wordings::first_wn(CGTokens::text(cgt->next_token))) ==
+FORWARDSLASH_V)) {if (cgt->slash_class == 0) {class_start = cgt; alternatives_group++; start new equiv classclass_start->slash_dash_dash = FALSE;
@@ -456,12 +457,13 @@ definition no effect, and disappears without trace in this process.
if (cgt->next_token->next_token)cgt->next_token->next_token->slash_class = alternatives_group;if ((cgt->next_token->next_token) &&
- (Wordings::length(CGTokens::text(cgt->next_token->next_token)) == 1) &&
- (Lexer::word(Wordings::first_wn(CGTokens::text(cgt->next_token->next_token))) == DOUBLEDASH_V)) {
+ (Wordings::length(CGTokens::text(cgt->next_token->next_token)) == 1) &&
+ (Lexer::word(Wordings::first_wn(CGTokens::text(cgt->next_token->next_token))) ==
+DOUBLEDASH_V)) {class_start->slash_dash_dash = TRUE;
-cgt->next_token = cgt->next_token->next_token->next_token; excise slash and dash-dash
+cgt->next_token = cgt->next_token->next_token->next_token; excise both } else {
-cgt->next_token = cgt->next_token->next_token; excise the slash from the token list
+cgt->next_token = cgt->next_token->next_token; excise slash } } }
@@ -473,7 +475,7 @@ definition no effect, and disappears without trace in this process.
LOOP_THROUGH_CG_TOKENS(cgt, cgl)if ((cgt->slash_class > 0) &&
- (CGTokens::is_literal(cgt) == FALSE)) {
+ (CGTokens::is_literal(cgt) == FALSE)) {StandardProblems::sentence_problem(Task::syntax_tree(),_p_(PM_OverAmbitiousSlash),"the slash '/' can only be used between single literal words",
@@ -564,9 +566,9 @@ affect how the list will be arranged when it is compiled.
}
§16.1. The general sort bonus is \(Rs_0 + s_1\), where \(R\) is the CGL_SCORE_TOKEN_RANGE
-and \(s_0\), \(s_1\) are the scores for the first and second tokens describing values;
-or if none of the \(n\) tokens describes a value, it is \(R^2n\), which is guaranteed
-to be larger.
+and \(s_0\), \(s_1\) are the scores for the first and second tokens describing values,
+which are such that \(0\leq s_i<R\); or if none of the \(n\) tokens describes a value,
+the GSB is \(R^2n\), which is guaranteed to be much larger.
However, there is also an understanding sort bonus, which is really a penalty
@@ -577,8 +579,9 @@ number, but is such that a "[text]" earlier in the line is penalised just a
little bit more than a "[text]" later.
-
For \(R=10\), the following might thus happen. (For simplicity, I've assumed
-the individual tokens scores are 1.)
+
For \(R=10\), the following might thus happen. (I've simplified this table by
+having the individual tokens all score 1, but in fact they can score a range
+of small numbers: see CGTokens::score_bonus.)
@@ -600,22 +603,24 @@ parsing the player's command at run-time. For the exact sorting rules, see below
intnulls_count = 0, pos = 0;
-for (cg_token *cgtt = first; cgtt; cgtt = cgtt->next_token) {
-intscore = 0;
-parse_node *spec = CGTokens::determine(cgtt, depth, &score);
+for (cg_token *cgt = first; cgt; cgt = cgt->next_token) {
+parse_node *spec = CGTokens::determine(cgt, depth);
+intscore = CGTokens::score_bonus(cgt);
+if ((score < 0) || (score >= CGL_SCORE_TOKEN_RANGE))
+internal_error("token score out of range");LOGIF(GRAMMAR_CONSTRUCTION, "token %d/%d: <%W> --> $P (score %d)\n",
-pos+1, line_length, CGTokens::text(cgtt), spec, score);
+pos+1, line_length, CGTokens::text(cgt), spec, score);if (spec) {Text tokens contribute also to the understanding sort bonus16.1.1;intscore_multiplier = 1;if (DeterminationTypes::get_no_values_described(&(cgl->cgl_type)) == 0)score_multiplier = CGL_SCORE_TOKEN_RANGE;DeterminationTypes::add_term(&(cgl->cgl_type), spec,
-CGTokens::is_multiple(cgtt));
+CGTokens::is_multiple(cgt));cgl->general_sort_bonus += score*score_multiplier; } elsenulls_count++;
-if (CGTokens::is_multiple(cgtt)) multiples++;
+if (CGTokens::is_multiple(cgt)) multiples++;pos++; }if (nulls_count == line_length)
@@ -823,7 +828,7 @@ the specificity of the tokens is what decides. The first token is more important
than the second, and a more specific token comes before a lower one.
-
§1. Introduction. Until 2021, CG tokens were held as parse nodes in the syntax tree, with a
+special type TOKEN_NT and a set of annotations, but as cute as that was
+it was also obfuscatory, and now each CG token corresponds to a cg_token
+object as follows:
+
typedefstructcg_token {structwordingtext_of_token;
-intis_literal;
-intslash_class;
-intslash_dash_dash;intgrammar_token_code;
-structparse_node *grammar_value; 0 or else one of the *_GTC values
+structparse_node *what_token_describes; 0 or else one of the *_GTC valuesstructbinary_predicate *token_relation;
-structcg_token *next_token;
+structnoun_filter_token *noun_filter;
+structcommand_grammar *defined_by;
+intslash_class; used in slashing: see CGLines::slash
+intslash_dash_dash; ditto
+structcg_token *next_token; in the list for a CG lineCLASS_DEFINITION} cg_token;
-wordingCGTokens::text(cg_token *cgt) {
-returncgt?(cgt->text_of_token):(EMPTY_WORDING);
+cg_token *CGTokens::cgt_of(wordingW, intlit) {
+cg_token *cgt = CREATE(cg_token);
+cgt->text_of_token = W;
+cgt->slash_dash_dash = FALSE;
+cgt->slash_class = 0;
+cgt->what_token_describes = NULL;
+cgt->grammar_token_code = lit?LITERAL_GTC:0;
+cgt->token_relation = NULL;
+cgt->noun_filter = NULL;
+cgt->defined_by = NULL;
+cgt->next_token = NULL;
+returncgt;}
The structure cg_token is accessed in 5/cgl and here.
-
§2. Tokens with a nonzero grammar_token_code correspond closely to what are
-also called "tokens" in the runtime command parser.
+
§2. Text to a CG token list. Tokens are created when text such as "drill [something] with [something]"
+is parsed, from an Understand sentence or elsewhere. What happens is much
+the same as when text with substitutions is read: the text is retokenised
+by the lexer to produce the following, in which the square brackets have
+become commas:
-
defineNAMED_TOKEN_GTC1 these positive values are used only in parsing
+
+"drill" , something , "with" , something
+
+
In fact we use a different punctuation set from the lexer's default, because
+we want forward slashes to break words, so that we need / to be a punctuation
+mark: thus "get away/off/out" becomes
+
+
+
+"get" "away" / "off" / "out"
+
+
defineGRAMMAR_PUNCTUATION_MARKSL".,:;?!(){}[]/" note the slash
+
+
+cg_token *CGTokens::tokenise(wordingW) {
+wchar_t *as_wide_string = Lexer::word_text(Wordings::first_wn(W));
+Reject this if it contains punctuation2.1;
+wordingTW = Feeds::feed_C_string_full(as_wide_string, TRUE,
+GRAMMAR_PUNCTUATION_MARKS);
+Reject this if it contains two consecutive commas2.2;
+
+cg_token *tokens = CGTokens::break_into_tokens(TW);
+if (tokens == NULL) {
+StandardProblems::sentence_problem(Task::syntax_tree(),
+_p_(PM_UnderstandEmptyText),
+"'understand' should be followed by text which contains at least "
+"one word or square-bracketed token",
+"so for instance 'understand \"take [something]\" as taking' is fine, "
+"but 'understand \"\" as the fog' is not. The same applies to the contents "
+"of 'topic' columns in tables, since those are also instructions for "
+"understanding.");
+ }
+returntokens;
+}
+
+
§2.1. Reject this if it contains punctuation2.1 =
+
+
+
+intskip = FALSE, literal_punct = FALSE;
+for (inti=0; as_wide_string[i]; i++) {
+if (as_wide_string[i] == '[') skip = TRUE;
+if (as_wide_string[i] == ']') skip = FALSE;
+if (skip) continue;
+if ((as_wide_string[i] == '.') || (as_wide_string[i] == ',') ||
+ (as_wide_string[i] == '!') || (as_wide_string[i] == '?') ||
+ (as_wide_string[i] == ':') || (as_wide_string[i] == ';'))
+literal_punct = TRUE;
+ }
+if (literal_punct) {
+StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_LiteralPunctuation),
+"'understand' text cannot contain literal punctuation",
+"or more specifically cannot contain any of these: . , ! ? : ; since they "
+"are already used in various ways by the parser, and would not correctly "
+"match here.");
+returnNULL;
+ }
+
§2.2. Reject this if it contains two consecutive commas2.2 =
+
+
+
+LOOP_THROUGH_WORDING(i, TW)
+if (i < Wordings::last_wn(TW))
+if ((compare_word(i, COMMA_V)) && (compare_word(i+1, COMMA_V))) {
+StandardProblems::sentence_problem(Task::syntax_tree(),
+_p_(PM_UnderstandCommaCommand),
+"'understand' as an action cannot involve a comma",
+"since a command leading to an action never does. "
+"(Although Inform understands commands like 'PETE, LOOK' "
+"only the part after the comma is read as an action command: "
+"the part before the comma is read as the name of someone, "
+"according to the usual rules for parsing a name.) "
+"Because of the way Inform processes text with square "
+"brackets, this problem message is also sometimes seen "
+"if empty square brackets are used, as in 'Understand "
+"\"bless []\" as blessing.'");
+returnNULL;
+ }
+
§7. The GTC. The GTC, or grammar token code, is a sort of type indicator for tokens. As
+produced by the tokeniser above, tokens initially have GTC either UNDETERMINED_GTC
+or LITERAL_GTC. Differentiation of non-literal tokens into other types happens
+in CGTokens::determine.
+
+
+
Note that there are two sets of GTC values, one set positive, one negative. The
+negative ones correspond closely to command-parser grammar reserved tokens in
+the old I6 compiler, and this is indeed what they compile to if we are
+generating I6 code.
+
+
+
defineNAMED_TOKEN_GTC1defineRELATED_GTC2defineSTUFF_GTC3defineANY_STUFF_GTC4defineANY_THINGS_GTC5
-defineNOUN_TOKEN_GTC -1 I6 noun
-defineMULTI_TOKEN_GTC -2 I6 multi
-defineMULTIINSIDE_TOKEN_GTC -3 I6 multiinside
-defineMULTIHELD_TOKEN_GTC -4 I6 multiheld
-defineHELD_TOKEN_GTC -5 I6 held
-defineCREATURE_TOKEN_GTC -6 I6 creature
-defineTOPIC_TOKEN_GTC -7 I6 topic
-defineMULTIEXCEPT_TOKEN_GTC -8 I6 multiexcept
+defineLITERAL_GTC6
+defineUNDETERMINED_GTC0
+defineNOUN_TOKEN_GTC -1 like I6 noun
+defineMULTI_TOKEN_GTC -2 like I6 multi
+defineMULTIINSIDE_TOKEN_GTC -3 like I6 multiinside
+defineMULTIHELD_TOKEN_GTC -4 like I6 multiheld
+defineHELD_TOKEN_GTC -5 like I6 held
+defineCREATURE_TOKEN_GTC -6 like I6 creature
+defineTOPIC_TOKEN_GTC -7 like I6 topic
+defineMULTIEXCEPT_TOKEN_GTC -8 like I6 multiexcept
§8. A multiple token is one which permits multiple matches in the run-time command
+parser: for instance, the player can type ALL where a MULTI_TOKEN_GTC is
+expected.
+
+voidCGTokens::log(cg_token *cgt) {if (cgt == NULL) LOG("<no-cgt>");else {LOG("<CGT%d:%W", cgt->allocation_id, cgt->text_of_token);
@@ -139,252 +359,50 @@ also called "tokens" in the runtime command parser.
}}
-
§3.
-
-
is_literal is set for literal words such as "into"
-and clear for square-bracketed tokens such as "[something]".
+
§10. Parsing nonliteral tokens. Unless a token is literal and in double-quotes, it will start out as having
+UNDETERMINED_GTC until we investigate what the words in it mean, which we
+will do with the following Preform grammar.
-
The grammar_token_code annotation is meaningful only for parse nodes
-with an evaluation of type DESCRIPTION. These are tokens which describe a
-range of objects. Examples include "[open container]", which compiles to an
-I6 noun filter, "[any container]", which compiles to an I6 scope filter, or
-"[things]", one of a small number of special cases compiling to primitive I6
-parser tokens. The annotation holds the allocation ID for the noun/scope
-filter structure built for the occasion in the former cases, and one of the
-following constants in the latter case. (These must all have negative values
-in order not to clash with allocation IDs 0, 1, 2, ..., and clearly must all
-be different, but otherwise the values are not significant and there is no
-preferred order.)
-
-
-
For tokens with any other evaluation, general_purpose is always 0, so
-that the special values below cannot arise.
-
-
-
§4. Tokens are created when text such as "drill [something] with [something]"
-is parsed, from an Understand sentence or elsewhere. What happens is much
-the same as when text with substitutions is read: that produces
-
-
-
-
"drill", something, "with", something
-
-
-
and the following little grammar is used to divide this text up into its
-four constituent tokens.
-
§5. We use a different punctuation set, in which forward slashes break words,
-to handle such as:
-
-
-
-
Understand "get away/off/out" as exiting.
-
-
-
Inform would ordinarily lex the text away/off/out as one single word — so that
-something like "on/off switch" would be regarded as two words not four —
-but with slash treated as a punctuation mark, we instead read "away / off /
-out", a sequence of five lexical words.
-
-
-
defineGRAMMAR_PUNCTUATION_MARKSL".,:;?!(){}[]/" note the slash...
-
§7. The special tokens. Do not change any of these GTC numbers without first checking and updating
-the discussion of CGL sorting in Command Grammar Lines:
-
-
-
-intCGTokens::gsb_for_special_token(intgtc) {
-switch(gtc) {
-caseNOUN_TOKEN_GTC:return0;
-caseMULTI_TOKEN_GTC:return0;
-caseMULTIINSIDE_TOKEN_GTC:return1;
-caseMULTIHELD_TOKEN_GTC:return2;
-caseHELD_TOKEN_GTC:return3;
-caseCREATURE_TOKEN_GTC:return0;
-caseTOPIC_TOKEN_GTC:return -1;
-caseMULTIEXCEPT_TOKEN_GTC:return2;
-default:internal_error("tried to find GSB for invalid GTC");
- }
-return0; to prevent a gcc error: never reached
-}
-
-
§8. These translate into I6 as follows:
-
-
-
-char *CGTokens::i6_token_for_special_token(intgtc) {
-switch(gtc) {
-caseNOUN_TOKEN_GTC:return"noun";
-caseMULTI_TOKEN_GTC:return"multi";
-caseMULTIINSIDE_TOKEN_GTC:return"multiinside";
-caseMULTIHELD_TOKEN_GTC:return"multiheld";
-caseHELD_TOKEN_GTC:return"held";
-caseCREATURE_TOKEN_GTC:return"creature";
-caseTOPIC_TOKEN_GTC:return"topic";
-caseMULTIEXCEPT_TOKEN_GTC:return"multiexcept";
-default:internal_error("tried to find I6 token for invalid GTC");
- }
-return""; to prevent a gcc error: never reached
-}
-
-inter_name *CGTokens::iname_for_special_token(intgtc) {
-switch(gtc) {
-caseNOUN_TOKEN_GTC:returnVERB_DIRECTIVE_NOUN_iname;
-caseMULTI_TOKEN_GTC:returnVERB_DIRECTIVE_MULTI_iname;
-caseMULTIINSIDE_TOKEN_GTC:returnVERB_DIRECTIVE_MULTIINSIDE_iname;
-caseMULTIHELD_TOKEN_GTC:returnVERB_DIRECTIVE_MULTIHELD_iname;
-caseHELD_TOKEN_GTC:returnVERB_DIRECTIVE_HELD_iname;
-caseCREATURE_TOKEN_GTC:returnVERB_DIRECTIVE_CREATURE_iname;
-caseTOPIC_TOKEN_GTC:returnVERB_DIRECTIVE_TOPIC_iname;
-caseMULTIEXCEPT_TOKEN_GTC:returnVERB_DIRECTIVE_MULTIEXCEPT_iname;
-default:internal_error("tried to find inter name for invalid GTC");
- }
-returnNULL; to prevent a gcc error: never reached
-}
-
-char *CGTokens::i6_constant_for_special_token(intgtc) {
-switch(gtc) {
-caseNOUN_TOKEN_GTC:return"NOUN_TOKEN";
-caseMULTI_TOKEN_GTC:return"MULTI_TOKEN";
-caseMULTIINSIDE_TOKEN_GTC:return"MULTIINSIDE_TOKEN";
-caseMULTIHELD_TOKEN_GTC:return"MULTIHELD_TOKEN";
-caseHELD_TOKEN_GTC:return"HELD_TOKEN";
-caseCREATURE_TOKEN_GTC:return"CREATURE_TOKEN";
-caseTOPIC_TOKEN_GTC:return"TOPIC_TOKEN";
-caseMULTIEXCEPT_TOKEN_GTC:return"MULTIEXCEPT_TOKEN";
-default:internal_error("tried to find I6 constant for invalid GTC");
- }
-return""; to prevent a gcc error: never reached
-}
-
-
§9. The special tokens all return a value in I6 which needs a kind
-to be used in I7: these are defined by the following routine.
-
§10. The tokens which aren't literal words in double-quotes are parsed as follows:
+
Note that <grammar-token> always matches any text, even if it sometimes throws
+a problem message on the way. Its return integer is a valid GTC, and its
+return pointer is a (non-null) description of what the token matches.
@@ -408,10 +447,10 @@ to be used in I7: these are defined by the following routine.
"invites me to understand names of related things, ""but the relation is not one that I know.");Problems::issue_problem_end();
- ==> { RELATED_GTC, NULL };
+ ==> { RELATED_GTC, Rvalues::from_binary_predicate(R_equality) }
@@ -429,10 +468,10 @@ to be used in I7: these are defined by the following routine.
"or in descriptions of actions or in table columns; it's really ""intended only for defining new commands.");Problems::issue_problem_end();
- ==> { TOPIC_TOKEN_GTC, NULL };
+ ==> { TOPIC_TOKEN_GTC, Specifications::from_kind(K_understanding) };
@@ -445,33 +484,65 @@ to be used in I7: these are defined by the following routine.
"all here', but Inform uses the special syntax '[thing]' ""for that. (Or '[things]' if multiple objects are allowed.)");Problems::issue_problem_end();
- ==> { MULTI_TOKEN_GTC, NULL };
+ ==> { MULTI_TOKEN_GTC, Specifications::from_kind(K_object) }
§10.6. Something of an extended mea culpa: but it had the desired effect, in
+
§10.9. Issue PM_BizarreToken problem10.9 =
+
+
+
+LOG("$T", current_sentence);
+Problems::quote_source(1, current_sentence);
+Problems::quote_wording(2, W);
+Problems::quote_kind_of(3, RP[1]);
+StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_BizarreToken));
+Problems::issue_problem_segment(
+"The grammar token '%2' in the sentence %1 looked to me as "
+"if it might be %3, but this isn't something allowed in "
+"parsing grammar.");
+Problems::issue_problem_end();
+ ==> { STUFF_GTC, Specifications::from_kind(K_thing) }
+
+LOG("$T", current_sentence);
+Problems::quote_source(1, current_sentence);
+Problems::quote_wording(2, W);
+StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_UnknownToken));
+Problems::issue_problem_segment(
+"I was unable to understand what you meant by the grammar token '%2' "
+"in the sentence %1.");
+Problems::issue_problem_end();
+ ==> { STUFF_GTC, Specifications::from_kind(K_thing) }
+
§11. Something of an extended mea culpa: but it had the desired effect, in
that nobody complained about what might have been a controversial change.
-voidCGTokens::incompatible_change_problem(char *token_tried, char *token_instead,
+voidCGTokens::incompatible_change_problem(char *token_tried, char *token_instead,char *token_better) {Problems::quote_source(1, current_sentence);Problems::quote_text(2, token_tried);
@@ -497,141 +568,130 @@ that nobody complained about what might have been a controversial change.
Problems::issue_problem_end();}
-
§10.7. Issue PM_BizarreToken problem10.7 =
+
§12. Determining. To calculate a description of what is being described by a token, then, we
+call the following function, which delegates to <grammar-token> above.
+
+
+
In the two cases NAMED_TOKEN_GTC and RELATED_GTC the pointer result is
+a temporary one telling us which named token, and which relation, respectively:
+we then convert those into the result. In all other cases, the parse_node
+pointer returned by <grammar-token> is the result.
-LOG("$T", current_sentence);
-Problems::quote_source(1, current_sentence);
-Problems::quote_wording(2, W);
-Problems::quote_kind_of(3, RP[1]);
-StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_BizarreToken));
-Problems::issue_problem_segment(
-"The grammar token '%2' in the sentence %1 looked to me as "
-"if it might be %3, but this isn't something allowed in "
-"parsing grammar.");
-Problems::issue_problem_end();
- ==> { STUFF_GTC, - };
-
-LOG("$T", current_sentence);
-Problems::quote_source(1, current_sentence);
-Problems::quote_wording(2, W);
-StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_UnknownToken));
-Problems::issue_problem_segment(
-"I was unable to understand what you meant by the grammar token '%2' "
-"in the sentence %1.");
-Problems::issue_problem_end();
- ==> { STUFF_GTC, - };
-
§12.1. If the token determines an actual constant value — as it can when it is a
+named token which always refers to a specific thing, for example — it is
+possible for result not to be a description. Otherwise, though, it has to
+be a description which is true or false for any given value, so:
+
+
+
Make sure the result is a description with one free variable12.1 =
§11.6. Vet the grammar token determination for parseability at run-time11.6 =
-
-
-
-if (Specifications::is_description(spec)) {
-kind *K = Specifications::to_kind(spec);
+if (Specifications::is_description(result)) {
+kind *K = Specifications::to_kind(result);if ((K_understanding) && (Kinds::Behaviour::is_object(K) == FALSE) && (Kinds::eq(K, K_understanding) == FALSE) && (Kinds::Behaviour::request_I6_GPR(K) == FALSE)) {Problems::quote_source(1, current_sentence);
-Problems::quote_wording(2, CGTokens::text(cgt));
-StandardProblems::handmade_problem(Task::syntax_tree(),
-_p_(PM_UnparsableKind));
+Problems::quote_wording(2, CGTokens::text(cgt));
+StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_UnparsableKind));Problems::issue_problem_segment(
-"The grammar token '%2' in the sentence %1 "
-"invites me to understand values typed by the player during "
-"play but for a kind of value which is beyond my ability. "
-"Generally speaking, the allowable kinds of value are "
-"number, time, text and any new kind of value you may "
-"have created - but not, for instance, scene or rule.");
+"The grammar token '%2' in the sentence %1 invites me to understand "
+"values typed by the player during play but for a kind of value which "
+"is beyond my ability. Generally speaking, the allowable kinds of value "
+"are number, time, text and any new kind of value you may have created - "
+"but not, for instance, scene or rule.");Problems::issue_problem_end();
-spec = NULL;
+result = Specifications::from_kind(K_object); } }
§13. Scoring. This score is needed when sorting CG lines in order of applicability: see the
+discussion at CGLines::cgl_determine. The function must return a value
+which is at least 0 but strictly less than CGL_SCORE_TOKEN_RANGE. The
+general idea is that higher scores cause tokens to take precedence over lower
+ones.
+
-typedefstructparsing_pp_data {
-intvisibility_level_in_parser; if so, does the run-time I6 parser recognise it?
-structwordingvisibility_condition; (at least if...?)
-structparse_node *visibility_sentence; where this is specified
-CLASS_DEFINITION
-} parsing_pp_data;
-
-
The structure parsing_pp_data is private to this section.
§5. Visible properties. 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".
-
-
-
Properly speaking it is not the property which is visible, but the
-combination of property and object (or kind): thus the following test
-depends on a property permission and not a mere property.
-
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.
-
-
-
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.
-
-
-
§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.
-
-
-
First, we need to look after a pointer to the CG used to hold the grammar
-being matched against the snippet of words.
-
§4. Parse name properties. One of the major services provided by I7, as compared with I6, is that it
-automatically compiles what would otherwise be laborious parse_name
-routines for its objects. This is messy, because the underlying I6 syntax
-is messy. The significant complication is that the I6 parser makes two
-quite different uses of parse_name: not just for parsing names, but
-also for determining whether two objects are visually distinguishable,
-something it needs to know in order to make plural objects work properly.
-
-
-
If an object has any actual grammar attached, say a collection of grammar
-lines belonging to GV3, we will compile the parse_name as an independent
-I6 routine with a name like Parse_Name_GV3. If not, a parse_name may
-still be needed, because of the distinguishability problem: if so then we
-will simply compile a parse_name routine inline, in the usual I6 way.
-
§5. The following routine produces one of three outcomes: either (i) the
-head of an I6 declaration of a free-standing routine to be used as a
-parse_name property, or (ii) the head of an I6 inline declaration of a
-parse_name property as a with clause for an Object directive, or
-
-
-
(iii) the empty output, in happy cases where neither parsing nor
-distinguishability need to be investigated. The routine returns a flag
-indicating if a tail need be compiled (i.e., in cases (i) or (ii) but not
-(iii)).
-
-
In cases (i) and (ii), the head is immediately followed by code which
-looks at the names of visible properties. Recall that a visible property
-is one which can be used to describe an object: for instance, if colour
-is a visible property of a car, then it can be called "green car" if
-and only if the current value of the colour of the car is "green", and
-so forth. In all such cases, we need to parse the text to look for the
-name of the current value.
-
-
-
But if a property can be used as part of the name, then it follows that
-two objects with the same grammar (and name words) cease to be
-indistinguishable when their values for this property differ. For instance,
-given two otherwise identical cars which can only be called "car", we
-can distinguish them with the names "red car" and "green car" if one
-is red and the other green. The parser needs to know this. It calls the
-parse_name routine with an I6 global called parser_action set to
-##TheSame in such a case, and we can return 0 to make no decision or
--2 to say that they are different.
-
-
-
Note that the parser checks this only if two or more objects share the same
-parse_name routine: which will in I7 happen only if they each inherit it
-from the I6 class of a common kind. Because parse_name is not additive in
-I6, this can only occur if the objects, and any intervening classes for
-intervening kinds, define no parse_name of their own.
-
-
-
We will test distinguishability only for kinds which have permissions for
-visible properties: kinds because no other parse_name values can ever
-be duplicated in instance objects, and visible properties because these
-are the only ways to tell apart instances which have no grammar of their
-own. (If either had grammar of its own, it would also have its own
-parse_name routine.) For all other kinds, we return a make-no-decision
-value in response to a ##TheSame request: this ensures that the I6
-parser looks at the name properties of the objects instead, and in
-the absence of either I7-level grammar lines or visible properties, that
-will be the correct decision.
-
§6. 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_names 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.
-
§7. The head and tail routines can only be understood by knowing that the
-following code is used to reset the grammar-line parser after each failure
-of a CGL to parse.
-
§8. The interesting point about the tail of the parse_name routine is that
-it ends on the ] "close routine" character, in mid-source line. This is
-because the routine may be being used inside an Object directive, and
-would therefore need to be followed by a comma, or in free-standing I6 code,
-in which case it would need to be followed by a semi-colon.
-
§9. 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.
-
§10. Common handling for distinguishing and parsing. The top-level considering routines parcel up work and hand it over to
-the distinguishing routines if phase is 1, and the parsing routines
-if phase is 2. Note that if there are no sometimes-visible-properties
-then the correct behaviour is to call none of the routines below this
-level, and to compile nothing to the file.
-
§11. 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.
-
§13. 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.
-
Filters are used to require nouns to have specific kinds or attributes, or to have specific scoping rules: they correspond to Inform 6's |noun=Routine| and |scope=Routine| tokens. Though these are quite different concepts in I6, their common handling seems natural in I7.
§3. Access via ID. For now, though, these are perhaps strangely accessed by ID number. (Because
-the parse_node structure can't conveniently be annotated with pointers,
-that's why.)
-
-
-
-inttoo_late_for_further_NFTs = FALSE;
-
-intUnderstandFilterTokens::new_id(parse_node *spec, intglobal_scope, intany_things) {
-if (too_late_for_further_NFTs)
-StandardProblems::sentence_problem(Task::syntax_tree(), _p_(BelievedImpossible),
-"complicated instructions on understanding the player's command "
-"are not allowed in the past tense",
-"for instance by being applied to several previous turns in a row.");
-
-kind *K = Specifications::to_kind(spec);
-if ((Kinds::Behaviour::is_object(K) == FALSE) && (Kinds::Behaviour::request_I6_GPR(K) == FALSE) && (global_scope))
-StandardProblems::sentence_problem(Task::syntax_tree(), _p_(BelievedImpossible),
-"this is a kind of value I can't understand in command grammar",
-"so the '[any ...]' part will have to go.");
-
-returnUnderstandFilterTokens::nft_new(spec, global_scope, any_things)->allocation_id;
-}
-
-voidUnderstandFilterTokens::compile_id(intid) {
-noun_filter_token *nft;
-LOOP_OVER(nft, noun_filter_token)
-if (nft->allocation_id == id) {
-if (nft->parse_using_gpr) Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_TT_HL));
-elseif (nft->global_scope_flag) Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(SCOPE_TT_HL));
-elseProduce::val_iname(Emit::tree(), K_value, Hierarchy::find(ROUTINEFILTER_TT_HL));
-Produce::val_iname(Emit::tree(), K_value, nft->nft_iname);
- }
-}
-
-voidUnderstandFilterTokens::emit_id(intid) {
-noun_filter_token *nft;
-LOOP_OVER(nft, noun_filter_token)
-if (nft->allocation_id == id) {
-inter_tiannot = 0;
-if (nft->parse_using_gpr == FALSE) {
-if (nft->global_scope_flag) annot = SCOPE_FILTER_IANN;
-elseannot = NOUN_FILTER_IANN;
- }
-inter_name *iname = UnderstandFilterTokens::nft_compile_routine_iname(nft);
-if (annot != 0)
-if (Produce::read_annotation(iname, annot) != 1)
-Produce::annotate_i(iname, annot, 1);
-Emit::array_iname_entry(iname);
- }
-}
-
-
§4. Compiling everything. Having referred to these filter routines, we need to compile them.
-
-
-
-
-
-
-
diff --git a/docs/if-module/5-pp.html b/docs/if-module/5-pp.html
index 9b32f5dfb..284de6f91 100644
--- a/docs/if-module/5-pp.html
+++ b/docs/if-module/5-pp.html
@@ -92,7 +92,7 @@ chapter.
PluginManager::plug(COMPARE_CONSTANT_PLUG, ParsingPlugin::compare_CONSTANT);PluginManager::plug(NEW_VARIABLE_NOTIFY_PLUG, ParsingPlugin::new_variable_notify);PluginManager::plug(NEW_SUBJECT_NOTIFY_PLUG, ParsingPlugin::new_subject_notify);
-PluginManager::plug(NEW_PERMISSION_NOTIFY_PLUG, Visibility::new_permission_notify);
+PluginManager::plug(NEW_PERMISSION_NOTIFY_PLUG, Visibility::new_permission_notify);PluginManager::plug(COMPLETE_MODEL_PLUG, ParsingPlugin::complete_model);}
@@ -107,14 +107,14 @@ for generating that is a little delicate.
BENCH(Understand::traverse); }if (stage == INTER2_CSEQ) {
-BENCH(UnderstandGeneralTokens::write_parse_name_routines);
+BENCH(UnderstandGeneralTokens::write_parse_name_routines);BENCH(RTCommandGrammarLines::MistakeActionSub_routine);BENCH(CommandGrammars::prepare);BENCH(RTCommandGrammars::compile_conditions);
-BENCH(UnderstandValueTokens::number);
-BENCH(UnderstandValueTokens::truth_state);
-BENCH(UnderstandValueTokens::time);
-BENCH(UnderstandValueTokens::compile_type_gprs);
+BENCH(UnderstandValueTokens::number);
+BENCH(UnderstandValueTokens::truth_state);
+BENCH(UnderstandValueTokens::time);
+BENCH(UnderstandValueTokens::compile_type_gprs);if (debugging) {BENCH(TestCommand::write_text);BENCH(TestCommand::TestScriptSub_routine);
@@ -123,11 +123,11 @@ for generating that is a little delicate.
} }if (stage == INTER3_CSEQ) {
-BENCH(UnderstandFilterTokens::compile);
+BENCH(UnderstandFilterTokens::compile); }if (stage == INTER4_CSEQ) {BENCH(RTCommandGrammars::compile_all);
-BENCH(UnderstandFilterTokens::compile);
+BENCH(UnderstandFilterTokens::compile); }returnFALSE;}
@@ -145,12 +145,18 @@ and in particular, to every object instance and every kind of object.
CLASS_DEFINITION} parsing_data;
+parsing_data *ParsingPlugin::new_data(inference_subject *subj) {
+parsing_data *pd = CREATE(parsing_data);
+pd->understand_as_this_object = NULL;
+returnpd;
+}
+
intParsingPlugin::new_subject_notify(inference_subject *subj) {
-ATTACH_PLUGIN_DATA_TO_SUBJECT(parsing, subj, Visibility::new_data(subj));
+ATTACH_PLUGIN_DATA_TO_SUBJECT(parsing, subj, ParsingPlugin::new_data(subj));returnFALSE;}
-
The structure parsing_data is accessed in 5/cg, 5/gp, 5/gpr.
+
The structure parsing_data is accessed in 5/cg and here.
§4. We make use of a new kind of rvalue in this plugin: K_understanding. This
is created in Familiar Kinds (in kinds), not here, but we do have to provide
the following functions to handle its constant rvalues. These correspond to
@@ -170,9 +176,9 @@ the following functions to handle its constant rvalues. These correspond to
returnFALSE;}
-parse_node *ParsingPlugin::rvalue_from_command_grammar(command_grammar *val) {
+parse_node *ParsingPlugin::rvalue_from_command_grammar(command_grammar *val) {CONV_FROM(command_grammar, K_understanding) }
-command_grammar *ParsingPlugin::rvalue_to_command_grammar(parse_node *spec) {
+command_grammar *ParsingPlugin::rvalue_to_command_grammar(parse_node *spec) {CONV_TO(command_grammar) }
§5. A number of global variables are given special treatment by this plugin,
@@ -206,7 +212,7 @@ the Inter command parser at runtime, whose data is typeless.
§7.
-intParsingPlugin::new_variable_notify(nonlocal_variable *var) {
+intParsingPlugin::new_variable_notify(nonlocal_variable *var) {if (<notable-parsing-variables>(var->name)) {switch (<<r>>) {case0:
@@ -233,7 +239,7 @@ and is in that sense (okay, ironically) "nameless".
property *P_name = NULL;
-property *ParsingPlugin::name_property(void) {
+property *ParsingPlugin::name_property(void) {if (P_name == NULL) {P_name = ValueProperties::new_nameless(I"name", K_text);Hierarchy::make_available(Emit::tree(), RTParsing::name_iname());
@@ -248,10 +254,10 @@ get the name pr
-intParsingPlugin::complete_model(intstage) {
+intParsingPlugin::complete_model(intstage) {if (stage == WORLD_STAGE_V) {instance *I;
-P_parse_name = ValueProperties::new_nameless(I"parse_name", K_value);
+property *P_parse_name = ValueProperties::new_nameless(I"parse_name", K_value);LOOP_OVER_INSTANCES(I, K_object) {inference_subject *subj = Instances::as_subject(I);
@@ -302,7 +308,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 = UnderstandGeneralTokens::compile_parse_name_property(subj);if (S)ValueProperties::assert(P_parse_name, subj,Rvalues::from_iname(S), CERTAIN_CE);
@@ -321,7 +327,7 @@ where grammar has specified a need. (By default, this will not happen.)
MAKE_ANNOTATION_FUNCTIONS(constant_command_grammar, command_grammar)
-voidParsingPlugin::nodes_and_annotations(void) {
+voidParsingPlugin::nodes_and_annotations(void) {Annotations::declare_type(constant_command_grammar_ANNOT,ParsingPlugin::write_constant_grammar_verb_ANNOT);
@@ -335,7 +341,7 @@ where grammar has specified a need. (By default, this will not happen.)
}
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.
§19.9.2. Reject this if it contains two consecutive commas19.9.2 =
-
-
-
-LOOP_THROUGH_WORDING(i, tokenised)
-if (i < Wordings::last_wn(tokenised))
-if ((compare_word(i, COMMA_V)) && (compare_word(i+1, COMMA_V))) {
-StandardProblems::sentence_problem(Task::syntax_tree(),
-_p_(PM_UnderstandCommaCommand),
-"'understand' as an action cannot involve a comma",
-"since a command leading to an action never does. "
-"(Although Inform understands commands like 'PETE, LOOK' "
-"only the part after the comma is read as an action command: "
-"the part before the comma is read as the name of someone, "
-"according to the usual rules for parsing a name.) "
-"Because of the way Inform processes text with square "
-"brackets, this problem message is also sometimes seen "
-"if empty square brackets are used, as in 'Understand "
-"\"bless []\" as blessing.'");
-return;
- }
-
diff --git a/docs/if-module/index.html b/docs/if-module/index.html
index 7c1c0dff0..3a3725fc7 100644
--- a/docs/if-module/index.html
+++ b/docs/if-module/index.html
@@ -306,24 +306,9 @@
Command grammars, their lines and their tokens may each "determine" up to two values, and here we provide a way to describe the range of those.
-
- Grammar Properties -
- A plugin for the I6 run-time properties needed to support parsing.
-
-
-
- Noun Filter Tokens -
- Filters are used to require nouns to have specific kinds or attributes, or to have specific scoping rules: they correspond to Inform 6's |noun=Routine| and |scope=Routine| tokens. Though these are quite different concepts in I6, their common handling seems natural in I7.
-
-
-
- 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/docs/runtime-module/2-cu.html b/docs/runtime-module/2-cu.html
index 0dec6b3fd..68de99156 100644
--- a/docs/runtime-module/2-cu.html
+++ b/docs/runtime-module/2-cu.html
@@ -182,7 +182,7 @@ but that's now easy, as we just have to read off the annotation made above &mdas
-compilation_unit *CompilationUnits::find(parse_node *from) {
+compilation_unit *CompilationUnits::find(parse_node *from) {if (from == NULL) returnNULL;returnNode::get_unit(from);}
diff --git a/docs/runtime-module/2-emt.html b/docs/runtime-module/2-emt.html
index 40dcf8381..33b004868 100644
--- a/docs/runtime-module/2-emt.html
+++ b/docs/runtime-module/2-emt.html
@@ -84,7 +84,7 @@ function togglePopup(material_id) {
inter_tree *I7_generation_tree = NULL;
-inter_tree *Emit::tree(void) {
+inter_tree *Emit::tree(void) {returnI7_generation_tree;}
@@ -512,7 +512,7 @@ insert them into the Inter stream close to the top.
returnsave;}
-voidEmit::array_iname_entry(inter_name *iname) {
+voidEmit::array_iname_entry(inter_name *iname) {if (current_A == NULL) internal_error("entry outside of inter array");inter_symbol *alias;if (iname == NULL) alias = Site::veneer_symbol(Emit::tree(), NOTHING_VSYMB);
@@ -667,7 +667,7 @@ insert them into the Inter stream close to the top.
*/}
-voidEmit::code_comment(text_stream *text) {
+voidEmit::code_comment(text_stream *text) { inter_ti ID = Inter::Warehouse::create_text(Inter::Tree::warehouse(Emit::tree()), Inter::Bookmarks::package(Packaging::at(Emit::tree())));Str::copy(Inter::Warehouse::get_text(Inter::Tree::warehouse(Emit::tree()), ID), text);Produce::guard(Inter::Comment::new(Produce::at(Emit::tree()), (inter_ti) Produce::level(Emit::tree()), NULL, ID));
@@ -802,7 +802,7 @@ insert them into the Inter stream close to the top.
returnPackaging::enclosure(Emit::tree());}
-packaging_stateEmit::unused_packaging_state(void) {
+packaging_stateEmit::unused_packaging_state(void) {returnPackaging::stateless();}
diff --git a/docs/runtime-module/2-hrr.html b/docs/runtime-module/2-hrr.html
index b027e795a..bf2b0aac9 100644
--- a/docs/runtime-module/2-hrr.html
+++ b/docs/runtime-module/2-hrr.html
@@ -1723,11 +1723,11 @@ function togglePopup(material_id) {
@@ -800,8 +800,8 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), LT_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
-Produce::val_symbol(Emit::tree(), K_value, gprk->cur_len_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->cur_len_s);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), GE_BIP);Produce::down(Emit::tree());
@@ -809,8 +809,8 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), LOOKUPBYTE_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->cur_addr_s);
-Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->cur_addr_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);Produce::up(Emit::tree());Produce::up(Emit::tree());Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 0);
@@ -820,11 +820,11 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), POSTINCREMENT_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), POSTINCREMENT_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->wpos_s);Produce::up(Emit::tree());Produce::up(Emit::tree());Produce::up(Emit::tree());
@@ -836,12 +836,12 @@ if we fail to make a match.
Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->tot_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->tot_s);Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 0);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 0);Produce::up(Emit::tree());
@@ -851,8 +851,8 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), LT_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
-Produce::val_symbol(Emit::tree(), K_value, gprk->cur_len_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->cur_len_s);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), GE_BIP);Produce::down(Emit::tree());
@@ -860,8 +860,8 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), LOOKUPBYTE_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->cur_addr_s);
-Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->cur_addr_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);Produce::up(Emit::tree());Produce::up(Emit::tree());Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 0);
@@ -871,25 +871,25 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);Produce::inv_call_iname(Emit::tree(), Hierarchy::find(DIGITTOVALUE_HL));Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), LOOKUPBYTE_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->cur_addr_s);
-Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->cur_addr_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);Produce::up(Emit::tree());Produce::up(Emit::tree());Produce::up(Emit::tree());
-Kinds::Scalings::compile_scale_and_add(gprk->tot_s, gprk->sgn_s, 10, 0, gprk->f_s, failed_label);
+Kinds::Scalings::compile_scale_and_add(gprk->tot_s, gprk->sgn_s, 10, 0, gprk->f_s, failed_label);Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 1);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), POSTINCREMENT_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->wpos_s);Produce::up(Emit::tree());Produce::up(Emit::tree());Produce::up(Emit::tree());
@@ -898,7 +898,7 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), EQ_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->f_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->f_s);Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 0);Produce::up(Emit::tree());Produce::code(Emit::tree());
@@ -915,7 +915,7 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), GE_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->tot_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->tot_s);Produce::val(Emit::tree(), K_number, LITERAL_IVAL, (inter_ti) lpe->element_range);Produce::up(Emit::tree());Produce::code(Emit::tree());
@@ -928,11 +928,11 @@ if we fail to make a match.
Produce::up(Emit::tree()); }
-Kinds::Scalings::compile_scale_and_add(gprk->tot_s, gprk->sgn_s, lpe->element_multiplier, 0, gprk->matched_number_s, failed_label);
+Kinds::Scalings::compile_scale_and_add(gprk->tot_s, gprk->sgn_s, lpe->element_multiplier, 0, gprk->matched_number_s, failed_label);Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->matched_number_s);
-Produce::val_symbol(Emit::tree(), K_value, gprk->tot_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->matched_number_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->tot_s);Produce::up(Emit::tree());intM = Kinds::Scalings::get_integer_multiplier(lp->scaling);
@@ -941,8 +941,8 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), EQ_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
-Produce::val_symbol(Emit::tree(), K_value, gprk->cur_len_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->cur_len_s);Produce::up(Emit::tree());Produce::code(Emit::tree());Produce::down(Emit::tree());
@@ -952,7 +952,7 @@ if we fail to make a match.
Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->cur_word_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->cur_word_s);Produce::inv_call_iname(Emit::tree(), Hierarchy::find(NEXTWORDSTOPPED_HL));Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);
@@ -968,7 +968,7 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), EQ_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->cur_word_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->cur_word_s);Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(THEN1__WD_HL));Produce::up(Emit::tree());Produce::code(Emit::tree());
@@ -984,18 +984,18 @@ if we fail to make a match.
Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->mid_word_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->mid_word_s);Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 0);Produce::up(Emit::tree());Compile I6 code to enter mid-word parsing if not already in it1.2.1;Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->x_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->x_s);Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 0);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);Produce::val(Emit::tree(), K_number, LITERAL_IVAL, (inter_ti) M);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), WHILE_BIP);
@@ -1004,7 +1004,7 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), GT_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->f_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->f_s);Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 1);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), AND_BIP);
@@ -1013,7 +1013,7 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), MODULO_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->f_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->f_s);Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 10);Produce::up(Emit::tree());Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 0);
@@ -1024,8 +1024,8 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), LOOKUPBYTE_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->cur_addr_s);
-Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->cur_addr_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);Produce::up(Emit::tree());Produce::up(Emit::tree());Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 0);
@@ -1036,7 +1036,7 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->w_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->w_s);Produce::inv_primitive(Emit::tree(), DIVIDE_BIP);Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), TIMES_BIP);
@@ -1045,27 +1045,27 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), LOOKUPBYTE_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->cur_addr_s);
-Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->cur_addr_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);Produce::up(Emit::tree());Produce::up(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->f_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->f_s);Produce::up(Emit::tree());Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 10);Produce::up(Emit::tree());Produce::up(Emit::tree());
-Kinds::Scalings::compile_scale_and_add(gprk->x_s, gprk->sgn_s,
-1, 0, gprk->w_s, failed_label);
+Kinds::Scalings::compile_scale_and_add(gprk->x_s, gprk->sgn_s,
+1, 0, gprk->w_s, failed_label);Produce::inv_primitive(Emit::tree(), POSTINCREMENT_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->wpos_s);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->f_s);Produce::inv_primitive(Emit::tree(), DIVIDE_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->f_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->f_s);Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 10);Produce::up(Emit::tree());Produce::up(Emit::tree());
@@ -1086,24 +1086,24 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), EQ_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->mid_word_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->mid_word_s);Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 0);Produce::up(Emit::tree());Produce::code(Emit::tree());Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->mid_word_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->mid_word_s);Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 1);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->wpos_s);Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 0);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->cur_addr_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->cur_addr_s);Produce::inv_call_iname(Emit::tree(), Hierarchy::find(WORDADDRESS_HL));Produce::down(Emit::tree());Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));
@@ -1111,7 +1111,7 @@ if we fail to make a match.
Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->cur_len_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->cur_len_s);Produce::inv_call_iname(Emit::tree(), Hierarchy::find(WORDLENGTH_HL));Produce::down(Emit::tree());Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));
@@ -1129,8 +1129,8 @@ if we fail to make a match.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), EQ_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
-Produce::val_symbol(Emit::tree(), K_value, gprk->cur_len_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->wpos_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->cur_len_s);Produce::up(Emit::tree());Produce::code(Emit::tree());Produce::down(Emit::tree());
@@ -1140,7 +1140,7 @@ if we fail to make a match.
Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->mid_word_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->mid_word_s);Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 0);Produce::up(Emit::tree());Produce::up(Emit::tree());
@@ -1150,7 +1150,7 @@ if we fail to make a match.
§2. Printing the I6 variable |value| out in an LP's notation at run-time.
-voidRoutines::end(packaging_statesave) {
+voidRoutines::end(packaging_statesave) {kind *R_kind = LocalVariables::deduced_function_kind(currently_compiling_in_frame);inter_name *kernel_name = NULL, *public_name = currently_compiling_iname;
diff --git a/docs/runtime-module/4-ts2.html b/docs/runtime-module/4-ts2.html
index 2973d7e30..e6aefccba 100644
--- a/docs/runtime-module/4-ts2.html
+++ b/docs/runtime-module/4-ts2.html
@@ -92,7 +92,7 @@ stipulations on place and possessions attached.
CLASS_DEFINITION} test_scenario;
-
The structure test_scenario is accessed in 4/rsp, 4/uoart, 4/vrb, 4/prp, 5/sc and here.
+
The structure test_scenario is accessed in 4/rsp, 4/uoart, 4/vrb, 4/prp, 5/sc, 5/gpr and here.
§2.
diff --git a/docs/runtime-module/5-act.html b/docs/runtime-module/5-act.html
index fb5c90969..a53b18468 100644
--- a/docs/runtime-module/5-act.html
+++ b/docs/runtime-module/5-act.html
@@ -502,7 +502,7 @@ infrastructure, and we access it with a single call.
}
diff --git a/docs/runtime-module/5-ap.html b/docs/runtime-module/5-ap.html
index 7a85a2cfa..8b6521198 100644
--- a/docs/runtime-module/5-ap.html
+++ b/docs/runtime-module/5-ap.html
@@ -911,7 +911,7 @@ and in this case we therefore ignore
diff --git a/docs/runtime-module/5-bd.html b/docs/runtime-module/5-bd.html
index e5dafa601..26cdec9d6 100644
--- a/docs/runtime-module/5-bd.html
+++ b/docs/runtime-module/5-bd.html
@@ -211,7 +211,7 @@ around it, in byte-accessible memory.
}
diff --git a/docs/runtime-module/5-cg.html b/docs/runtime-module/5-cg.html
index 3afacf117..ef621bbd4 100644
--- a/docs/runtime-module/5-cg.html
+++ b/docs/runtime-module/5-cg.html
@@ -122,7 +122,7 @@ function togglePopup(material_id) {
global_compilation_settings.no_verb_verb_exists = TRUE;}
-
The structure cg_compilation_data is private to this section.
+
The structure cg_compilation_data is accessed in 5/gpr 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
@@ -161,6 +161,22 @@ in the final I6 output.
inter_name *VERB_DIRECTIVE_TOPIC_iname = NULL;inter_name *VERB_DIRECTIVE_MULTIEXCEPT_iname = NULL;
+inter_name *RTCommandGrammars::iname_for_I6_parser_token(cg_token *cgt) {
+switch (cgt->grammar_token_code) {
+caseNOUN_TOKEN_GTC:returnVERB_DIRECTIVE_NOUN_iname;
+caseMULTI_TOKEN_GTC:returnVERB_DIRECTIVE_MULTI_iname;
+caseMULTIINSIDE_TOKEN_GTC:returnVERB_DIRECTIVE_MULTIINSIDE_iname;
+caseMULTIHELD_TOKEN_GTC:returnVERB_DIRECTIVE_MULTIHELD_iname;
+caseHELD_TOKEN_GTC:returnVERB_DIRECTIVE_HELD_iname;
+caseCREATURE_TOKEN_GTC:returnVERB_DIRECTIVE_CREATURE_iname;
+caseTOPIC_TOKEN_GTC:returnVERB_DIRECTIVE_TOPIC_iname;
+caseMULTIEXCEPT_TOKEN_GTC:returnVERB_DIRECTIVE_MULTIEXCEPT_iname;
+default:internal_error("tried to find inter name for invalid GTC");
+ }
+returnNULL; to prevent a gcc error: never reached
+}
+
+
inter_name *RTCommandGrammars::grammar_constant(intN, intV) {inter_name *iname = Hierarchy::find(N);Emit::named_numeric_constant(iname, 1);
@@ -233,7 +249,7 @@ by exploring each CG in turn.
-packaging_stateRTCommandGrammars::cg_compile_Verb_directive_header(command_grammar *cg, inter_name *array_iname) {
+packaging_stateRTCommandGrammars::cg_compile_Verb_directive_header(command_grammar *cg, inter_name *array_iname) {if (cg->cg_is != CG_IS_COMMAND)internal_error("tried to compile Verb from non-command CG");if (CGLines::list_length(cg) == 0)
@@ -267,7 +283,7 @@ specified for all things. (This mimics I6 class-to-instance inheritance.)
-voidRTCommandGrammars::cg_compile_lines(gpr_kit *gprk, command_grammar *cg) {
+voidRTCommandGrammars::cg_compile_lines(gpr_kit *gprk, command_grammar *cg) {CommandsIndex::list_assert_ownership(cg); Mark for later indexingCommandGrammars::sort_command_grammar(cg); Phase III for the CGLs in the CG happens hereRTCommandGrammarLines::sorted_line_list_compile(gprk,
@@ -313,7 +329,7 @@ next priority, and so on up the hierarchy.
-voidRTCommandGrammars::compile(command_grammar *cg) {
+voidRTCommandGrammars::compile(command_grammar *cg) {if (CGLines::list_length(cg) == 0) return;LOGIF(GRAMMAR, "Compiling command grammar $G\n", cg);
@@ -331,19 +347,19 @@ next priority, and so on up the hierarchy.
break; }caseCG_IS_TOKEN: {
-gpr_kitgprk = UnderstandValueTokens::new_kit();
+gpr_kitgprk = UnderstandValueTokens::new_kit();if (cg->compilation_data.cg_token_iname == NULL) internal_error("cg token not ready");packaging_statesave = Routines::begin(cg->compilation_data.cg_token_iname);
-UnderstandValueTokens::add_original(&gprk);
-UnderstandValueTokens::add_standard_set(&gprk);
+UnderstandValueTokens::add_original(&gprk);
+UnderstandValueTokens::add_standard_set(&gprk);Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk.original_wn_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk.original_wn_s);Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk.rv_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk.rv_s);Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_PREPOSITION_HL));Produce::up(Emit::tree());RTCommandGrammars::cg_compile_lines(&gprk, cg);
@@ -355,25 +371,25 @@ next priority, and so on up the hierarchy.
break; }caseCG_IS_CONSULT: {
-gpr_kitgprk = UnderstandValueTokens::new_kit();
-inter_name *iname = UnderstandGeneralTokens::consult_iname(cg);
+gpr_kitgprk = UnderstandValueTokens::new_kit();
+inter_name *iname = UnderstandGeneralTokens::consult_iname(cg);packaging_statesave = Routines::begin(iname);
-UnderstandValueTokens::add_range_calls(&gprk);
-UnderstandValueTokens::add_original(&gprk);
-UnderstandValueTokens::add_standard_set(&gprk);
+UnderstandValueTokens::add_range_calls(&gprk);
+UnderstandValueTokens::add_original(&gprk);
+UnderstandValueTokens::add_standard_set(&gprk);Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());Produce::ref_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));
-Produce::val_symbol(Emit::tree(), K_value, gprk.range_from_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk.range_from_s);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk.original_wn_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk.original_wn_s);Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk.rv_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk.rv_s);Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_PREPOSITION_HL));Produce::up(Emit::tree());RTCommandGrammars::cg_compile_lines(&gprk, cg);
@@ -385,11 +401,11 @@ next priority, and so on up the hierarchy.
break; }caseCG_IS_SUBJECT: {
-gpr_kitgprk = UnderstandValueTokens::new_kit();
+gpr_kitgprk = UnderstandValueTokens::new_kit();packaging_statesave = Emit::unused_packaging_state();
-if (UnderstandGeneralTokens::compile_parse_name_head(&save, &gprk, cg->subj_understood, cg, NULL)) {
+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);
+UnderstandGeneralTokens::compile_parse_name_tail(&gprk);Routines::end(save); }break;
@@ -398,19 +414,19 @@ next priority, and so on up the hierarchy.
internal_error("iv");break;caseCG_IS_PROPERTY_NAME: {
-gpr_kitgprk = UnderstandValueTokens::new_kit();
+gpr_kitgprk = UnderstandValueTokens::new_kit();if (cg->compilation_data.cg_prn_iname == NULL) internal_error("PRN PN not ready");packaging_statesave = Routines::begin(cg->compilation_data.cg_prn_iname);
-UnderstandValueTokens::add_original(&gprk);
-UnderstandValueTokens::add_standard_set(&gprk);
+UnderstandValueTokens::add_original(&gprk);
+UnderstandValueTokens::add_standard_set(&gprk);Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk.original_wn_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk.original_wn_s);Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk.rv_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk.rv_s);Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_PREPOSITION_HL));Produce::up(Emit::tree());RTCommandGrammars::cg_compile_lines(&gprk, cg);
@@ -424,7 +440,7 @@ next priority, and so on up the hierarchy.
}}
-voidRTCommandGrammars::compile_iv(gpr_kit *gprk, command_grammar *cg) {
+voidRTCommandGrammars::compile_iv(gpr_kit *gprk, command_grammar *cg) {if (CGLines::list_length(cg) > 0) {LOGIF(GRAMMAR, "Compiling command grammar $G\n", cg);current_sentence = cg->where_cg_created;
@@ -434,12 +450,12 @@ next priority, and so on up the hierarchy.
}}
-voidRTCommandGrammars::emit_determination_type(determination_type *gty) {
+voidRTCommandGrammars::emit_determination_type(determination_type *gty) {Specifications::Compiler::emit_as_val(K_value, gty->term[0].what);}
diff --git a/docs/runtime-module/5-cgl.html b/docs/runtime-module/5-cgl.html
index bd63a548c..087e4a02d 100644
--- a/docs/runtime-module/5-cgl.html
+++ b/docs/runtime-module/5-cgl.html
@@ -169,7 +169,7 @@ the mistake.
inter_name *MistakeAction_iname = NULL;
-intRTCommandGrammarLines::cgl_compile_result_of_mistake(gpr_kit *gprk, cg_line *cgl) {
+intRTCommandGrammarLines::cgl_compile_result_of_mistake(gpr_kit *gprk, cg_line *cgl) {if (cgl->mistaken) {if (MistakeAction_iname == NULL) internal_error("no MistakeAction yet");Emit::array_iname_entry(VERB_DIRECTIVE_RESULT_iname);
@@ -280,7 +280,7 @@ the mistake.
}}
-voidRTCommandGrammarLines::cgl_compile_extra_token_for_condition(gpr_kit *gprk, cg_line *cgl,
+voidRTCommandGrammarLines::cgl_compile_extra_token_for_condition(gpr_kit *gprk, cg_line *cgl,intcg_is, inter_symbol *current_label) {if (CGLines::conditional(cgl)) {if (cgl->compilation_data.cond_token_iname == NULL) internal_error("CGL cond token not ready");
@@ -322,7 +322,7 @@ of the name pro
-voidRTCommandGrammarLines::sorted_line_list_compile(gpr_kit *gprk,
+voidRTCommandGrammarLines::sorted_line_list_compile(gpr_kit *gprk,intcg_is, command_grammar *cg, intgenuinely_verbal) {LOG_INDENT;LOOP_THROUGH_SORTED_CG_LINES(cgl, cg)
@@ -355,7 +355,7 @@ command CGs) have not yet been type-checked, whereas all others have.
-voidRTCommandGrammarLines::compile_cg_line(gpr_kit *gprk, cg_line *cgl, intcg_is, command_grammar *cg,
+voidRTCommandGrammarLines::compile_cg_line(gpr_kit *gprk, cg_line *cgl, intcg_is, command_grammar *cg,intgenuinely_verbal) {inti;inttoken_values;
@@ -415,7 +415,7 @@ command CGs) have not yet been type-checked, whereas all others have.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), EQ_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->instance_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->instance_s);RTCommandGrammars::emit_determination_type(&(cgl->cgl_type));Produce::up(Emit::tree());Produce::code(Emit::tree());
@@ -453,18 +453,18 @@ command CGs) have not yet been type-checked, whereas all others have.
caseCG_IS_TOKEN:Produce::inv_primitive(Emit::tree(), RETURN_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->rv_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->rv_s);Produce::up(Emit::tree());Produce::place_label(Emit::tree(), fail_label);Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->rv_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->rv_s);Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_PREPOSITION_HL));Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());Produce::ref_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));
-Produce::val_symbol(Emit::tree(), K_value, gprk->original_wn_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->original_wn_s);Produce::up(Emit::tree());break;caseCG_IS_CONSULT:
@@ -474,7 +474,7 @@ command CGs) have not yet been type-checked, whereas all others have.
Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), EQ_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->range_words_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->range_words_s);Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 0);Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), EQ_BIP);
@@ -482,16 +482,16 @@ command CGs) have not yet been type-checked, whereas all others have.
Produce::inv_primitive(Emit::tree(), MINUS_BIP);Produce::down(Emit::tree());Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));
-Produce::val_symbol(Emit::tree(), K_value, gprk->range_from_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->range_from_s);Produce::up(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->range_words_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->range_words_s);Produce::up(Emit::tree());Produce::up(Emit::tree());Produce::code(Emit::tree());Produce::down(Emit::tree());Produce::inv_primitive(Emit::tree(), RETURN_BIP);Produce::down(Emit::tree());
-Produce::val_symbol(Emit::tree(), K_value, gprk->rv_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->rv_s);Produce::up(Emit::tree());Produce::up(Emit::tree());Produce::up(Emit::tree());
@@ -499,17 +499,17 @@ command CGs) have not yet been type-checked, whereas all others have.
Produce::place_label(Emit::tree(), fail_label);Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->rv_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->rv_s);Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_PREPOSITION_HL));Produce::up(Emit::tree());Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());Produce::ref_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));
-Produce::val_symbol(Emit::tree(), K_value, gprk->original_wn_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->original_wn_s);Produce::up(Emit::tree());break;caseCG_IS_SUBJECT:
-UnderstandGeneralTokens::after_gl_failed(gprk, fail_label, cgl->pluralised);
+UnderstandGeneralTokens::after_gl_failed(gprk, fail_label, cgl->pluralised);break;caseCG_IS_VALUE:Produce::inv_primitive(Emit::tree(), STORE_BIP);
@@ -525,7 +525,7 @@ command CGs) have not yet been type-checked, whereas all others have.
Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());Produce::ref_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));
-Produce::val_symbol(Emit::tree(), K_value, gprk->original_wn_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->original_wn_s);Produce::up(Emit::tree());break; }
@@ -552,7 +552,7 @@ command CGs) have not yet been type-checked, whereas all others have.
§7.
-voidRTCommandGrammarLines::compile_token_line(gpr_kit *gprk, intcode_mode, cg_token *cgt, cg_token *cgt_to, intcg_is, intconsult_mode,
+voidRTCommandGrammarLines::compile_token_line(gpr_kit *gprk, intcode_mode, cg_token *cgt, cg_token *cgt_to, intcg_is, intconsult_mode,int *token_values, kind **token_value_kinds, inter_symbol *group_wn_s, inter_symbol *fail_label) {intlexeme_equivalence_class = 0;intalternative_number = 0;
@@ -563,7 +563,7 @@ command CGs) have not yet been type-checked, whereas all others have.
LOG_INDENT;for (; cgt; cgt = cgt->next_token) {LOGIF(GRAMMAR_CONSTRUCTION, "Compiling token $c\n", cgt);
-if ((cgt->grammar_token_code == TOPIC_TOKEN_GTC) && (cgt->next_token) &&
+if ((CGTokens::is_topic(cgt)) && (cgt->next_token) && (CGTokens::is_literal(cgt->next_token) == FALSE)) {StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_TextFollowedBy),"a '[text]' token must either match the end of some text, or "
@@ -602,8 +602,6 @@ command CGs) have not yet been type-checked, whereas all others have.
alternative_number = 1; }
-if (empty_text_allowed_in_lexeme) LOG("empty_text_allowed_in_lexeme!\n");
-
inter_symbol *jump_on_fail = fail_label;if (lexeme_equivalence_class > 0) {
@@ -611,7 +609,7 @@ command CGs) have not yet been type-checked, whereas all others have.
if (first_token_in_lexeme) {Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());
-Produce::ref_symbol(Emit::tree(), K_value, gprk->group_wn_s);
+Produce::ref_symbol(Emit::tree(), K_value, gprk->group_wn_s);Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));Produce::up(Emit::tree()); }
@@ -624,7 +622,7 @@ command CGs) have not yet been type-checked, whereas all others have.
Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());Produce::ref_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));
-Produce::val_symbol(Emit::tree(), K_value, gprk->group_wn_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->group_wn_s);Produce::up(Emit::tree());if ((last_token_in_lexeme == FALSE) || (empty_text_allowed_in_lexeme)) {
@@ -671,7 +669,7 @@ command CGs) have not yet been type-checked, whereas all others have.
Produce::inv_primitive(Emit::tree(), STORE_BIP);Produce::down(Emit::tree());Produce::ref_iname(Emit::tree(), K_value, Hierarchy::find(WN_HL));
-Produce::val_symbol(Emit::tree(), K_value, gprk->group_wn_s);
+Produce::val_symbol(Emit::tree(), K_value, gprk->group_wn_s);Produce::up(Emit::tree()); }if (eog_reserved_label) Produce::place_label(Emit::tree(), eog_reserved_label);
@@ -712,11 +710,11 @@ command CGs) have not yet been type-checked, whereas all others have.
slash_gpr *sgpr;LOOP_OVER(sgpr, slash_gpr) {packaging_statesave = Routines::begin(sgpr->sgpr_iname);
-gpr_kitgprk = UnderstandValueTokens::new_kit();
-UnderstandValueTokens::add_original(&gprk);
-UnderstandValueTokens::add_standard_set(&gprk);
+gpr_kitgprk = UnderstandValueTokens::new_kit();
+UnderstandValueTokens::add_original(&gprk);
+UnderstandValueTokens::add_standard_set(&gprk);
-RTCommandGrammarLines::compile_token_line(&gprk, TRUE, sgpr->first_choice, sgpr->last_choice, CG_IS_TOKEN, FALSE, NULL, NULL, gprk.group_wn_s, NULL);
+RTCommandGrammarLines::compile_token_line(&gprk, TRUE, sgpr->first_choice, sgpr->last_choice, CG_IS_TOKEN, FALSE, NULL, NULL, gprk.group_wn_s, NULL);Produce::inv_primitive(Emit::tree(), RETURN_BIP);Produce::down(Emit::tree());Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_PREPOSITION_HL));
@@ -758,7 +756,7 @@ nothing else.
diff --git a/docs/runtime-module/5-scn.html b/docs/runtime-module/5-scn.html
index 5fbe2a4f8..c4f25ea57 100644
--- a/docs/runtime-module/5-scn.html
+++ b/docs/runtime-module/5-scn.html
@@ -782,7 +782,7 @@ actually running:
}
diff --git a/docs/runtime-module/5-se.html b/docs/runtime-module/5-se.html
index f592d4ec8..d7648a762 100644
--- a/docs/runtime-module/5-se.html
+++ b/docs/runtime-module/5-se.html
@@ -77,7 +77,7 @@
}
diff --git a/docs/runtime-module/5-spt.html b/docs/runtime-module/5-spt.html
index ff12092dd..7f34edac4 100644
--- a/docs/runtime-module/5-spt.html
+++ b/docs/runtime-module/5-spt.html
@@ -142,7 +142,7 @@ be compiled, so this code is never used.
}
diff --git a/docs/runtime-module/5-tm.html b/docs/runtime-module/5-tm.html
index 432933285..8a8d00779 100644
--- a/docs/runtime-module/5-tm.html
+++ b/docs/runtime-module/5-tm.html
@@ -341,7 +341,7 @@ identifier names for instance have not yet been settled.
}
diff --git a/docs/runtime-module/5-tp.html b/docs/runtime-module/5-tp.html
index 6df8405eb..06c5da6b6 100644
--- a/docs/runtime-module/5-tp.html
+++ b/docs/runtime-module/5-tp.html
@@ -114,7 +114,7 @@ the function ChangePlayer}
diff --git a/docs/runtime-module/5-ts.html b/docs/runtime-module/5-ts.html
index 2a45def9d..ed7ee5f69 100644
--- a/docs/runtime-module/5-ts.html
+++ b/docs/runtime-module/5-ts.html
@@ -88,7 +88,7 @@
}
diff --git a/docs/runtime-module/index.html b/docs/runtime-module/index.html
index 41277e32e..df1c3bf53 100644
--- a/docs/runtime-module/index.html
+++ b/docs/runtime-module/index.html
@@ -404,6 +404,21 @@
Command Grammar Lines -
Runtime support for CGLs.
+
+
+ Noun Filter Tokens -
+ Filters are used to require nouns to have specific kinds or attributes, or to have specific scoping rules: they correspond to Inform 6's |noun=Routine| and |scope=Routine| tokens. Though these are quite different concepts in I6, their common handling seems natural in I7.
+
+
+
+ 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 cca834ec5..c91ae4a79 100644
--- a/inform7/Figures/memory-diagnostics.txt
+++ b/inform7/Figures/memory-diagnostics.txt
@@ -1,10 +1,10 @@
Total memory consumption was 259375K = 253 MB
-62.6% was used for 1338636 objects, in 278659 frames in 203 x 800K = 162400K = 158 MB:
+62.6% was used for 1338639 objects, in 278662 frames in 203 x 800K = 162400K = 158 MB:
9.7% inter_tree_node_array 36 x 8192 = 294912 objects, 25953408 bytes
5.5% text_stream_array 2595 x 100 = 259500 objects, 14615040 bytes
- 3.8% parse_node 129403 objects, 10352240 bytes
+ 3.8% parse_node 129406 objects, 10352480 bytes
2.7% verb_conjugation 160 objects, 7425280 bytes
2.5% parse_node_annotation_array 429 x 500 = 214500 objects, 6877728 bytes
2.4% linked_list 11793 objects, 6604080 bytes
@@ -64,12 +64,12 @@ Total memory consumption was 259375K = 253 MB
---- pcalc_func_array 1 x 1000 objects, 56032 bytes
---- ph_stack_frame_box 577 objects, 55392 bytes
---- kind_constructor 77 objects, 54824 bytes
+ ---- cg_token 603 objects, 53064 bytes
---- property_inference_data 1315 objects, 52600 bytes
---- ap_clause_array 2 x 400 = 800 objects, 51264 bytes
---- text_substitution 436 objects, 48832 bytes
---- cg_line 230 objects, 47840 bytes
---- table 7 objects, 45528 bytes
- ---- cg_token 603 objects, 43416 bytes
---- inter_node_list 750 objects, 42000 bytes
---- activity_list_array 1 x 1000 objects, 40032 bytes
---- anl_clause_array 1 x 1000 objects, 40032 bytes
@@ -232,7 +232,7 @@ Total memory consumption was 259375K = 253 MB
37.3% was used for memory not allocated for objects:
- 15.9% text stream storage 42247756 bytes in 265816 claims
+ 15.9% text stream storage 42247456 bytes in 265816 claims
3.4% dictionary storage 9278976 bytes in 16372 claims
---- sorting 1056 bytes in 3 claims
2.7% source text 7200000 bytes in 3 claims
@@ -248,5 +248,5 @@ Total memory consumption was 259375K = 253 MB
---- emitter array storage 12320 bytes in 8 claims
---- code generation workspace for objects 9200 bytes in 9 claims
-20.3% was overhead - 53951768 bytes = 52687K = 51 MB
+20.3% was overhead - 53941880 bytes = 52677K = 51 MB
diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt
index beb7d20f0..36f1f7987 100644
--- a/inform7/Figures/timings-diagnostics.txt
+++ b/inform7/Figures/timings-diagnostics.txt
@@ -1,36 +1,37 @@
100.0% in inform7 run
- 67.1% in compilation to Inter
- 25.6% in //Phrases::Manager::compile_first_block//
- 8.7% in //Phrases::Manager::compile_as_needed//
+ 66.7% in compilation to Inter
+ 25.8% in //Phrases::Manager::compile_first_block//
+ 8.4% in //Phrases::Manager::compile_as_needed//
6.8% in //Strings::compile_responses//
- 6.3% in //InferenceSubjects::emit_all//
- 4.2% in //MajorNodes::pre_pass//
- 3.3% in //MajorNodes::pass_1//
- 2.0% in //Phrases::Manager::RulePrintingRule_routine//
- 1.8% in //Phrases::Manager::rulebooks_array//
- 0.9% in //RTVerbs::ConjugateVerb//
+ 6.1% in //InferenceSubjects::emit_all//
+ 4.1% in //MajorNodes::pre_pass//
+ 3.2% in //MajorNodes::pass_1//
+ 1.9% in //Phrases::Manager::RulePrintingRule_routine//
+ 1.9% in //Phrases::Manager::rulebooks_array//
+ 1.0% in //RTVerbs::ConjugateVerb//
0.7% in //Phrases::Manager::traverse//
+ 0.5% in //Phrases::Manager::compile_rulebooks//
0.5% in //World::stage_V//
0.3% in //MajorNodes::pass_2//
- 0.3% in //Phrases::Manager::compile_rulebooks//
0.3% in //Phrases::Manager::parse_rule_parameters//
0.3% in //RTRelations::compile_defined_relations//
0.1% in //RTCommandGrammars::compile_all//
0.1% in //RTKinds::compile_data_type_support_routines//
0.1% in //Task::make_built_in_kind_constructors//
0.1% in //World::stages_II_and_III//
- 3.7% not specifically accounted for
- 30.4% in running Inter pipeline
- 10.0% in step preparation
- 9.6% in inter step 2/12: link
- 7.2% in inter step 12/12: generate inform6 -> auto.inf
+ 3.4% not specifically accounted for
+ 30.8% in running Inter pipeline
+ 10.1% in step preparation
+ 9.9% in inter step 2/12: link
+ 7.0% in inter step 12/12: generate inform6 -> auto.inf
0.3% in inter step 9/12: make-identifiers-unique
0.1% in inter step 10/12: reconcile-verbs
0.1% in inter step 11/12: eliminate-redundant-labels
+ 0.1% in inter step 4/12: parse-linked-matter
0.1% in inter step 5/12: resolve-conditional-compilation
0.1% in inter step 6/12: assimilate
0.1% in inter step 7/12: resolve-external-symbols
0.1% in inter step 8/12: inspect-plugs
2.1% not specifically accounted for
- 2.0% in supervisor
+ 1.9% in supervisor
0.4% not specifically accounted for
diff --git a/inform7/Tests/Groups/commands.testgroup b/inform7/Tests/Groups/commands.testgroup
index e5f8b0307..5556d54f3 100644
--- a/inform7/Tests/Groups/commands.testgroup
+++ b/inform7/Tests/Groups/commands.testgroup
@@ -1,3 +1,4 @@
+AwkwardParseNames
InstanceParsing
SilentMistake
SlashDashDash
diff --git a/inform7/Tests/Test Problems/PM_GrammarObjectlessRelation.txt b/inform7/Tests/Test Problems/PM_GrammarObjectlessRelation.txt
index 29fc9549e..e6f760a80 100644
--- a/inform7/Tests/Test Problems/PM_GrammarObjectlessRelation.txt
+++ b/inform7/Tests/Test Problems/PM_GrammarObjectlessRelation.txt
@@ -1,3 +1,3 @@
Xanadu is a room.
-Understand "box of [something related by containment]" as 10.
+Understand "box of [something related by containment]" as "[fish]".
diff --git a/inform7/Tests/Test Problems/_Results_Ideal/PM_GrammarObjectlessRelation.txt b/inform7/Tests/Test Problems/_Results_Ideal/PM_GrammarObjectlessRelation.txt
index bcc6d0cf5..26028ade2 100644
--- a/inform7/Tests/Test Problems/_Results_Ideal/PM_GrammarObjectlessRelation.txt
+++ b/inform7/Tests/Test Problems/_Results_Ideal/PM_GrammarObjectlessRelation.txt
@@ -1,10 +1,11 @@
-Inform 7.10.1 build 6N67 has started.
+Inform 7 v10.1.0 has started.
I've now read your source text, which is 13 words long.
-I've also read Standard Rules by Graham Nelson, which is 43240 words long.
+I've also read Basic Inform by Graham Nelson, which is 7687 words long.
I've also read English Language by Graham Nelson, which is 2328 words long.
+I've also read Standard Rules by Graham Nelson, which is 32067 words long.
Problem__ PM_GrammarObjectlessRelation
- >--> You wrote 'Understand "box of [something related by containment]" as 10'
- (source text, line 3): but a grammar token in an 'Understand...' can only
- be based on a relation if it is to understand the name of a room or thing,
- since otherwise there is nothing for the relation to be with.
-Inform 7 has finished: 146 centiseconds used.
+ >--> You wrote 'Understand "box of [something related by containment]" as
+ "[fish]"' (source text, line 3): but a grammar token in an 'Understand...'
+ can only be based on a relation if it is to understand the name of a room
+ or thing, since otherwise there is nothing for the relation to be with.
+Inform 7 has finished.
diff --git a/inform7/if-module/Chapter 5/Command Grammar Lines.w b/inform7/if-module/Chapter 5/Command Grammar Lines.w
index 08465b4e9..923879982 100644
--- a/inform7/if-module/Chapter 5/Command Grammar Lines.w
+++ b/inform7/if-module/Chapter 5/Command Grammar Lines.w
@@ -312,7 +312,8 @@ definition no effect, and disappears without trace in this process.
cg_token *class_start = NULL;
LOOP_THROUGH_CG_TOKENS(cgt, cgl) {
if ((cgt->next_token) && (Wordings::length(CGTokens::text(cgt->next_token)) == 1) &&
- (Lexer::word(Wordings::first_wn(CGTokens::text(cgt->next_token))) == FORWARDSLASH_V)) {
+ (Lexer::word(Wordings::first_wn(CGTokens::text(cgt->next_token))) ==
+ FORWARDSLASH_V)) {
if (cgt->slash_class == 0) {
class_start = cgt; alternatives_group++; /* start new equiv class */
class_start->slash_dash_dash = FALSE;
@@ -322,11 +323,12 @@ definition no effect, and disappears without trace in this process.
cgt->next_token->next_token->slash_class = alternatives_group;
if ((cgt->next_token->next_token) &&
(Wordings::length(CGTokens::text(cgt->next_token->next_token)) == 1) &&
- (Lexer::word(Wordings::first_wn(CGTokens::text(cgt->next_token->next_token))) == DOUBLEDASH_V)) {
+ (Lexer::word(Wordings::first_wn(CGTokens::text(cgt->next_token->next_token))) ==
+ DOUBLEDASH_V)) {
class_start->slash_dash_dash = TRUE;
- cgt->next_token = cgt->next_token->next_token->next_token; /* excise slash and dash-dash */
+ cgt->next_token = cgt->next_token->next_token->next_token; /* excise both */
} else {
- cgt->next_token = cgt->next_token->next_token; /* excise the slash from the token list */
+ cgt->next_token = cgt->next_token->next_token; /* excise slash */
}
}
}
@@ -417,9 +419,9 @@ void CGLines::cgl_determine(cg_line *cgl, command_grammar *cg, int depth) {
}
@ The general sort bonus is $Rs_0 + s_1$, where $R$ is the |CGL_SCORE_TOKEN_RANGE|
-and $s_0$, $s_1$ are the scores for the first and second tokens describing values;
-or if none of the $n$ tokens describes a value, it is $R^2n$, which is guaranteed
-to be larger.
+and $s_0$, $s_1$ are the scores for the first and second tokens describing values,
+which are such that $0\leq s_i =
int nulls_count = 0, pos = 0;
- for (cg_token *cgtt = first; cgtt; cgtt = cgtt->next_token) {
- int score = 0;
- parse_node *spec = CGTokens::determine(cgtt, depth, &score);
+ for (cg_token *cgt = first; cgt; cgt = cgt->next_token) {
+ parse_node *spec = CGTokens::determine(cgt, depth);
+ int score = CGTokens::score_bonus(cgt);
+ if ((score < 0) || (score >= CGL_SCORE_TOKEN_RANGE))
+ internal_error("token score out of range");
LOGIF(GRAMMAR_CONSTRUCTION, "token %d/%d: <%W> --> $P (score %d)\n",
- pos+1, line_length, CGTokens::text(cgtt), spec, score);
+ pos+1, line_length, CGTokens::text(cgt), spec, score);
if (spec) {
@;
int score_multiplier = 1;
if (DeterminationTypes::get_no_values_described(&(cgl->cgl_type)) == 0)
score_multiplier = CGL_SCORE_TOKEN_RANGE;
DeterminationTypes::add_term(&(cgl->cgl_type), spec,
- CGTokens::is_multiple(cgtt));
+ CGTokens::is_multiple(cgt));
cgl->general_sort_bonus += score*score_multiplier;
} else nulls_count++;
- if (CGTokens::is_multiple(cgtt)) multiples++;
+ if (CGTokens::is_multiple(cgt)) multiples++;
pos++;
}
if (nulls_count == line_length)
@@ -479,7 +484,6 @@ which parses to a |K_understanding| match.
cgl->understanding_sort_bonus += usb_contribution;
}
-
@h Sorting the lines in a grammar.
The CGLs in a grammar are insertion sorted into a sorted version. This is not
the controversial part: //CGLines::cg_line_must_precede// is the part
diff --git a/inform7/if-module/Chapter 5/Command Grammar Tokens.w b/inform7/if-module/Chapter 5/Command Grammar Tokens.w
index c68cb7323..0ad713f33 100644
--- a/inform7/if-module/Chapter 5/Command Grammar Tokens.w
+++ b/inform7/if-module/Chapter 5/Command Grammar Tokens.w
@@ -2,41 +2,246 @@
CGs are list of CG lines, which are lists of CG tokens.
-@
+@h Introduction.
+Until 2021, CG tokens were held as parse nodes in the syntax tree, with a
+special type |TOKEN_NT| and a set of annotations, but as cute as that was
+it was also obfuscatory, and now each CG token corresponds to a //cg_token//
+object as follows:
=
typedef struct cg_token {
struct wording text_of_token;
- int is_literal;
- int slash_class;
- int slash_dash_dash;
int grammar_token_code;
- struct parse_node *grammar_value; /* 0 or else one of the |*_GTC| values */
+ struct parse_node *what_token_describes; /* 0 or else one of the |*_GTC| values */
struct binary_predicate *token_relation;
- struct cg_token *next_token;
+ struct noun_filter_token *noun_filter;
+ struct command_grammar *defined_by;
+ int slash_class; /* used in slashing: see //CGLines::slash// */
+ int slash_dash_dash; /* ditto */
+ struct cg_token *next_token; /* in the list for a CG line */
CLASS_DEFINITION
} cg_token;
+cg_token *CGTokens::cgt_of(wording W, int lit) {
+ cg_token *cgt = CREATE(cg_token);
+ cgt->text_of_token = W;
+ cgt->slash_dash_dash = FALSE;
+ cgt->slash_class = 0;
+ cgt->what_token_describes = NULL;
+ cgt->grammar_token_code = lit?LITERAL_GTC:0;
+ cgt->token_relation = NULL;
+ cgt->noun_filter = NULL;
+ cgt->defined_by = NULL;
+ cgt->next_token = NULL;
+ return cgt;
+}
+
+@h Text to a CG token list.
+Tokens are created when text such as "drill [something] with [something]"
+is parsed, from an Understand sentence or elsewhere. What happens is much
+the same as when text with substitutions is read: the text is retokenised
+by the lexer to produce the following, in which the square brackets have
+become commas:
+= (text)
+"drill" , something , "with" , something
+=
+In fact we use a different punctuation set from the lexer's default, because
+we want forward slashes to break words, so that we need |/| to be a punctuation
+mark: thus "get away/off/out" becomes
+= (text)
+"get" "away" / "off" / "out"
+=
+
+@d GRAMMAR_PUNCTUATION_MARKS L".,:;?!(){}[]/" /* note the slash */
+
+=
+cg_token *CGTokens::tokenise(wording W) {
+ wchar_t *as_wide_string = Lexer::word_text(Wordings::first_wn(W));
+ @;
+ wording TW = Feeds::feed_C_string_full(as_wide_string, TRUE,
+ GRAMMAR_PUNCTUATION_MARKS);
+ @;
+
+ cg_token *tokens = CGTokens::break_into_tokens(TW);
+ if (tokens == NULL) {
+ StandardProblems::sentence_problem(Task::syntax_tree(),
+ _p_(PM_UnderstandEmptyText),
+ "'understand' should be followed by text which contains at least "
+ "one word or square-bracketed token",
+ "so for instance 'understand \"take [something]\" as taking' is fine, "
+ "but 'understand \"\" as the fog' is not. The same applies to the contents "
+ "of 'topic' columns in tables, since those are also instructions for "
+ "understanding.");
+ }
+ return tokens;
+}
+
+@ =
+ int skip = FALSE, literal_punct = FALSE;
+ for (int i=0; as_wide_string[i]; i++) {
+ if (as_wide_string[i] == '[') skip = TRUE;
+ if (as_wide_string[i] == ']') skip = FALSE;
+ if (skip) continue;
+ if ((as_wide_string[i] == '.') || (as_wide_string[i] == ',') ||
+ (as_wide_string[i] == '!') || (as_wide_string[i] == '?') ||
+ (as_wide_string[i] == ':') || (as_wide_string[i] == ';'))
+ literal_punct = TRUE;
+ }
+ if (literal_punct) {
+ StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_LiteralPunctuation),
+ "'understand' text cannot contain literal punctuation",
+ "or more specifically cannot contain any of these: . , ! ? : ; since they "
+ "are already used in various ways by the parser, and would not correctly "
+ "match here.");
+ return NULL;
+ }
+
+@ =
+ LOOP_THROUGH_WORDING(i, TW)
+ if (i < Wordings::last_wn(TW))
+ if ((compare_word(i, COMMA_V)) && (compare_word(i+1, COMMA_V))) {
+ StandardProblems::sentence_problem(Task::syntax_tree(),
+ _p_(PM_UnderstandCommaCommand),
+ "'understand' as an action cannot involve a comma",
+ "since a command leading to an action never does. "
+ "(Although Inform understands commands like 'PETE, LOOK' "
+ "only the part after the comma is read as an action command: "
+ "the part before the comma is read as the name of someone, "
+ "according to the usual rules for parsing a name.) "
+ "Because of the way Inform processes text with square "
+ "brackets, this problem message is also sometimes seen "
+ "if empty square brackets are used, as in 'Understand "
+ "\"bless []\" as blessing.'");
+ return NULL;
+ }
+
+@ The following tiny Preform grammar is then used to break up the resulting
+text at commas:
+=
+ ::=
+ ... , ... | ==> { NOT_APPLICABLE, - }
+ | ==> { TRUE, - }
+ ... ==> { FALSE, - }
+
+@ The following function takes a wording and turns it into a linked list of
+CG tokens, divided by commas:
+
+=
+cg_token *CGTokens::break_into_tokens(wording W) {
+ return CGTokens::break_into_tokens_r(NULL, W);
+}
+cg_token *CGTokens::break_into_tokens_r(cg_token *list, wording W) {
+ (W);
+ switch (<>) {
+ case NOT_APPLICABLE: {
+ wording LW = GET_RW(, 1);
+ wording RW = GET_RW(, 2);
+ list = CGTokens::break_into_tokens_r(list, LW);
+ list = CGTokens::break_into_tokens_r(list, RW);
+ break;
+ }
+ case TRUE:
+ Word::dequote(Wordings::first_wn(W));
+ if (*(Lexer::word_text(Wordings::first_wn(W))) == 0) return list;
+ W = Feeds::feed_C_string_full(Lexer::word_text(Wordings::first_wn(W)),
+ FALSE, GRAMMAR_PUNCTUATION_MARKS);
+ LOOP_THROUGH_WORDING(i, W) {
+ cg_token *cgt = CGTokens::cgt_of(Wordings::one_word(i), TRUE);
+ list = CGTokens::add_to_list(cgt, list);
+ }
+ break;
+ case FALSE: {
+ cg_token *cgt = CGTokens::cgt_of(W, FALSE);
+ list = CGTokens::add_to_list(cgt, list);
+ break;
+ }
+ }
+ return list;
+}
+
+@ If |list| represents the head of the list (and is |NULL| for an empty list),
+this adds |cgt| at the end and returns the new head.
+
+=
+cg_token *CGTokens::add_to_list(cg_token *cgt, cg_token *list) {
+ if (list == NULL) return cgt;
+ if (cgt == NULL) return list;
+ cg_token *x = list;
+ while (x->next_token) x = x->next_token;
+ x->next_token = cgt;
+ return list;
+}
+
+@ As the above shows, the text of a token is not necessarily a single word,
+unless it's a literal.
+
+=
wording CGTokens::text(cg_token *cgt) {
return cgt?(cgt->text_of_token):(EMPTY_WORDING);
}
-@ Tokens with a nonzero |grammar_token_code| correspond closely to what are
-also called "tokens" in the runtime command parser.
+@h The GTC.
+The GTC, or grammar token code, is a sort of type indicator for tokens. As
+produced by the tokeniser above, tokens initially have GTC either |UNDETERMINED_GTC|
+or |LITERAL_GTC|. Differentiation of non-literal tokens into other types happens
+in //CGTokens::determine//.
-@d NAMED_TOKEN_GTC 1 /* these positive values are used only in parsing */
+Note that there are two sets of GTC values, one set positive, one negative. The
+negative ones correspond closely to command-parser grammar reserved tokens in
+the old I6 compiler, and this is indeed what they compile to if we are
+generating I6 code.
+
+@d NAMED_TOKEN_GTC 1
@d RELATED_GTC 2
@d STUFF_GTC 3
@d ANY_STUFF_GTC 4
@d ANY_THINGS_GTC 5
-@d NOUN_TOKEN_GTC -1 /* I6 |noun| */
-@d MULTI_TOKEN_GTC -2 /* I6 |multi| */
-@d MULTIINSIDE_TOKEN_GTC -3 /* I6 |multiinside| */
-@d MULTIHELD_TOKEN_GTC -4 /* I6 |multiheld| */
-@d HELD_TOKEN_GTC -5 /* I6 |held| */
-@d CREATURE_TOKEN_GTC -6 /* I6 |creature| */
-@d TOPIC_TOKEN_GTC -7 /* I6 |topic| */
-@d MULTIEXCEPT_TOKEN_GTC -8 /* I6 |multiexcept| */
+@d LITERAL_GTC 6
+
+@d UNDETERMINED_GTC 0
+
+@d NOUN_TOKEN_GTC -1 /* like I6 |noun| */
+@d MULTI_TOKEN_GTC -2 /* like I6 |multi| */
+@d MULTIINSIDE_TOKEN_GTC -3 /* like I6 |multiinside| */
+@d MULTIHELD_TOKEN_GTC -4 /* like I6 |multiheld| */
+@d HELD_TOKEN_GTC -5 /* like I6 |held| */
+@d CREATURE_TOKEN_GTC -6 /* like I6 |creature| */
+@d TOPIC_TOKEN_GTC -7 /* like I6 |topic| */
+@d MULTIEXCEPT_TOKEN_GTC -8 /* like I6 |multiexcept| */
+
+=
+int CGTokens::is_literal(cg_token *cgt) {
+ if ((cgt) && (cgt->grammar_token_code == LITERAL_GTC)) return TRUE;
+ return FALSE;
+}
+
+int CGTokens::is_I6_parser_token(cg_token *cgt) {
+ if ((cgt) && (cgt->grammar_token_code < 0)) return TRUE;
+ return FALSE;
+}
+
+int CGTokens::is_topic(cg_token *cgt) {
+ if ((cgt) && (cgt->grammar_token_code == TOPIC_TOKEN_GTC)) return TRUE;
+ return FALSE;
+}
+
+@ A multiple token is one which permits multiple matches in the run-time command
+parser: for instance, the player can type ALL where a |MULTI_TOKEN_GTC| is
+expected.
+
+=
+int CGTokens::is_multiple(cg_token *cgt) {
+ switch (cgt->grammar_token_code) {
+ case MULTI_TOKEN_GTC:
+ case MULTIINSIDE_TOKEN_GTC:
+ case MULTIHELD_TOKEN_GTC:
+ case MULTIEXCEPT_TOKEN_GTC:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+@h Logging.
=
void CGTokens::log(cg_token *cgt) {
@@ -64,237 +269,49 @@ void CGTokens::log(cg_token *cgt) {
}
}
-@
+@h Parsing nonliteral tokens.
+Unless a token is literal and in double-quotes, it will start out as having
+|UNDETERMINED_GTC| until we investigate what the words in it mean, which we
+will do with the following Preform grammar.
-|is_literal| is set for literal words such as |"into"|
-and clear for square-bracketed tokens such as |"[something]"|.
-
-The |grammar_token_code| annotation is meaningful only for parse nodes
-with an evaluation of type |DESCRIPTION|. These are tokens which describe a
-range of objects. Examples include "[open container]", which compiles to an
-I6 noun filter, "[any container]", which compiles to an I6 scope filter, or
-"[things]", one of a small number of special cases compiling to primitive I6
-parser tokens. The annotation holds the allocation ID for the noun/scope
-filter structure built for the occasion in the former cases, and one of the
-following constants in the latter case. (These must all have negative values
-in order not to clash with allocation IDs 0, 1, 2, ..., and clearly must all
-be different, but otherwise the values are not significant and there is no
-preferred order.)
-
-For tokens with any other evaluation, |general_purpose| is always 0, so
-that the special values below cannot arise.
-
-@ Tokens are created when text such as "drill [something] with [something]"
-is parsed, from an Understand sentence or elsewhere. What happens is much
-the same as when text with substitutions is read: that produces
-
->> "drill", something, "with", something
-
-and the following little grammar is used to divide this text up into its
-four constituent tokens.
-
-=
- ::=
- ... , ... | ==> { NOT_APPLICABLE, - }
- | ==> { TRUE, - }
- ... ==> { FALSE, - }
-
-@ We use a different punctuation set, in which forward slashes break words,
-to handle such as:
-
->> Understand "get away/off/out" as exiting.
-
-Inform would ordinarily lex the text away/off/out as one single word -- so that
-something like "on/off switch" would be regarded as two words not four --
-but with slash treated as a punctuation mark, we instead read "away / off /
-out", a sequence of five lexical words.
-
-@d GRAMMAR_PUNCTUATION_MARKS L".,:;?!(){}[]/" /* note the slash... */
-
-=
-cg_token *CGTokens::break_into_tokens(cg_token *from, wording W) {
- (W);
- switch (<>) {
- case NOT_APPLICABLE: {
- wording LW = GET_RW(, 1);
- wording RW = GET_RW(, 2);
- from = CGTokens::break_into_tokens(from, LW);
- from = CGTokens::break_into_tokens(from, RW);
- break;
- }
- case TRUE:
- Word::dequote(Wordings::first_wn(W));
- if (*(Lexer::word_text(Wordings::first_wn(W))) == 0) return from;
- W = Feeds::feed_C_string_full(Lexer::word_text(Wordings::first_wn(W)), FALSE, GRAMMAR_PUNCTUATION_MARKS);
- LOOP_THROUGH_WORDING(i, W) {
- cg_token *cgt = CGTokens::cgt_of(Wordings::one_word(i), TRUE);
- from = CGTokens::graft(cgt, from);
- }
- break;
- case FALSE: {
- cg_token *cgt = CGTokens::cgt_of(W, FALSE);
- from = CGTokens::graft(cgt, from);
- break;
- }
- }
- return from;
-}
-
-cg_token *CGTokens::cgt_of(wording W, int lit) {
- cg_token *cgt = CREATE(cg_token);
- cgt->text_of_token = W;
- cgt->is_literal = lit;
- cgt->slash_dash_dash = FALSE;
- cgt->slash_class = 0;
- cgt->grammar_value = NULL;
- cgt->grammar_token_code = 0;
- cgt->token_relation = NULL;
- cgt->next_token = NULL;
- return cgt;
-}
-
-cg_token *CGTokens::graft(cg_token *cgt, cg_token *list) {
- if (list == NULL) return cgt;
- if (cgt == NULL) return list;
- cg_token *x = list;
- while (x->next_token) x = x->next_token;
- x->next_token = cgt;
- return list;
-}
-
-int CGTokens::is_literal(cg_token *cgt) {
- return (cgt)?(cgt->is_literal):FALSE;
-}
-
-@h Multiple tokens.
-A multiple token is one which permits multiple matches in the I6 parser: for
-instance, permits the use of "all".
-
-=
-int CGTokens::is_multiple(cg_token *cgt) {
- switch (cgt->grammar_token_code) {
- case MULTI_TOKEN_GTC:
- case MULTIINSIDE_TOKEN_GTC:
- case MULTIHELD_TOKEN_GTC:
- case MULTIEXCEPT_TOKEN_GTC:
- return TRUE;
- }
- return FALSE;
-}
-
-@h The special tokens.
-Do not change any of these GTC numbers without first checking and updating
-the discussion of CGL sorting in //Command Grammar Lines//:
-
-=
-int CGTokens::gsb_for_special_token(int gtc) {
- switch(gtc) {
- case NOUN_TOKEN_GTC: return 0;
- case MULTI_TOKEN_GTC: return 0;
- case MULTIINSIDE_TOKEN_GTC: return 1;
- case MULTIHELD_TOKEN_GTC: return 2;
- case HELD_TOKEN_GTC: return 3;
- case CREATURE_TOKEN_GTC: return 0;
- case TOPIC_TOKEN_GTC: return -1;
- case MULTIEXCEPT_TOKEN_GTC: return 2;
- default: internal_error("tried to find GSB for invalid GTC");
- }
- return 0; /* to prevent a gcc error: never reached */
-}
-
-@ These translate into I6 as follows:
-
-=
-char *CGTokens::i6_token_for_special_token(int gtc) {
- switch(gtc) {
- case NOUN_TOKEN_GTC: return "noun";
- case MULTI_TOKEN_GTC: return "multi";
- case MULTIINSIDE_TOKEN_GTC: return "multiinside";
- case MULTIHELD_TOKEN_GTC: return "multiheld";
- case HELD_TOKEN_GTC: return "held";
- case CREATURE_TOKEN_GTC: return "creature";
- case TOPIC_TOKEN_GTC: return "topic";
- case MULTIEXCEPT_TOKEN_GTC: return "multiexcept";
- default: internal_error("tried to find I6 token for invalid GTC");
- }
- return ""; /* to prevent a gcc error: never reached */
-}
-
-inter_name *CGTokens::iname_for_special_token(int gtc) {
- switch(gtc) {
- case NOUN_TOKEN_GTC: return VERB_DIRECTIVE_NOUN_iname;
- case MULTI_TOKEN_GTC: return VERB_DIRECTIVE_MULTI_iname;
- case MULTIINSIDE_TOKEN_GTC: return VERB_DIRECTIVE_MULTIINSIDE_iname;
- case MULTIHELD_TOKEN_GTC: return VERB_DIRECTIVE_MULTIHELD_iname;
- case HELD_TOKEN_GTC: return VERB_DIRECTIVE_HELD_iname;
- case CREATURE_TOKEN_GTC: return VERB_DIRECTIVE_CREATURE_iname;
- case TOPIC_TOKEN_GTC: return VERB_DIRECTIVE_TOPIC_iname;
- case MULTIEXCEPT_TOKEN_GTC: return VERB_DIRECTIVE_MULTIEXCEPT_iname;
- default: internal_error("tried to find inter name for invalid GTC");
- }
- return NULL; /* to prevent a gcc error: never reached */
-}
-
-char *CGTokens::i6_constant_for_special_token(int gtc) {
- switch(gtc) {
- case NOUN_TOKEN_GTC: return "NOUN_TOKEN";
- case MULTI_TOKEN_GTC: return "MULTI_TOKEN";
- case MULTIINSIDE_TOKEN_GTC: return "MULTIINSIDE_TOKEN";
- case MULTIHELD_TOKEN_GTC: return "MULTIHELD_TOKEN";
- case HELD_TOKEN_GTC: return "HELD_TOKEN";
- case CREATURE_TOKEN_GTC: return "CREATURE_TOKEN";
- case TOPIC_TOKEN_GTC: return "TOPIC_TOKEN";
- case MULTIEXCEPT_TOKEN_GTC: return "MULTIEXCEPT_TOKEN";
- default: internal_error("tried to find I6 constant for invalid GTC");
- }
- return ""; /* to prevent a gcc error: never reached */
-}
-
-@ The special tokens all return a value in I6 which needs a kind
-to be used in I7: these are defined by the following routine.
-
-=
-kind *CGTokens::kind_for_special_token(int gtc) {
- if ((K_understanding) && (gtc == TOPIC_TOKEN_GTC)) return K_understanding;
- return K_object;
-}
-
-@ The tokens which aren't literal words in double-quotes are parsed as follows:
+Note that always matches any text, even if it sometimes throws
+a problem message on the way. Its return integer is a valid GTC, and its
+return pointer is a (non-null) description of what the token matches.
=
::=
- | ==> { NAMED_TOKEN_GTC, -, <> = RP[1] }
- any things | ==> { ANY_THINGS_GTC, -, <> = Specifications::from_kind(K_thing) }
- any | ==> { ANY_STUFF_GTC, -, <> = RP[1] }
- anything | ==> { ANY_STUFF_GTC, -, <> = Specifications::from_kind(K_thing) }
- anybody | ==> { ANY_STUFF_GTC, -, <> = Specifications::from_kind(K_person) }
- anyone | ==> { ANY_STUFF_GTC, -, <> = Specifications::from_kind(K_person) }
- anywhere | ==> { ANY_STUFF_GTC, -, <> = Specifications::from_kind(K_room) }
- something related by reversed | ==> { RELATED_GTC, BinaryPredicates::get_reversal(RP[1]) }
- something related by | ==> { RELATED_GTC, RP[1] }
- something related by ... | ==> @
- | ==> { R[1], NULL }
- | ==> { STUFF_GTC, -, <> = Specifications::from_kind(RP[2]) }
- | ==> { STUFF_GTC, -, <> = RP[1] }
- | ==> @
- ... ==> @
+ | ==> @
+ any things | ==> { ANY_THINGS_GTC, Specifications::from_kind(K_thing) }
+ any | ==> { ANY_STUFF_GTC, RP[1] }
+ anything | ==> { ANY_STUFF_GTC, Specifications::from_kind(K_thing) }
+ anybody | ==> { ANY_STUFF_GTC, Specifications::from_kind(K_person) }
+ anyone | ==> { ANY_STUFF_GTC, Specifications::from_kind(K_person) }
+ anywhere | ==> { ANY_STUFF_GTC, Specifications::from_kind(K_room) }
+ something related by reversed | ==> @
+ something related by | ==> @
+ something related by ... | ==> @
+ | ==> { pass 1 }
+ | ==> { STUFF_GTC, Specifications::from_kind(RP[2]) }
+ | ==> { STUFF_GTC, RP[1] }
+ | ==> @
+ ... ==> @ ::=
- something | ==> { NOUN_TOKEN_GTC, - }
- things | ==> { MULTI_TOKEN_GTC, - }
- things inside | ==> { MULTIINSIDE_TOKEN_GTC, - }
- things preferably held | ==> { MULTIHELD_TOKEN_GTC, - }
- something preferably held | ==> { HELD_TOKEN_GTC, - }
- other things | ==> { MULTIEXCEPT_TOKEN_GTC, - }
- someone | ==> { CREATURE_TOKEN_GTC, - }
- somebody | ==> { CREATURE_TOKEN_GTC, - }
- text | ==> { TOPIC_TOKEN_GTC, - }
- topic | ==> @
- a topic | ==> @
- object | ==> @
- an object | ==> @
- something held | ==> @
- things held ==> @
+ something | ==> { NOUN_TOKEN_GTC, Specifications::from_kind(K_object) }
+ things | ==> { MULTI_TOKEN_GTC, Specifications::from_kind(K_object) }
+ things inside | ==> { MULTIINSIDE_TOKEN_GTC, Specifications::from_kind(K_object) }
+ things preferably held | ==> { MULTIHELD_TOKEN_GTC, Specifications::from_kind(K_object) }
+ something preferably held | ==> { HELD_TOKEN_GTC, Specifications::from_kind(K_object) }
+ other things | ==> { MULTIEXCEPT_TOKEN_GTC, Specifications::from_kind(K_object) }
+ someone | ==> { CREATURE_TOKEN_GTC, Specifications::from_kind(K_object) }
+ somebody | ==> { CREATURE_TOKEN_GTC, Specifications::from_kind(K_object) }
+ text | ==> { TOPIC_TOKEN_GTC, Specifications::from_kind(K_understanding) }
+ topic | ==> @
+ a topic | ==> @
+ object | ==> @
+ an object | ==> @
+ something held | ==> @
+ things held ==> @ internal {
command_grammar *cg = CommandGrammars::named_token_by_name(W);
@@ -305,6 +322,15 @@ kind *CGTokens::kind_for_special_token(int gtc) {
==> { fail nonterminal };
}
+@ =
+ ==> { NAMED_TOKEN_GTC, ParsingPlugin::rvalue_from_command_grammar(RP[1]) }
+
+@ =
+ ==> { RELATED_GTC, Rvalues::from_binary_predicate(BinaryPredicates::get_reversal(RP[1])) }
+
+@ =
+ ==> { RELATED_GTC, Rvalues::from_binary_predicate(RP[1]) }
+
@ =
Problems::quote_source(1, current_sentence);
Problems::quote_wording(2, W);
@@ -314,7 +340,7 @@ kind *CGTokens::kind_for_special_token(int gtc) {
"invites me to understand names of related things, "
"but the relation is not one that I know.");
Problems::issue_problem_end();
- ==> { RELATED_GTC, NULL };
+ ==> { RELATED_GTC, Rvalues::from_binary_predicate(R_equality) }
@ =
Problems::quote_source(1, current_sentence);
@@ -331,7 +357,7 @@ kind *CGTokens::kind_for_special_token(int gtc) {
"or in descriptions of actions or in table columns; it's really "
"intended only for defining new commands.");
Problems::issue_problem_end();
- ==> { TOPIC_TOKEN_GTC, NULL };
+ ==> { TOPIC_TOKEN_GTC, Specifications::from_kind(K_understanding) };
@ =
Problems::quote_source(1, current_sentence);
@@ -343,17 +369,41 @@ kind *CGTokens::kind_for_special_token(int gtc) {
"all here', but Inform uses the special syntax '[thing]' "
"for that. (Or '[things]' if multiple objects are allowed.)");
Problems::issue_problem_end();
- ==> { MULTI_TOKEN_GTC, NULL };
+ ==> { MULTI_TOKEN_GTC, Specifications::from_kind(K_object) }
@ =
CGTokens::incompatible_change_problem(
"something held", "something", "something preferably held");
- ==> { HELD_TOKEN_GTC, NULL };
+ ==> { HELD_TOKEN_GTC, Specifications::from_kind(K_object) }
@ =
CGTokens::incompatible_change_problem(
"things held", "things", "things preferably held");
- ==> { MULTIHELD_TOKEN_GTC, NULL };
+ ==> { MULTIHELD_TOKEN_GTC, Specifications::from_kind(K_object) }
+
+@ =
+ LOG("$T", current_sentence);
+ Problems::quote_source(1, current_sentence);
+ Problems::quote_wording(2, W);
+ Problems::quote_kind_of(3, RP[1]);
+ StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_BizarreToken));
+ Problems::issue_problem_segment(
+ "The grammar token '%2' in the sentence %1 looked to me as "
+ "if it might be %3, but this isn't something allowed in "
+ "parsing grammar.");
+ Problems::issue_problem_end();
+ ==> { STUFF_GTC, Specifications::from_kind(K_thing) }
+
+@ =
+ LOG("$T", current_sentence);
+ Problems::quote_source(1, current_sentence);
+ Problems::quote_wording(2, W);
+ StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_UnknownToken));
+ Problems::issue_problem_segment(
+ "I was unable to understand what you meant by the grammar token '%2' "
+ "in the sentence %1.");
+ Problems::issue_problem_end();
+ ==> { STUFF_GTC, Specifications::from_kind(K_thing) }
@ Something of an extended mea culpa: but it had the desired effect, in
that nobody complained about what might have been a controversial change.
@@ -385,106 +435,114 @@ void CGTokens::incompatible_change_problem(char *token_tried, char *token_instea
Problems::issue_problem_end();
}
-@ =
- LOG("$T", current_sentence);
- Problems::quote_source(1, current_sentence);
- Problems::quote_wording(2, W);
- Problems::quote_kind_of(3, RP[1]);
- StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_BizarreToken));
- Problems::issue_problem_segment(
- "The grammar token '%2' in the sentence %1 looked to me as "
- "if it might be %3, but this isn't something allowed in "
- "parsing grammar.");
- Problems::issue_problem_end();
- ==> { STUFF_GTC, - };
-
-@ =
- LOG("$T", current_sentence);
- Problems::quote_source(1, current_sentence);
- Problems::quote_wording(2, W);
- StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_UnknownToken));
- Problems::issue_problem_segment(
- "I was unable to understand what you meant by the grammar token '%2' "
- "in the sentence %1.");
- Problems::issue_problem_end();
- ==> { STUFF_GTC, - };
-
@h Determining.
+To calculate a description of what is being described by a token, then, we
+call the following function, which delegates to above.
+In the two cases |NAMED_TOKEN_GTC| and |RELATED_GTC| the pointer result is
+a temporary one telling us which named token, and which relation, respectively:
+we then convert those into the result. In all other cases, the |parse_node|
+pointer returned by is the result.
=
-parse_node *CGTokens::determine(cg_token *cgt, int depth, int *score) {
+parse_node *CGTokens::determine(cg_token *cgt, int depth) {
if (CGTokens::is_literal(cgt)) return NULL;
- <> = NULL;
- parse_node *spec = NULL;
(CGTokens::text(cgt));
- switch (<>) {
- case NAMED_TOKEN_GTC: @; break;
- case ANY_STUFF_GTC: @; break;
- case ANY_THINGS_GTC: @; break;
- case RELATED_GTC: @; break;
- case STUFF_GTC: @; break;
- default: @; break;
+ cgt->grammar_token_code = <>;
+ parse_node *result = <