Compiled code to print and parse values expressed as literals.
- §1. Compilation data
- §4. Compilation
- §4.2. Matching an LP at run-time
- §5. Printing the I6 variable |value| out in an LP's notation at run-time
§1. Compilation data. Each literal_pattern object contains this data.
typedef struct literal_pattern_compilation_data { struct package_request *lp_package; struct inter_name *print_fn_iname; struct inter_name *parse_fn_iname; struct parse_node *where_created; } literal_pattern_compilation_data; literal_pattern_compilation_data RTLiteralPatterns::new_compilation_data(literal_pattern *lp) { literal_pattern_compilation_data lpcd; lpcd.lp_package = NULL; lpcd.print_fn_iname = NULL; lpcd.parse_fn_iname = NULL; lpcd.where_created = current_sentence; return lpcd; }
- The structure literal_pattern_compilation_data is accessed in 3/uo, 5/mlt, 5/tbl, 5/dbi, 5/dli, 5/dci, 5/prp, 5/kc, 5/act2, 5/nap and here.
§2. And each gives rise to a package, though it contains only two functions: one to print, one to parse from a player's command. (So in Basic Inform, only the first function appears.)
package_request *RTLiteralPatterns::package(literal_pattern *lp) { if (lp == NULL) internal_error("null lp"); if (lp->compilation_data.lp_package == NULL) lp->compilation_data.lp_package = Hierarchy::local_package_to(LITERAL_PATTERNS_HAP, lp->compilation_data.where_created); return lp->compilation_data.lp_package; } inter_name *RTLiteralPatterns::print_fn_iname(literal_pattern *lp) { if (lp->compilation_data.print_fn_iname == NULL) lp->compilation_data.print_fn_iname = Hierarchy::make_iname_in(LP_PRINT_FN_HL, RTLiteralPatterns::package(lp)); return lp->compilation_data.print_fn_iname; } inter_name *RTLiteralPatterns::parse_fn_iname(literal_pattern *lp) { if (lp->compilation_data.parse_fn_iname == NULL) lp->compilation_data.parse_fn_iname = Hierarchy::make_iname_in(LP_PARSE_FN_HL, RTLiteralPatterns::package(lp)); return lp->compilation_data.parse_fn_iname; }
§3. Unless the parsing feature is activated, this request is never made.
int literal_pattern_parsing_enabled = FALSE; void RTLiteralPatterns::enable_parsing(void) { literal_pattern_parsing_enabled = TRUE; }
void RTLiteralPatterns::compile(void) { literal_pattern *lp; LOOP_OVER(lp, literal_pattern) { text_stream *desc = Str::new(); WRITE_TO(desc, "literal pattern '%W'", lp->prototype_text); Sequence::queue(&RTLiteralPatterns::compilation_agent, STORE_POINTER_literal_pattern(lp), desc); } } void RTLiteralPatterns::compilation_agent(compilation_subtask *t) { literal_pattern *lp = RETRIEVE_POINTER_literal_pattern(t->data); Compile the print function4.1; if (literal_pattern_parsing_enabled) Compile the parse function4.2; }
§4.1. Compile the print function4.1 =
inter_name *iname = RTLiteralPatterns::print_fn_iname(lp); packaging_state save = Functions::begin(iname); inter_symbol *value_s = LocalVariables::new_other_as_symbol(I"value"); inter_symbol *rem_s = LocalVariables::new_internal_as_symbol(I"rem"); inter_symbol *S_s = LocalVariables::new_internal_as_symbol(I"S"); Print according to this particular literal pattern4.1.1; EmitCode::rtrue(); Functions::end(save);
- This code is used in §4.
§4.1.1. Print according to this particular literal pattern4.1.1 =
RTLiteralPatterns::comment_use_of_lp(lp); int ec=0, oc=0; for (int tc=0; tc<lp->no_lp_tokens; tc++) { if (lp->lp_elements[ec].preamble_optional) Truncate the printed form here if subsequent numerical parts are zero4.1.1.4; if ((tc>0) && (lp->lp_tokens[tc].new_word_at)) { EmitCode::inv(PRINT_BIP); EmitCode::down(); EmitCode::val_text(I" "); EmitCode::up(); } switch (lp->lp_tokens[tc].lpt_type) { case WORD_LPT: Compile Inter to print a fixed word token within a literal pattern4.1.1.1; break; case CHARACTER_LPT: Compile Inter to print a character token within a literal pattern4.1.1.2; break; case ELEMENT_LPT: Compile Inter to print an element token within a literal pattern4.1.1.3; break; default: internal_error("unknown literal pattern token type"); } }
- This code is used in §4.1.
§4.1.1.1. Compile Inter to print a fixed word token within a literal pattern4.1.1.1 =
TEMPORARY_TEXT(T) TranscodeText::from_wide_string(T, Lexer::word_raw_text(lp->lp_tokens[tc].token_wn), CT_RAW); EmitCode::inv(PRINT_BIP); EmitCode::down(); EmitCode::val_text(T); EmitCode::up(); DISCARD_TEXT(T)
- This code is used in §4.1.1.
§4.1.1.2. Compile Inter to print a character token within a literal pattern4.1.1.2 =
TEMPORARY_TEXT(T) TEMPORARY_TEXT(tiny_string) PUT_TO(tiny_string, lp->lp_tokens[tc].token_char); TranscodeText::from_stream(T, tiny_string, CT_RAW); DISCARD_TEXT(tiny_string) EmitCode::inv(PRINT_BIP); EmitCode::down(); EmitCode::val_text(T); EmitCode::up(); DISCARD_TEXT(T)
- This code is used in §4.1.1.
§4.1.1.3. Compile Inter to print an element token within a literal pattern4.1.1.3 =
literal_pattern_element *lpe = &(lp->lp_elements[ec]); if (lpe->element_optional) Truncate the printed form here if subsequent numerical parts are zero4.1.1.4; oc = ec + 1; if ((lp->no_lp_elements == 1) && (lpe->element_range == -1) && (Str::len(lpe->digits_text) == 0) && (lpe->values == NULL)) { Kinds::Scalings::compile_print_in_quanta(lp->scaling, value_s, rem_s, S_s); } else { if ((ec == 0) && (lp->number_signed)) { EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(AND_BIP); EmitCode::down(); EmitCode::inv(LT_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::val_number(0); EmitCode::up(); EmitCode::inv(EQ_BIP); EmitCode::down(); Evaluate LPE value to be printed4.1.1.3.3; EmitCode::val_number(0); EmitCode::up(); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(PRINT_BIP); EmitCode::down(); EmitCode::val_text(I"-"); EmitCode::up(); EmitCode::up(); EmitCode::up(); } Print leading zeros4.1.1.3.2; Print the value itself4.1.1.3.1; if ((ec == 0) && (lp->number_signed)) { EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(LT_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::val_number(0); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, value_s); EmitCode::inv(MINUS_BIP); EmitCode::down(); EmitCode::val_number(0); EmitCode::val_symbol(K_value, value_s); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); } } ec++;
- This code is used in §4.1.1.
§4.1.1.3.1. Print the value itself4.1.1.3.1 =
if (lpe->values) { EmitCode::call(RTLiteralPatterns::values_iname(lpe->values->source)); EmitCode::down(); Evaluate LPE value to be printed without offset4.1.1.3.1.1; EmitCode::up(); } else { if ((lpe->number_base == 10) && (Str::len(lpe->digits_text) == 0)) { EmitCode::inv(PRINTNUMBER_BIP); EmitCode::down(); Evaluate LPE value to be printed4.1.1.3.3; EmitCode::up(); } else { EmitCode::call(Hierarchy::find(PRINTINBASE_HL)); EmitCode::down(); Evaluate LPE value to be printed4.1.1.3.3; EmitCode::val_number((inter_ti) (lpe->number_base)); EmitCode::val_number(0); if (Str::len(lpe->digits_text) > 0) EmitCode::val_iname(K_value, RTLiteralPatterns::digits_iname(lpe->digits_text)); EmitCode::up(); } }
- This code is used in §4.1.1.3.
§4.1.1.3.2. Print leading zeros4.1.1.3.2 =
if (lpe->print_with_leading_zeros) { int max_printable = lpe->element_range + lpe->element_offset; if (lpe->max_digits < 1000000) { int b = 1; for (int d = 1; d <= lpe->max_digits; d++) b = b * lpe->number_base; max_printable = b - 1; } int pow = 1; while (max_printable > pow) pow = pow * lpe->number_base; for (; pow>1; pow = pow/lpe->number_base) if (max_printable > pow) { EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(LT_BIP); EmitCode::down(); Evaluate LPE value to be printed4.1.1.3.3; EmitCode::val_number((inter_ti) (pow)); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(PRINTCHAR_BIP); EmitCode::down(); if (Str::len(lpe->digits_text) > 0) EmitCode::val_number((inter_ti) Str::get_at(lpe->digits_text, 0)); else EmitCode::val_number((inter_ti) '0'); EmitCode::up(); EmitCode::up(); EmitCode::up(); } }
- This code is used in §4.1.1.3.
§4.1.1.3.3. Evaluate LPE value to be printed4.1.1.3.3 =
if (lpe->element_offset != 0) { EmitCode::inv(PLUS_BIP); EmitCode::down(); } if (lpe->element_range >= 0) { EmitCode::inv(MODULO_BIP); EmitCode::down(); } EmitCode::inv(DIVIDE_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::val_number((inter_ti) (lpe->element_multiplier)); EmitCode::up(); if (lpe->element_range >= 0) { EmitCode::val_number((inter_ti) (lpe->element_range)); EmitCode::up(); } if (lpe->element_offset != 0) { EmitCode::val_number((inter_ti) (lpe->element_offset)); EmitCode::up(); }
- This code is used in §4.1.1.3, §4.1.1.3.1 (twice), §4.1.1.3.2, §4.1.1.4 (twice).
§4.1.1.3.1.1. Evaluate LPE value to be printed without offset4.1.1.3.1.1 =
if (lpe->element_range >= 0) { EmitCode::inv(MODULO_BIP); EmitCode::down(); } EmitCode::inv(DIVIDE_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::val_number((inter_ti) (lpe->element_multiplier)); EmitCode::up(); if (lpe->element_range >= 0) { EmitCode::val_number((inter_ti) (lpe->element_range)); EmitCode::up(); }
- This code is used in §4.1.1.3.1.
§4.1.1.4. Truncate the printed form here if subsequent numerical parts are zero4.1.1.4 =
if (oc == ec) { literal_pattern_element *lpe = &(lp->lp_elements[ec]); if (ec == 0) { EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); Evaluate LPE value to be printed4.1.1.3.3; EmitCode::val_number(0); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::rtrue(); EmitCode::up(); EmitCode::up(); } else { EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); Evaluate LPE value to be printed4.1.1.3.3; EmitCode::val_number(0); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::rtrue(); EmitCode::up(); EmitCode::up(); } oc = ec + 1; }
§4.2. Matching an LP at run-time. The following function compiles a "general parsing routine" (GPR), in the sense used by the Inform 6 Designer's Manual, to match typed input in the correct notation: roughly speaking, it tries to match words at the current word position wn, and returns either GPR_FAIL or GPR_NUMBER. In the latter case, it sets the parsed_number global to the value matched.
Compile the parse function4.2 =
inter_name *iname = RTLiteralPatterns::parse_fn_iname(lp); packaging_state save = Functions::begin(iname); gpr_kit gprk = GPRs::new_kit(); GPRs::add_original_var(&gprk); GPRs::add_standard_vars(&gprk); GPRs::add_LP_vars(&gprk); inter_symbol *succeeded_label = EmitCode::reserve_label(I".Succeeded"); inter_symbol *failed_label = EmitCode::reserve_label(I".Failed"); Match the literal pattern4.2.1; EmitCode::place_label(failed_label); EmitCode::inv(RETURN_BIP); EmitCode::down(); EmitCode::val_iname(K_value, Hierarchy::find(GPR_FAIL_HL)); EmitCode::up(); Functions::end(save);
- This code is used in §4.
§4.2.1. Match the literal pattern4.2.1 =
int tc, ec; RTLiteralPatterns::comment_use_of_lp(lp); unsigned int bufferbip; if (TargetVMs::is_16_bit(Task::vm())) bufferbip = LOOKUPBYTE_BIP; else bufferbip = LOOKUP_BIP; EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::val_number(0); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.mid_word_s); EmitCode::val_false(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.matched_number_s); EmitCode::val_number(0); EmitCode::up(); for (tc=0, ec=0; tc<lp->no_lp_tokens; tc++) { int lookahead = -1; if ((tc+1<lp->no_lp_tokens) && (lp->lp_tokens[tc+1].lpt_type == CHARACTER_LPT)) lookahead = (int) (lp->lp_tokens[tc+1].token_char); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.mid_word_s); EmitCode::val_false(); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.cur_word_s); EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); EmitCode::up(); EmitCode::inv(POSTDECREMENT_BIP); EmitCode::down(); EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::up(); inter_symbol *to_label = NULL; if ((lp->lp_elements[ec].preamble_optional) && (lp->lp_tokens[tc].lpt_type == ELEMENT_LPT)) to_label = failed_label; else if (LiteralPatterns::at_optional_break_point(lp, ec, tc)) to_label = succeeded_label; else to_label = failed_label; EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_word_s); EmitCode::val_number((inter_ti) -1); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(to_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); switch (lp->lp_tokens[tc].lpt_type) { case WORD_LPT: Compile Inter to match a fixed word token within a literal pattern4.2.1.1; break; case CHARACTER_LPT: Compile Inter to match a character token within a literal pattern4.2.1.2; break; case ELEMENT_LPT: Compile Inter to match an element token within a literal pattern4.2.1.3; break; default: internal_error("unknown literal pattern token type"); } } EmitCode::place_label(succeeded_label); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.mid_word_s); EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(LT_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.sgn_s); EmitCode::val_number(0); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.matched_number_s); if (Kinds::FloatingPoint::uses_floating_point(lp->kind_specified)) { EmitCode::inv(BITWISEOR_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.matched_number_s); EmitCode::val_number(0x80000000); EmitCode::up(); } else { EmitCode::inv(TIMES_BIP); EmitCode::down(); EmitCode::val_number((inter_ti) -1); EmitCode::val_symbol(K_value, gprk.matched_number_s); EmitCode::up(); } EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_iname(K_object, Hierarchy::find(PARSED_NUMBER_HL)); EmitCode::val_symbol(K_value, gprk.matched_number_s); EmitCode::up(); Kinds::Scalings::compile_quanta_to_value(lp->scaling, Hierarchy::find(PARSED_NUMBER_HL), gprk.sgn_s, gprk.x_s, failed_label); EmitCode::inv(IFDEBUG_BIP); EmitCode::down(); EmitCode::code(); EmitCode::down(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(GE_BIP); EmitCode::down(); EmitCode::val_iname(K_value, Hierarchy::find(PARSER_TRACE_HL)); EmitCode::val_number(3); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(PRINT_BIP); EmitCode::down(); EmitCode::val_text(I" [parsed value "); EmitCode::up(); EmitCode::inv(PRINTNUMBER_BIP); EmitCode::down(); EmitCode::val_iname(K_object, Hierarchy::find(PARSED_NUMBER_HL)); EmitCode::up(); EmitCode::inv(PRINT_BIP); EmitCode::down(); TEMPORARY_TEXT(EXP) WRITE_TO(EXP, " by: %W]\n", lp->prototype_text); EmitCode::val_text(EXP); DISCARD_TEXT(EXP) EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(RETURN_BIP); EmitCode::down(); EmitCode::val_iname(K_value, Hierarchy::find(GPR_NUMBER_HL)); EmitCode::up();
- This code is used in §4.2.
§4.2.1.1. Compile Inter to match a fixed word token within a literal pattern4.2.1.1 =
EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.mid_word_s); EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(NE_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_word_s); TEMPORARY_TEXT(N) WRITE_TO(N, "%N", lp->lp_tokens[tc].token_wn); EmitCode::val_dword(N); DISCARD_TEXT(N) EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::up();
- This code is used in §4.2.1.
§4.2.1.2. Compile Inter to match a character token within a literal pattern4.2.1.2 =
Compile Inter to enter mid-word parsing if not already in it4.2.1.2.1; inchar32_t lower_form = Characters::tolower(lp->lp_tokens[tc].token_char); inchar32_t upper_form = Characters::toupper(lp->lp_tokens[tc].token_char); EmitCode::inv(IF_BIP); EmitCode::down(); if (upper_form != lower_form) { EmitCode::inv(AND_BIP); EmitCode::down(); } EmitCode::inv(NE_BIP); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::up(); EmitCode::val_number((inter_ti) lower_form); EmitCode::up(); if (upper_form != lower_form) { EmitCode::inv(NE_BIP); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::inv(MINUS_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_number(1); EmitCode::up(); EmitCode::up(); EmitCode::val_number((inter_ti) upper_form); EmitCode::up(); } if (upper_form != lower_form) { EmitCode::up(); } EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); Compile Inter to exit mid-word parsing if at end of a word4.2.1.2.2;
- This code is used in §4.2.1.
§4.2.1.3. Compile Inter to match an element token within a literal pattern4.2.1.3 =
Compile Inter to enter mid-word parsing if not already in it4.2.1.2.1; literal_pattern_element *lpe = &(lp->lp_elements[ec++]); if (ec == 1) { EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.sgn_s); EmitCode::val_number(1); EmitCode::up(); } EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::val_number((inter_ti) '-'); EmitCode::up(); EmitCode::code(); EmitCode::down(); if ((lp->number_signed) && (ec == 1)) { EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.sgn_s); EmitCode::val_number((inter_ti) -1); EmitCode::up(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::up(); } else { EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); } EmitCode::up(); EmitCode::up(); if (Kinds::FloatingPoint::uses_floating_point(lp->kind_specified)) Compile Inter to match a real number here4.2.1.3.1 else Compile Inter to match an integer here4.2.1.3.2; Compile Inter to exit mid-word parsing if at end of a word4.2.1.2.2;
- This code is used in §4.2.1.
§4.2.1.3.1. Compile Inter to match a real number here4.2.1.3.1 =
EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::val_false(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.x_s); EmitCode::inv(PLUS_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::up(); March forwards through decimal digits4.2.1.3.1.1; EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.f_s); EmitCode::val_number(0); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_symbol(K_value, gprk.cur_len_s); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.cur_word_s); EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::inv(MINUS_BIP); EmitCode::down(); EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::val_number(2); EmitCode::up(); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_word_s); EmitCode::val_iname(K_value, Hierarchy::find(THEN1__WD_HL)); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::inv(PLUS_BIP); EmitCode::down(); EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::val_number(2); EmitCode::up(); EmitCode::up(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.mid_word_s); EmitCode::val_false(); EmitCode::up(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::up(); Compile Inter to enter mid-word parsing if not already in it4.2.1.2.1; March forwards through decimal digits4.2.1.3.1.1; EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.tot_s); EmitCode::val_number(0); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_symbol(K_value, gprk.cur_len_s); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.tot_s); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.cur_word_s); EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.mid_word_s); EmitCode::val_false(); EmitCode::up(); Compile Inter to enter mid-word parsing if not already in it4.2.1.2.1; EmitCode::up(); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(AND_BIP); EmitCode::down(); EmitCode::inv(LT_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_symbol(K_value, gprk.cur_len_s); EmitCode::up(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::val_number((inter_ti) 'x'); EmitCode::up(); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::inv(PLUS_BIP); EmitCode::down(); EmitCode::inv(PLUS_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.f_s); EmitCode::val_symbol(K_value, gprk.tot_s); EmitCode::up(); EmitCode::val_number(1); EmitCode::up(); EmitCode::up(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_symbol(K_value, gprk.cur_len_s); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.cur_word_s); EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.mid_word_s); EmitCode::val_false(); EmitCode::up(); Compile Inter to enter mid-word parsing if not already in it4.2.1.2.1; EmitCode::up(); EmitCode::up(); EmitCode::inv(IFELSE_BIP); EmitCode::down(); EmitCode::inv(AND_BIP); EmitCode::down(); EmitCode::inv(LT_BIP); EmitCode::down(); EmitCode::inv(PLUS_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_number(3); EmitCode::up(); EmitCode::val_symbol(K_value, gprk.cur_len_s); EmitCode::up(); EmitCode::inv(AND_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::val_number((inter_ti) '1'); EmitCode::up(); EmitCode::inv(AND_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::inv(PLUS_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_number(1); EmitCode::up(); EmitCode::up(); EmitCode::val_number((inter_ti) '0'); EmitCode::up(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::inv(PLUS_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_number(2); EmitCode::up(); EmitCode::up(); EmitCode::val_number((inter_ti) '^'); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::inv(PLUS_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.f_s); EmitCode::val_number(3); EmitCode::up(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::inv(PLUS_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_number(3); EmitCode::up(); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(AND_BIP); EmitCode::down(); EmitCode::inv(LT_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_symbol(K_value, gprk.cur_len_s); EmitCode::up(); EmitCode::inv(OR_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::val_number((inter_ti) '+'); EmitCode::up(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::val_number((inter_ti) '-'); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::up(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::up(); EmitCode::up(); March forwards through decimal digits4.2.1.3.1.1; EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(POSTDECREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.x_s); EmitCode::call(Hierarchy::find(FLOATPARSE_HL)); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.x_s); EmitCode::val_symbol(K_value, gprk.f_s); EmitCode::val_true(); EmitCode::up(); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.x_s); EmitCode::val_iname(K_value, Hierarchy::find(FLOAT_NAN_HL)); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_number(0); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.mid_word_s); EmitCode::val_false(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.matched_number_s); EmitCode::val_symbol(K_value, gprk.x_s); EmitCode::up();
- This code is used in §4.2.1.3.
§4.2.1.3.1.1. March forwards through decimal digits4.2.1.3.1.1 =
EmitCode::inv(WHILE_BIP); EmitCode::down(); EmitCode::inv(AND_BIP); EmitCode::down(); EmitCode::inv(LT_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_symbol(K_value, gprk.cur_len_s); EmitCode::up(); EmitCode::inv(GE_BIP); EmitCode::down(); EmitCode::call(RTLiteralPatterns::digit_value_function_iname(lpe)); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::up(); EmitCode::val_number(0); EmitCode::up(); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::up(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::up(); EmitCode::up();
- This code is used in §4.2.1.3.1 (three times).
§4.2.1.3.2. Compile Inter to match an integer here4.2.1.3.2 =
EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.tot_s); EmitCode::val_number(0); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::val_false(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.rv_s); EmitCode::val_number(0); EmitCode::up(); if (lpe->values) Use the custom value set4.2.1.3.2.1 else Use regular digit-by-digit parsing4.2.1.3.2.2; Kinds::Scalings::compile_scale_and_add(gprk.tot_s, gprk.sgn_s, lpe->element_multiplier, 0, gprk.matched_number_s, failed_label); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.matched_number_s); EmitCode::val_symbol(K_value, gprk.tot_s); EmitCode::up(); int M = Kinds::Scalings::get_integer_multiplier(lp->scaling); if (M > 1) { EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_symbol(K_value, gprk.cur_len_s); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.cur_word_s); EmitCode::call(Hierarchy::find(NEXTWORDSTOPPED_HL)); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::inv(MINUS_BIP); EmitCode::down(); EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::val_number(2); EmitCode::up(); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_word_s); EmitCode::val_iname(K_value, Hierarchy::find(THEN1__WD_HL)); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::inv(PLUS_BIP); EmitCode::down(); EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::val_number(2); EmitCode::up(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.mid_word_s); EmitCode::val_false(); EmitCode::up(); Compile Inter to enter mid-word parsing if not already in it4.2.1.2.1; EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.x_s); EmitCode::val_number(0); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::val_number((inter_ti) M); EmitCode::up(); EmitCode::inv(WHILE_BIP); EmitCode::down(); EmitCode::inv(AND_BIP); EmitCode::down(); EmitCode::inv(GT_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.f_s); EmitCode::val_number(1); EmitCode::up(); EmitCode::inv(AND_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::inv(MODULO_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.f_s); EmitCode::val_number((inter_ti) lpe->number_base); EmitCode::up(); EmitCode::val_number(0); EmitCode::up(); EmitCode::inv(GE_BIP); EmitCode::down(); EmitCode::call(RTLiteralPatterns::digit_value_function_iname(lpe)); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::up(); if (lpe->number_base != 10) EmitCode::val_number((inter_ti) lpe->number_base); EmitCode::up(); EmitCode::val_number(0); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.w_s); EmitCode::inv(DIVIDE_BIP); EmitCode::down(); EmitCode::inv(TIMES_BIP); EmitCode::down(); EmitCode::call(RTLiteralPatterns::digit_value_function_iname(lpe)); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::up(); if (lpe->number_base != 10) EmitCode::val_number((inter_ti) lpe->number_base); EmitCode::up(); EmitCode::val_symbol(K_value, gprk.f_s); EmitCode::up(); EmitCode::val_number((inter_ti) lpe->number_base); EmitCode::up(); EmitCode::up(); Kinds::Scalings::compile_scale_and_add(gprk.x_s, gprk.sgn_s, 1, 0, gprk.w_s, failed_label); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::inv(DIVIDE_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.f_s); EmitCode::val_number((inter_ti) lpe->number_base); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up(); }
- This code is used in §4.2.1.3.
§4.2.1.3.2.1. Use the custom value set4.2.1.3.2.1 =
TEMPORARY_TEXT(lname) WRITE_TO(lname, ".Exit%d", lpe->element_index); inter_symbol *exit_label = EmitCode::reserve_label(lname); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.rv_s); EmitCode::val_false(); EmitCode::up(); literal_pattern_element_value_set *set = lpe->values; for (int c = 0; c < LiteralPatterns::element_value_count(set); c++) { text_stream *match = LiteralPatterns::element_value_text(set, c); for (int i = 0; i < Str::len(match); i++) { EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); if (i > 0) { EmitCode::inv(PLUS_BIP); EmitCode::down(); } EmitCode::val_symbol(K_value, gprk.wpos_s); if (i > 0) { EmitCode::val_number((inter_ti) i); EmitCode::up(); } EmitCode::up(); EmitCode::val_number((inter_ti) Characters::tolower(Str::get_at(match, i))); EmitCode::up(); EmitCode::code(); EmitCode::down(); } EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.tot_s); EmitCode::val_number((inter_ti) LiteralPatterns::element_value_equivalent(set, c)); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.rv_s); EmitCode::val_true(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::inv(PLUS_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_number((inter_ti) Str::len(match)); EmitCode::up(); EmitCode::up(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(exit_label); EmitCode::up(); for (int i = 0; i < Str::len(match); i++) { EmitCode::up(); EmitCode::up(); } } EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.rv_s); EmitCode::val_false(); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::place_label(exit_label); DISCARD_TEXT(lname)
- This code is used in §4.2.1.3.2.
§4.2.1.3.2.2. Use regular digit-by-digit parsing4.2.1.3.2.2 =
EmitCode::inv(WHILE_BIP); EmitCode::down(); EmitCode::inv(AND_BIP); EmitCode::down(); if (lpe->max_digits < 1000000) { EmitCode::inv(LT_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.rv_s); EmitCode::val_number((inter_ti) lpe->max_digits); EmitCode::up(); EmitCode::inv(AND_BIP); EmitCode::down(); } EmitCode::inv(LT_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_symbol(K_value, gprk.cur_len_s); EmitCode::up(); EmitCode::inv(GE_BIP); EmitCode::down(); EmitCode::call(RTLiteralPatterns::digit_value_function_iname(lpe)); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::up(); if (lpe->number_base != 10) EmitCode::val_number((inter_ti) lpe->number_base); EmitCode::up(); EmitCode::val_number(0); EmitCode::up(); if (lpe->max_digits < 1000000) { EmitCode::up(); } EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::call(RTLiteralPatterns::digit_value_function_iname(lpe)); EmitCode::down(); EmitCode::inv(bufferbip); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.cur_addr_s); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::up(); if (lpe->number_base != 10) EmitCode::val_number((inter_ti) lpe->number_base); EmitCode::up(); EmitCode::up(); Kinds::Scalings::compile_scale_and_add(gprk.tot_s, gprk.sgn_s, lpe->number_base, 0, gprk.f_s, failed_label); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.f_s); EmitCode::val_true(); EmitCode::up(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::up(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.rv_s); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.f_s); EmitCode::val_false(); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); if (lpe->min_digits > 1) { EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(LT_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.rv_s); EmitCode::val_number((inter_ti) lpe->min_digits); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); } if (lpe->element_offset != 0) { EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.tot_s); EmitCode::inv(MINUS_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.tot_s); EmitCode::val_number((inter_ti) lpe->element_offset); EmitCode::up(); EmitCode::up(); } if (lpe->element_range > 0) { inter_ti min_val = 0; inter_ti max_val = (inter_ti) (lpe->element_range); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(LT_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.tot_s); EmitCode::val_number(min_val); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(GE_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.tot_s); EmitCode::val_number(max_val); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(JUMP_BIP); EmitCode::down(); EmitCode::lab(failed_label); EmitCode::up(); EmitCode::up(); EmitCode::up(); }
- This code is used in §4.2.1.3.2.
§4.2.1.2.1. Compile Inter to enter mid-word parsing if not already in it4.2.1.2.1 =
EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.mid_word_s); EmitCode::val_false(); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.mid_word_s); EmitCode::val_true(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.wpos_s); EmitCode::val_number(0); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.cur_addr_s); EmitCode::call(Hierarchy::find(WORDADDRESS_HL)); EmitCode::down(); EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::up(); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.cur_len_s); EmitCode::call(Hierarchy::find(WORDLENGTH_HL)); EmitCode::down(); EmitCode::val_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::up(); EmitCode::up(); EmitCode::up(); EmitCode::up();
- This code is used in §4.2.1.2, §4.2.1.3, §4.2.1.3.1 (three times), §4.2.1.3.2.
§4.2.1.2.2. Compile Inter to exit mid-word parsing if at end of a word4.2.1.2.2 =
EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, gprk.wpos_s); EmitCode::val_symbol(K_value, gprk.cur_len_s); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::inv(POSTINCREMENT_BIP); EmitCode::down(); EmitCode::ref_iname(K_value, Hierarchy::find(WN_HL)); EmitCode::up(); EmitCode::inv(STORE_BIP); EmitCode::down(); EmitCode::ref_symbol(K_value, gprk.mid_word_s); EmitCode::val_false(); EmitCode::up(); EmitCode::up(); EmitCode::up();
§5. Printing the I6 variable |value| out in an LP's notation at run-time.
void RTLiteralPatterns::printing_routine(inter_name *iname, literal_pattern *lp_list) { packaging_state save = Functions::begin(iname); literal_pattern_name *lpn; literal_pattern *lp; int k; inter_symbol *value_s = LocalVariables::new_other_as_symbol(I"value"); inter_symbol *which_s = LocalVariables::new_other_as_symbol(I"which"); LOOP_OVER(lpn, literal_pattern_name) { if (Wordings::nonempty(lpn->notation_name)) { k = 0; for (lp = lp_list; lp; lp = lp->next_for_this_kind) lp->marked_for_printing = FALSE; literal_pattern_name *lpn2; for (lpn2 = lpn; lpn2; lpn2 = lpn2->next) for (lp = lp_list; lp; lp = lp->next_for_this_kind) if (lp == lpn2->can_use_this_lp) { k++; lp->marked_for_printing = TRUE; } if (k > 0) { TEMPORARY_TEXT(C) WRITE_TO(C, "The named notation: %W", lpn->notation_name); EmitCode::comment(C); DISCARD_TEXT(C) EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, which_s); EmitCode::val_number((inter_ti) (lpn->allocation_id + 1)); EmitCode::up(); EmitCode::code(); EmitCode::down(); Compile code to jump to the correct printing pattern5.2; EmitCode::up(); EmitCode::up(); } } } Choose which patterns are eligible for printing5.1; Compile code to jump to the correct printing pattern5.2; EmitCode::rtrue(); Functions::end(save); }
§5.1. This was at one time a more complicated criterion, which masked bugs in the sorting measure.
Choose which patterns are eligible for printing5.1 =
for (k=0, lp = lp_list; lp; lp = lp->next_for_this_kind) { int eligible = FALSE; if (lp->equivalent_unit == FALSE) eligible = TRUE; if (eligible) k++; lp->marked_for_printing = eligible; }
- This code is used in §5.
§5.2. Compile code to jump to the correct printing pattern5.2 =
literal_pattern *lpb = NULL; for (lp = lp_list; lp; lp = lp->next_for_this_kind) if (lp->marked_for_printing) if (lp->benchmark) lpb = lp; if ((lpb) && (lpb->singular_form_only == FALSE)) { EmitCode::inv(IF_BIP); EmitCode::down(); EmitCode::inv(EQ_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::val_number(0); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::call(RTLiteralPatterns::print_fn_iname(lpb)); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::up(); EmitCode::rtrue(); EmitCode::up(); EmitCode::up(); } literal_pattern *last_lp = NULL, *last_primary = NULL, *last_singular = NULL, *last_plural = NULL; for (lp = lp_list; lp; lp = lp->next_for_this_kind) { if (lp->marked_for_printing) { inter_ti op = GE_BIP; last_lp = lp; if (lp->primary_alternative) { last_primary = lp; } if (lp->singular_form_only) { last_singular = lp; op = EQ_BIP; } if (lp->plural_form_only) { last_plural = lp; op = GT_BIP; } EmitCode::inv(IF_BIP); EmitCode::down(); Kinds::Scalings::compile_threshold_test(lp->scaling, value_s, op); EmitCode::code(); EmitCode::down(); EmitCode::call(RTLiteralPatterns::print_fn_iname(lp)); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::up(); EmitCode::rtrue(); EmitCode::up(); EmitCode::up(); } } if (last_primary) last_lp = last_primary; if (last_lp) { if ((last_lp->singular_form_only) && (last_plural) && (Kinds::Scalings::compare(last_plural->scaling, last_lp->scaling) == 0)) { EmitCode::call(RTLiteralPatterns::print_fn_iname(last_plural)); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::up(); EmitCode::rtrue(); } EmitCode::call(RTLiteralPatterns::print_fn_iname(last_lp)); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::up(); EmitCode::rtrue(); }
- This code is used in §5 (twice).
§6. A comment used in both of the above functions.
void RTLiteralPatterns::comment_use_of_lp(literal_pattern *lp) { TEMPORARY_TEXT(W) WRITE_TO(W, "%W, ", lp->prototype_text); Kinds::Scalings::describe(W, lp->scaling); EmitCode::comment(W); DISCARD_TEXT(W) }
§7. Dealing with non-standard digits.
enum DIGIT_PRINTER_NSDF from 0 enum VALUES_PRINTER_NSDF enum DIGIT_READER_NSDF
dictionary *digits_iname_D[4] = { NULL, NULL, NULL, NULL }; inter_name *RTLiteralPatterns::digits_iname(text_stream *text) { return RTLiteralPatterns::digits_iname_inner(text, DIGIT_PRINTER_NSDF); } inter_name *RTLiteralPatterns::values_iname(text_stream *text) { return RTLiteralPatterns::digits_iname_inner(text, VALUES_PRINTER_NSDF); } inter_name *RTLiteralPatterns::digit_value_function_iname(literal_pattern_element *lpe) { if ((lpe) && (lpe->digits_text)) return RTLiteralPatterns::digits_iname_inner(lpe->digits_text, DIGIT_READER_NSDF); return Hierarchy::find(DIGITTOVALUE_HL); } typedef struct digit_manager { struct inter_name *function_iname; struct text_stream *text; int category; CLASS_DEFINITION } digit_manager; inter_name *RTLiteralPatterns::digits_iname_inner(text_stream *text, int cat) { if (digits_iname_D[cat] == NULL) digits_iname_D[cat] = Dictionaries::new(16, FALSE); dictionary *D = digits_iname_D[cat]; if (Dictionaries::find(D, text)) return Dictionaries::read_value(D, text); package_request *PR = HierarchyLocations::attach_new_package( Emit::tree(), NULL, Emit::current_enclosure(), DIGIT_MANAGERS_HAP); inter_name *iname = Hierarchy::make_iname_in(DIGIT_MANAGER_HL, PR); text_stream *desc = Str::new(); WRITE_TO(desc, "digit manager for <%S> cat %d", text, cat); digit_manager *dm = CREATE(digit_manager); dm->function_iname = iname; dm->text = Str::duplicate(text); dm->category = cat; Sequence::queue(&RTLiteralPatterns::dm_agent, STORE_POINTER_digit_manager(dm), desc); Dictionaries::create(D, text); Dictionaries::write_value(D, text, iname); return iname; } void RTLiteralPatterns::dm_agent(compilation_subtask *t) { digit_manager *dm = RETRIEVE_POINTER_digit_manager(t->data); packaging_state save = Functions::begin(dm->function_iname); inter_symbol *value_s = LocalVariables::new_other_as_symbol(I"value"); switch (dm->category) { case DIGIT_PRINTER_NSDF: Compile the body of a digit-printer function7.1; break; case VALUES_PRINTER_NSDF: Compile the body of a value-printer function7.2; break; case DIGIT_READER_NSDF: Compile the body of a digit-reader function7.3; break; } Functions::end(save); }
- The structure digit_manager is accessed in 4/bq and here.
§7.1. Compile the body of a digit-printer function7.1 =
EmitCode::inv(SWITCH_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::code(); EmitCode::down(); for (int c = 0; c < Str::len(dm->text); c++) { EmitCode::inv(CASE_BIP); EmitCode::down(); EmitCode::val_number((inter_ti) c); EmitCode::code(); EmitCode::down(); EmitCode::inv(PRINTCHAR_BIP); EmitCode::down(); EmitCode::val_number((inter_ti) Str::get_at(dm->text, c)); EmitCode::up(); EmitCode::up(); EmitCode::up(); } EmitCode::up(); EmitCode::up(); EmitCode::rtrue();
- This code is used in §7.
§7.2. Compile the body of a value-printer function7.2 =
EmitCode::inv(SWITCH_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::code(); EmitCode::down(); literal_pattern_element_value_set *set = LiteralPatterns::parse_value_set(dm->text); for (int c = 0; c < LiteralPatterns::element_value_count(set); c++) { EmitCode::inv(CASE_BIP); EmitCode::down(); EmitCode::val_number((inter_ti) LiteralPatterns::element_value_equivalent(set, c)); EmitCode::code(); EmitCode::down(); EmitCode::inv(PRINT_BIP); EmitCode::down(); EmitCode::val_text(LiteralPatterns::element_value_text(set, c)); EmitCode::up(); EmitCode::up(); EmitCode::up(); } EmitCode::up(); EmitCode::up(); EmitCode::rtrue();
- This code is used in §7.
§7.3. Compile the body of a digit-reader function7.3 =
EmitCode::inv(SWITCH_BIP); EmitCode::down(); EmitCode::val_symbol(K_value, value_s); EmitCode::code(); EmitCode::down(); for (int c = 0; c < Str::len(dm->text); c++) { EmitCode::inv(CASE_BIP); EmitCode::down(); EmitCode::val_number((inter_ti) Str::get_at(dm->text, c)); EmitCode::code(); EmitCode::down(); EmitCode::inv(RETURN_BIP); EmitCode::down(); EmitCode::val_number((inter_ti) c); EmitCode::up(); EmitCode::up(); EmitCode::up(); } EmitCode::up(); EmitCode::up(); EmitCode::inv(RETURN_BIP); EmitCode::down(); EmitCode::val_number((inter_ti) -1); EmitCode::up();
- This code is used in §7.