diff options
Diffstat (limited to 'source/luametatex/source/tex/texmaincontrol.c')
-rw-r--r-- | source/luametatex/source/tex/texmaincontrol.c | 256 |
1 files changed, 194 insertions, 62 deletions
diff --git a/source/luametatex/source/tex/texmaincontrol.c b/source/luametatex/source/tex/texmaincontrol.c index dbb52ab15..aa160968e 100644 --- a/source/luametatex/source/tex/texmaincontrol.c +++ b/source/luametatex/source/tex/texmaincontrol.c @@ -2487,7 +2487,7 @@ static void tex_aux_extra_right_brace_error(void) inline static void tex_aux_finish_hbox(void) { tex_aux_fixup_directions_only(); - tex_package(hpack_code); + tex_package(hbox_code); } inline static void tex_aux_finish_adjusted_hbox(void) @@ -2496,14 +2496,14 @@ inline static void tex_aux_finish_adjusted_hbox(void) lmt_packaging_state.pre_adjust_tail = pre_adjust_head; lmt_packaging_state.post_migrate_tail = post_migrate_head; lmt_packaging_state.pre_migrate_tail = pre_migrate_head; - tex_package(hpack_code); + tex_package(hbox_code); } inline static void tex_aux_finish_vbox(void) { if (! tex_wrapped_up_paragraph(vbox_par_context)) { tex_end_paragraph(vbox_group, vbox_par_context); - tex_package(vpack_code); + tex_package(vbox_code); } } @@ -2515,6 +2515,14 @@ inline static void tex_aux_finish_vtop(void) } } +inline static void tex_aux_finish_dbox(void) +{ + if (! tex_wrapped_up_paragraph(dbox_par_context)) { + tex_end_paragraph(dbox_group, dbox_par_context); + tex_package(dbox_code); + } +} + inline static void tex_aux_finish_simple_group(void) { tex_aux_fixup_directions_and_unsave(); @@ -2557,6 +2565,9 @@ static void tex_aux_run_right_brace(void) case vtop_group: tex_aux_finish_vtop(); break; + case dbox_group: + tex_aux_finish_dbox(); + break; case align_group: tex_finish_alignment_group(); break; @@ -3538,40 +3549,71 @@ inline static halfword tex_aux_get_register_value(int level, int optionalequal) } } -static int tex_aux_valid_arithmic(int cmd, int *index, int *level, int *varcmd) +static int tex_aux_valid_arithmic(int cmd, int *index, int *level, int *varcmd, int *simple, int *original) { /*tex So: |\multiply|, |\divide| or |\advance|. */ tex_get_x_token(); *varcmd = cur_cmd; + /* *simple = 0; */ switch (cur_cmd) { case register_int_cmd: case internal_int_cmd: *index = cur_chr; *level = int_val_level; + *original = eq_value(*index); return 1; case register_attribute_cmd: case internal_attribute_cmd: *index = cur_chr; *level = attr_val_level; + *original = eq_value(*index); return 1; case register_dimen_cmd: case internal_dimen_cmd: *index = cur_chr; *level = dimen_val_level; + *original = eq_value(*index); return 1; case register_glue_cmd: case internal_glue_cmd: *index = cur_chr; *level = glue_val_level; + *original = eq_value(*index); return 1; case register_mu_glue_cmd: case internal_mu_glue_cmd: *index = cur_chr; *level = mu_val_level; + *original = eq_value(*index); return 1; case register_cmd: - *level = cur_chr; *index = tex_aux_get_register_index(*level); + *level = cur_chr; + *original = eq_value(*index); + return 1; + case integer_cmd: + *index = cur_cs; + *level = int_val_level; + *original = cur_chr; + *simple = integer_cmd; + return 1; + case dimension_cmd: + *index = cur_cs; + *level = dimen_val_level; + *original = cur_chr; + *simple = dimension_cmd; + return 1; + case gluespec_cmd: + *index = cur_cs; + *level = glue_val_level; + *original = cur_chr; + *simple = gluespec_cmd; + return 1; + case mugluespec_cmd: + *index = cur_cs; + *level = mu_val_level; + *original = cur_chr; + *simple = mugluespec_cmd; return 1; default: tex_handle_error( @@ -3635,7 +3677,7 @@ inline static void tex_aux_update_register(int a, int level, halfword index, hal } } -static void tex_aux_set_register(int a) +inline static void tex_aux_set_register(int a) { halfword level = cur_chr; halfword varcmd = cur_cmd; @@ -3644,51 +3686,60 @@ static void tex_aux_set_register(int a) tex_aux_update_register(a, level, index, value, varcmd); } +/*tex + The by-less variant is more efficient as there is no push back of the token when there is not + such keyword. It goes unnoticed on an average run but not on the total runtime of 15.000 + (times 2) runs of a 30 page \CONTEXT\ document with plenty of complex tables. So this is one + of the few obscure optimizations I grand myself (if only to be able to discuss it). +*/ + static void tex_aux_arithmic_register(int a, int code) { halfword cmd = cur_cmd; halfword level = cur_chr; halfword index = 0; halfword varcmd = 0; - if (tex_aux_valid_arithmic(cmd, &index, &level, &varcmd)) { + halfword simple = 0; + halfword original = 0; + if (tex_aux_valid_arithmic(cmd, &index, &level, &varcmd, &simple, &original)) { halfword value = null; - tex_scan_optional_keyword("by"); lmt_scanner_state.arithmic_error = 0; switch (code) { case advance_code: + tex_scan_optional_keyword("by"); + case advance_by_code: { value = tex_aux_get_register_value(level, 0); switch (level) { case int_val_level: case attr_val_level: case dimen_val_level: - value += eq_value(index); + value += original; break; case glue_val_level: case mu_val_level: { /* Compute the sum of two glue specs */ - halfword oldvalue = eq_value(index); halfword newvalue = tex_new_glue_spec_node(value); tex_flush_node(value); - glue_amount(newvalue) += glue_amount(oldvalue); + glue_amount(newvalue) += glue_amount(original); if (glue_stretch(newvalue) == 0) { glue_stretch_order(newvalue) = normal_glue_order; } - if (glue_stretch_order(newvalue) == glue_stretch_order(oldvalue)) { - glue_stretch(newvalue) += glue_stretch(oldvalue); - } else if ((glue_stretch_order(newvalue) < glue_stretch_order(oldvalue)) && (glue_stretch(oldvalue))) { - glue_stretch(newvalue) = glue_stretch(oldvalue); - glue_stretch_order(newvalue) = glue_stretch_order(oldvalue); + if (glue_stretch_order(newvalue) == glue_stretch_order(original)) { + glue_stretch(newvalue) += glue_stretch(original); + } else if ((glue_stretch_order(newvalue) < glue_stretch_order(original)) && (glue_stretch(original))) { + glue_stretch(newvalue) = glue_stretch(original); + glue_stretch_order(newvalue) = glue_stretch_order(original); } if (glue_shrink(newvalue) == 0) { glue_shrink_order(newvalue) = normal_glue_order; } - if (glue_shrink_order(newvalue) == glue_shrink_order(oldvalue)) { - glue_shrink(newvalue) += glue_shrink(oldvalue); - } else if ((glue_shrink_order(newvalue) < glue_shrink_order(oldvalue)) && (glue_shrink(oldvalue))) { - glue_shrink(newvalue) = glue_shrink(oldvalue); - glue_shrink_order(newvalue) = glue_shrink_order(oldvalue); + if (glue_shrink_order(newvalue) == glue_shrink_order(original)) { + glue_shrink(newvalue) += glue_shrink(original); + } else if ((glue_shrink_order(newvalue) < glue_shrink_order(original)) && (glue_shrink(original))) { + glue_shrink(newvalue) = glue_shrink(original); + glue_shrink_order(newvalue) = glue_shrink_order(original); } value = newvalue; break; @@ -3698,29 +3749,34 @@ static void tex_aux_arithmic_register(int a, int code) break; } /*tex There is no overflow detection for addition, just wraparound. */ - tex_aux_update_register(a, level, index, value, varcmd); + if (simple) { + tex_define(a, index, simple, value); + } else { + tex_aux_update_register(a, level, index, value, varcmd); + } break; } case multiply_code: + tex_scan_optional_keyword("by"); + case multiply_by_code: { halfword amount = tex_scan_int(0, NULL); switch (level) { case int_val_level: case attr_val_level: - value = tex_multiply_integers(eq_value(index), amount); + value = tex_multiply_integers(original, amount); break; case dimen_val_level: - value = tex_nx_plus_y(eq_value(index), amount, 0); + value = tex_nx_plus_y(original, amount, 0); break; case glue_val_level: case mu_val_level: { - halfword s = eq_value(index); - halfword r = tex_new_glue_spec_node(s); - glue_amount(r) = tex_nx_plus_y(glue_amount(s), amount, 0); - glue_stretch(r) = tex_nx_plus_y(glue_stretch(s), amount, 0); - glue_shrink(r) = tex_nx_plus_y(glue_shrink(s), amount, 0); - value = r; + halfword newvalue = tex_new_glue_spec_node(original); + glue_amount(newvalue) = tex_nx_plus_y(glue_amount(original), amount, 0); + glue_stretch(newvalue) = tex_nx_plus_y(glue_stretch(original), amount, 0); + glue_shrink(newvalue) = tex_nx_plus_y(glue_shrink(original), amount, 0); + value = newvalue; break; } default: @@ -3729,29 +3785,32 @@ static void tex_aux_arithmic_register(int a, int code) } if (lmt_scanner_state.arithmic_error) { tex_aux_arithmic_overflow_error(level, value); + } else if (simple) { + tex_define(a, index, simple, value); } else { tex_aux_update_register(a, level, index, value, varcmd); } break; } case divide_code: + tex_scan_optional_keyword("by"); + case divide_by_code: { halfword amount = tex_scan_int(0, NULL); switch (level) { case int_val_level: case attr_val_level: case dimen_val_level: - value = tex_x_over_n(eq_value(index), amount); + value = tex_x_over_n(original, amount); break; case glue_val_level: case mu_val_level: { - halfword s = eq_value(index); - halfword r = tex_new_glue_spec_node(s); - glue_amount(r) = tex_x_over_n(glue_amount(s), amount); - glue_stretch(r) = tex_x_over_n(glue_stretch(s), amount); - glue_shrink(r) = tex_x_over_n(glue_shrink(s), amount); - value = r; + halfword newvalue = tex_new_glue_spec_node(original); + glue_amount(newvalue) = tex_x_over_n(glue_amount(original), amount); + glue_stretch(newvalue) = tex_x_over_n(glue_stretch(original), amount); + glue_shrink(newvalue) = tex_x_over_n(glue_shrink(original), amount); + value = newvalue; break; } default: @@ -3760,11 +3819,31 @@ static void tex_aux_arithmic_register(int a, int code) } if (lmt_scanner_state.arithmic_error) { tex_aux_arithmic_overflow_error(level, value); + } else if (simple) { + tex_define(a, index, simple, value); } else { tex_aux_update_register(a, level, index, value, varcmd); } break; } + /* + case advance_by_plus_one_code: + case advance_by_minus_one_code: + { + switch (level) { + case int_val_level: + case attr_val_level: + original += code == advance_by_plus_one_code ? 1 : -1; + if (simple) { + tex_define(a, index, simple, original); + } else { + tex_aux_update_register(a, level, index, original, varcmd); + } + break; + } + break; + } + */ } } } @@ -4171,8 +4250,20 @@ static void tex_aux_set_box(int a) static void tex_aux_set_shorthand_def(int a, int force) { halfword code = cur_chr; + /* + switch (code) { + case integer_def_csname_code: + case dimension_def_csname_code: + cur_cs = tex_create_csname(); + break; + default: + tex_get_r_token(); + break; + } + */ tex_get_r_token(); if (force || tex_define_permitted(cur_cs, a)) { + /* can we optimize the dual define, like no need to destroy in second call */ halfword p = cur_cs; tex_define(a, p, relax_cmd, relax_code); tex_scan_optional_equals(); @@ -4180,92 +4271,94 @@ static void tex_aux_set_shorthand_def(int a, int force) case char_def_code: { halfword chr = tex_scan_char_number(0); /* maybe 1 */ - tex_define(a, p, char_given_cmd, chr); + tex_define_again(a, p, char_given_cmd, chr); break; } case math_char_def_code: { mathcodeval mval = tex_scan_mathchar(tex_mathcode); - tex_define(a, p, mathspec_cmd, tex_new_math_spec(mval, tex_mathcode)); + tex_define_again(a, p, mathspec_cmd, tex_new_math_spec(mval, tex_mathcode)); break; } case math_dchar_def_code: { mathdictval dval = tex_scan_mathdict(); mathcodeval mval = tex_scan_mathchar(umath_mathcode); - tex_define(a, p, mathspec_cmd, tex_new_math_dict_spec(dval, mval, umath_mathcode)); + tex_define_again(a, p, mathspec_cmd, tex_new_math_dict_spec(dval, mval, umath_mathcode)); break; } case math_xchar_def_code: { mathcodeval mval = tex_scan_mathchar(umath_mathcode); - tex_define(a, p, mathspec_cmd, tex_new_math_spec(mval, umath_mathcode)); + tex_define_again(a, p, mathspec_cmd, tex_new_math_spec(mval, umath_mathcode)); break; } case count_def_code: { halfword n = tex_scan_int_register_number(); - tex_define(a, p, register_int_cmd, register_int_location(n)); + tex_define_again(a, p, register_int_cmd, register_int_location(n)); break; } case attribute_def_code: { halfword n = tex_scan_attribute_register_number(); - tex_define(a, p, register_attribute_cmd, register_attribute_location(n)); + tex_define_again(a, p, register_attribute_cmd, register_attribute_location(n)); break; } case dimen_def_code: { scaled n = tex_scan_dimen_register_number(); - tex_define(a, p, register_dimen_cmd, register_dimen_location(n)); + tex_define_again(a, p, register_dimen_cmd, register_dimen_location(n)); break; } case skip_def_code: { halfword n = tex_scan_glue_register_number(); - tex_define(a, p, register_glue_cmd, register_glue_location(n)); + tex_define_again(a, p, register_glue_cmd, register_glue_location(n)); break; } case mu_skip_def_code: { halfword n = tex_scan_mu_glue_register_number(); - tex_define(a, p, register_mu_glue_cmd, register_mu_glue_location(n)); + tex_define_again(a, p, register_mu_glue_cmd, register_mu_glue_location(n)); break; } case toks_def_code: { halfword n = tex_scan_toks_register_number(); - tex_define(a, p, register_toks_cmd, register_toks_location(n)); + tex_define_again(a, p, register_toks_cmd, register_toks_location(n)); break; } case lua_def_code: { halfword v = tex_scan_function_reference(1); - tex_define(a, p, is_protected(a) ? lua_protected_call_cmd : lua_call_cmd, v); + tex_define_again(a, p, is_protected(a) ? lua_protected_call_cmd : lua_call_cmd, v); } break; case integer_def_code: + /* case integer_def_csname_code: */ { halfword v = tex_scan_int(1, NULL); - tex_define(a, p, integer_cmd, v); + tex_define_again(a, p, integer_cmd, v); } break; case dimension_def_code: + /* case dimension_def_csname_code: */ { scaled v = tex_scan_dimen(0, 0, 0, 1, NULL); - tex_define(a, p, dimension_cmd, v); + tex_define_again(a, p, dimension_cmd, v); } break; case gluespec_def_code: { halfword v = tex_scan_glue(glue_val_level, 1); - tex_define(a, p, gluespec_cmd, v); + tex_define_again(a, p, gluespec_cmd, v); } break; case mugluespec_def_code: { halfword v = tex_scan_glue(mu_val_level, 1); - tex_define(a, p, mugluespec_cmd, v); + tex_define_again(a, p, mugluespec_cmd, v); } break; /* @@ -4677,13 +4770,13 @@ static void tex_aux_set_let(int a, int force) a = add_global_flag(a); } if (force || tex_define_permitted(cur_cs, a)) { - /*tex - The commented line permits plenty empty definitions, a |\let| can run out of - ref count so maybe some day \unknown - */ + // /*tex + // The commented line permits plenty empty definitions, a |\let| can run out of + // ref count so maybe some day \unknown + // */ // halfword empty = get_reference_token(); - halfword empty = lmt_token_state.empty; // tex_add_token_reference(empty); + halfword empty = lmt_token_state.empty; tex_define(a, cur_cs, tex_flags_to_cmd(a), empty); } return; @@ -4704,6 +4797,10 @@ static void tex_aux_set_let(int a, int force) singleword newf = 0; singleword cmd = (singleword) cur_cmd; if (is_aliased(a)) { + /*tex + Aliases only work for non constants: else make a |\def| of it or we need some + pointer to the original but as the meaning can change. Too tricky. + */ newf = oldf; } else { oldf = remove_overload_flags(oldf); @@ -5393,6 +5490,36 @@ static int tex_aux_set_some_item(halfword a) } } +static void tex_aux_set_constant_register(halfword cmd, halfword cs, halfword flags) +{ + switch(cmd) { + case integer_cmd: + { + halfword v = tex_scan_int(1, NULL); + tex_define(flags, cs, integer_cmd, v); + } + break; + case dimension_cmd: + { + scaled v = tex_scan_dimen(0, 0, 0, 1, NULL); + tex_define(flags, cs, dimension_cmd, v); + } + break; + case gluespec_cmd: + { + halfword v = tex_scan_glue(glue_val_level, 1); + tex_define(flags, cs, gluespec_cmd, v); + } + break; + case mugluespec_cmd: + { + halfword v = tex_scan_glue(mu_val_level, 1); + tex_define(flags, cs, mugluespec_cmd, v); + } + break; + } +} + void tex_run_prefixed_command(void) { /*tex accumulated prefix codes so far */ @@ -5550,6 +5677,12 @@ void tex_run_prefixed_command(void) tex_aux_run_illegal_case(); } break; + case integer_cmd: + case dimension_cmd: + case gluespec_cmd: + case mugluespec_cmd: + tex_aux_set_constant_register(cur_cmd, cur_cs, flags); + break; default: if (lastprefix < 0) { tex_confusion("prefixed command"); @@ -6340,11 +6473,10 @@ inline static void tex_aux_big_switch(int mode, int cmd) register_simple(set_specification_cmd, tex_run_prefixed_command); register_simple(shorthand_def_cmd, tex_run_prefixed_command); register_simple(lua_value_cmd, tex_run_prefixed_command); - - register_simple(integer_cmd, tex_aux_run_illegal_case); /*tex This is better than |run_relax|. */ - register_simple(dimension_cmd, tex_aux_run_illegal_case); /*tex This is better than |run_relax|. */ - register_simple(gluespec_cmd, tex_aux_run_illegal_case); /*tex This is better than |run_relax|. */ - register_simple(mugluespec_cmd, tex_aux_run_illegal_case); /*tex This is better than |run_relax|. */ + register_simple(integer_cmd, tex_run_prefixed_command); + register_simple(dimension_cmd, tex_run_prefixed_command); + register_simple(gluespec_cmd, tex_run_prefixed_command); + register_simple(mugluespec_cmd, tex_run_prefixed_command); register_simple(fontspec_cmd, tex_run_font_spec); |