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.
typedef struct gpr_kit { inter_symbol *cur_addr_s; inter_symbol *cur_len_s; inter_symbol *cur_word_s; inter_symbol *f_s; inter_symbol *g_s; inter_symbol *group_wn_s; inter_symbol *instance_s; inter_symbol *matched_number_s; inter_symbol *mid_word_s; inter_symbol *n_s; inter_symbol *original_wn_s; inter_symbol *pass_s; inter_symbol *pass1_n_s; inter_symbol *pass2_n_s; inter_symbol *range_from_s; inter_symbol *range_words_s; inter_symbol *rv_s; local_variable *rv_lv; inter_symbol *sgn_s; inter_symbol *spn_s; inter_symbol *ss_s; inter_symbol *tot_s; inter_symbol *try_from_wn_s; inter_symbol *v_s; inter_symbol *w_s; inter_symbol *wpos_s; inter_symbol *x_s; } gpr_kit; gpr_kit PL::Parsing::Tokens::Values::new_kit(void) { gpr_kit gprk; gprk.cur_addr_s = NULL; gprk.cur_len_s = NULL; gprk.cur_word_s = NULL; gprk.f_s = NULL; gprk.g_s = NULL; gprk.group_wn_s = NULL; gprk.instance_s = NULL; gprk.matched_number_s = NULL; gprk.mid_word_s = NULL; gprk.n_s = NULL; gprk.original_wn_s = NULL; gprk.pass_s = NULL; gprk.pass1_n_s = NULL; gprk.pass2_n_s = NULL; gprk.range_from_s = NULL; gprk.range_words_s = NULL; gprk.rv_s = NULL; gprk.rv_lv = NULL; gprk.sgn_s = NULL; gprk.spn_s = NULL; gprk.ss_s = NULL; gprk.tot_s = NULL; gprk.try_from_wn_s = NULL; gprk.v_s = NULL; gprk.w_s = NULL; gprk.wpos_s = NULL; gprk.x_s = NULL; return gprk; } void PL::Parsing::Tokens::Values::add_instance_call(gpr_kit *gprk) { gprk->instance_s = LocalVariables::add_named_call_as_symbol(I"instance"); } void PL::Parsing::Tokens::Values::add_range_calls(gpr_kit *gprk) { gprk->range_from_s = LocalVariables::add_internal_local_c_as_symbol(I"range_from", "call parameter: word number of snippet start"); gprk->range_words_s = LocalVariables::add_internal_local_c_as_symbol(I"range_words", "call parameter: snippet length"); } void PL::Parsing::Tokens::Values::add_original(gpr_kit *gprk) { gprk->original_wn_s = LocalVariables::add_internal_local_as_symbol(I"original_wn"); } void PL::Parsing::Tokens::Values::add_standard_set(gpr_kit *gprk) { gprk->group_wn_s = LocalVariables::add_internal_local_as_symbol(I"group_wn"); gprk->v_s = LocalVariables::add_internal_local_as_symbol(I"v"); gprk->w_s = LocalVariables::add_internal_local_as_symbol(I"w"); gprk->rv_s = LocalVariables::add_internal_local_as_symbol_noting(I"rv", &(gprk->rv_lv)); } void PL::Parsing::Tokens::Values::add_lp_vars(gpr_kit *gprk) { gprk->wpos_s = LocalVariables::add_internal_local_as_symbol(I"wpos"); gprk->mid_word_s = LocalVariables::add_internal_local_as_symbol(I"mid_word"); gprk->matched_number_s = LocalVariables::add_internal_local_as_symbol(I"matched_number"); gprk->cur_word_s = LocalVariables::add_internal_local_as_symbol(I"cur_word"); gprk->cur_len_s = LocalVariables::add_internal_local_as_symbol(I"cur_len"); gprk->cur_addr_s = LocalVariables::add_internal_local_as_symbol(I"cur_addr"); gprk->sgn_s = LocalVariables::add_internal_local_as_symbol(I"sgn"); gprk->tot_s = LocalVariables::add_internal_local_as_symbol(I"tot"); gprk->f_s = LocalVariables::add_internal_local_as_symbol(I"f"); gprk->x_s = LocalVariables::add_internal_local_as_symbol(I"x"); } void PL::Parsing::Tokens::Values::add_parse_name_vars(gpr_kit *gprk) { gprk->original_wn_s = LocalVariables::add_internal_local_c_as_symbol(I"original_wn", "first word of text parsed"); gprk->group_wn_s = LocalVariables::add_internal_local_c_as_symbol(I"group_wn", "first word matched against A/B/C/... disjunction"); gprk->try_from_wn_s = LocalVariables::add_internal_local_c_as_symbol(I"try_from_wn", "position to try matching from"); gprk->n_s = LocalVariables::add_internal_local_c_as_symbol(I"n", "number of words matched"); gprk->f_s = LocalVariables::add_internal_local_c_as_symbol(I"f", "flag: sufficiently good match found to justify success"); gprk->w_s = LocalVariables::add_internal_local_c_as_symbol(I"w", "for use by individual grammar lines"); gprk->rv_s = LocalVariables::add_internal_local_as_symbol_noting(I"rv", &(gprk->rv_lv)); gprk->g_s = LocalVariables::add_internal_local_c_as_symbol(I"g", "temporary: success flag for parsing visibles"); gprk->ss_s = LocalVariables::add_internal_local_c_as_symbol(I"ss", "temporary: saves 'self' in distinguishing visibles"); gprk->spn_s = LocalVariables::add_internal_local_c_as_symbol(I"spn", "temporary: saves 'parsed_number' in parsing visibles"); gprk->pass_s = LocalVariables::add_internal_local_c_as_symbol(I"pass", "pass counter (1 to 3)"); gprk->pass1_n_s = LocalVariables::add_internal_local_c_as_symbol(I"pass1_n", "value of n recorded during pass 1"); gprk->pass2_n_s = LocalVariables::add_internal_local_c_as_symbol(I"pass2_n", "value of n recorded during pass 2"); } void PL::Parsing::Tokens::Values::number(void) { inter_name *iname = Hierarchy::find(DECIMAL_TOKEN_INNER_HL); packaging_state save = Routines::begin(iname); gpr_kit gprk = PL::Parsing::Tokens::Values::new_kit(); PL::Parsing::Tokens::Values::add_original(&gprk); grammar_verb *gv = PL::Parsing::Verbs::get_parsing_grammar(K_number); if (gv) PL::Parsing::Verbs::compile_iv(&gprk, gv); Produce::inv_primitive(Emit::tree(), RETURN_BIP); Produce::down(Emit::tree()); Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_FAIL_HL)); Produce::up(Emit::tree()); Routines::end(save); Hierarchy::make_available(Emit::tree(), iname); } void PL::Parsing::Tokens::Values::time(void) { inter_name *iname = Hierarchy::find(TIME_TOKEN_INNER_HL); packaging_state save = Routines::begin(iname); gpr_kit gprk = PL::Parsing::Tokens::Values::new_kit(); PL::Parsing::Tokens::Values::add_original(&gprk); kind *K = TimesOfDay::kind(); if (K) { grammar_verb *gv = PL::Parsing::Verbs::get_parsing_grammar(K); if (gv) PL::Parsing::Verbs::compile_iv(&gprk, gv); } Produce::inv_primitive(Emit::tree(), RETURN_BIP); Produce::down(Emit::tree()); Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_FAIL_HL)); Produce::up(Emit::tree()); Routines::end(save); Hierarchy::make_available(Emit::tree(), iname); } void PL::Parsing::Tokens::Values::truth_state(void) { inter_name *iname = Hierarchy::find(TRUTH_STATE_TOKEN_INNER_HL); packaging_state save = Routines::begin(iname); gpr_kit gprk = PL::Parsing::Tokens::Values::new_kit(); PL::Parsing::Tokens::Values::add_original(&gprk); grammar_verb *gv = PL::Parsing::Verbs::get_parsing_grammar(K_truth_state); if (gv) PL::Parsing::Verbs::compile_iv(&gprk, gv); Produce::inv_primitive(Emit::tree(), RETURN_BIP); Produce::down(Emit::tree()); Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_FAIL_HL)); Produce::up(Emit::tree()); Routines::end(save); Hierarchy::make_available(Emit::tree(), iname); } void PL::Parsing::Tokens::Values::compile_type_gprs(void) { int next_label = 1, longest; grammar_verb *gv; kind *K; LOOP_OVER_BASE_KINDS(K) { if ((Kinds::Behaviour::is_an_enumeration(K)) || (Kinds::Behaviour::is_quasinumerical(K))) { instance *q; literal_pattern *lp; if (Kinds::Behaviour::needs_I6_GPR(K) == FALSE) continue; inter_name *iname = RTKinds::get_kind_GPR_iname(K); packaging_state save = Routines::begin(iname); int need_lf_vars = FALSE; LITERAL_FORMS_LOOP(lp, K) { need_lf_vars = TRUE; break; } gpr_kit gprk = PL::Parsing::Tokens::Values::new_kit(); PL::Parsing::Tokens::Values::add_original(&gprk); PL::Parsing::Tokens::Values::add_standard_set(&gprk); if (need_lf_vars) PL::Parsing::Tokens::Values::add_lp_vars(&gprk); Compile body of kind GPR1.1; Routines::end(save); if (Kinds::Behaviour::is_an_enumeration(K)) { inter_name *iname = RTKinds::get_instance_GPR_iname(K); packaging_state save = Routines::begin(iname); gpr_kit gprk = PL::Parsing::Tokens::Values::new_kit(); PL::Parsing::Tokens::Values::add_instance_call(&gprk); PL::Parsing::Tokens::Values::add_original(&gprk); PL::Parsing::Tokens::Values::add_standard_set(&gprk); GV_IS_VALUE_instance_mode = TRUE; Compile body of kind GPR1.1; GV_IS_VALUE_instance_mode = FALSE; Routines::end(save); } } } }
- The structure gpr_kit is accessed in 5/gv, 5/gl, 5/gt2, 5/gpr and here.
§1.1. Compile body of kind GPR1.1 =
Save word number1.1.1; LITERAL_FORMS_LOOP(lp, K) { RTLiteralPatterns::gpr(&gprk, lp); Reset word number1.1.2; } gv = PL::Parsing::Verbs::get_parsing_grammar(K); if (gv != NULL) { PL::Parsing::Verbs::compile_iv(&gprk, gv); Reset word number1.1.2; } longest = 0; LOOP_OVER_INSTANCES(q, K) { wording NW = Instances::get_name_in_play(q, FALSE); int L = Wordings::length(NW) - 1; if (L > longest) longest = L; } for (; longest >= 0; longest--) { LOOP_OVER_INSTANCES(q, K) { wording NW = Instances::get_name_in_play(q, FALSE); if (Wordings::length(NW) - 1 == longest) { if (GV_IS_VALUE_instance_mode) { Produce::inv_primitive(Emit::tree(), IF_BIP); 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_iname(Emit::tree(), K_value, RTInstances::iname(q)); Produce::up(Emit::tree()); Produce::code(Emit::tree()); Produce::down(Emit::tree()); } Reset word number1.1.2; TEMPORARY_TEXT(L) WRITE_TO(L, ".Failed_%d", next_label++); inter_symbol *flab = Produce::reserve_label(Emit::tree(), L); DISCARD_TEXT(L) LOOP_THROUGH_WORDING(k, NW) { Produce::inv_primitive(Emit::tree(), IF_BIP); Produce::down(Emit::tree()); Produce::inv_primitive(Emit::tree(), NE_BIP); Produce::down(Emit::tree()); Produce::inv_call_iname(Emit::tree(), Hierarchy::find(NEXTWORDSTOPPED_HL)); TEMPORARY_TEXT(W) WRITE_TO(W, "%N", k); Produce::val_dword(Emit::tree(), W); DISCARD_TEXT(W) Produce::up(Emit::tree()); Produce::code(Emit::tree()); Produce::down(Emit::tree()); Produce::inv_primitive(Emit::tree(), JUMP_BIP); Produce::down(Emit::tree()); Produce::lab(Emit::tree(), flab); Produce::up(Emit::tree()); Produce::up(Emit::tree()); Produce::up(Emit::tree()); } Produce::inv_primitive(Emit::tree(), STORE_BIP); Produce::down(Emit::tree()); Produce::ref_iname(Emit::tree(), K_value, Hierarchy::find(PARSED_NUMBER_HL)); Produce::val_iname(Emit::tree(), K_value, RTInstances::iname(q)); Produce::up(Emit::tree()); Produce::inv_primitive(Emit::tree(), RETURN_BIP); Produce::down(Emit::tree()); Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_NUMBER_HL)); Produce::up(Emit::tree()); if (GV_IS_VALUE_instance_mode) { Produce::up(Emit::tree()); Produce::up(Emit::tree()); } Produce::place_label(Emit::tree(), flab); } } } Produce::inv_primitive(Emit::tree(), RETURN_BIP); Produce::down(Emit::tree()); Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(GPR_FAIL_HL)); Produce::up(Emit::tree());
- This code is used in §1 (twice).
§1.1.1. Save word number1.1.1 =
Produce::inv_primitive(Emit::tree(), STORE_BIP); Produce::down(Emit::tree()); 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());
- This code is used in §1.1.
§1.1.2. Reset word number1.1.2 =
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::up(Emit::tree());
- This code is used in §1.1 (three times).