diff options
Diffstat (limited to 'source/luametatex/source/tex/texequivalents.h')
-rw-r--r-- | source/luametatex/source/tex/texequivalents.h | 1776 |
1 files changed, 1776 insertions, 0 deletions
diff --git a/source/luametatex/source/tex/texequivalents.h b/source/luametatex/source/tex/texequivalents.h new file mode 100644 index 000000000..aaf45d0c1 --- /dev/null +++ b/source/luametatex/source/tex/texequivalents.h @@ -0,0 +1,1776 @@ +/* + See license.txt in the root of this project. +*/ + +# ifndef LMT_EQUIVALENTS_H +# define LMT_EQUIVALENTS_H + +# include "tex/textypes.h" + +/*tex + + Like the preceding parameters, the following quantities can be changed at compile time to extend + or reduce \TEX's capacity. But if they are changed, it is necessary to rerun the initialization + program |INITEX| to generate new tables for the production \TEX\ program. One can't simply make + helter-skelter changes to the following constants, since certain rather complex initialization + numbers are computed from them. They are defined here using \WEB\ macros, instead of being put + into \PASCAL's |const| list, in order to emphasize this distinction. + + The original token interface at the \LUA\ end used the \quote {real} chr values that are offsets + into the table of equivalents. However, that is sort of fragile when one also provides ways to + construct tokens. For that reason the \LUAMETATEX\ interface is a bit more abstract and therefore + can do some testing. After all, the real numbers don't matter. This means that registers for + instance run from |0..65535| (without the region offsets). + + In order to make this easier the token registers are now more consistent with the other registers + in the sense that there is no longer a special cmd for those registers. This was not that hard to + do because most code already was sort of prepared for that move. + + Now, there is one \quote {complication}: integers, dimensions etc references can be registers but + also internal variables. This means that we cannot simply remap the eq slots they refer to. When + we offset by some base (the first register) we end up with negative indices for the internal ones + because they come before this 64K range. So, this is why the \LUA\ interface works with negative + numbers for internal variables. + + Another side effect is that we now have the mu glue internals in the muglue region. This is + possible because we have separated the subtypes from the chr codes. I might also relocate the + special things (like penalties) some day. + + In a couple of cases a specific chr was used that made it possible to share for instance setters. + Examples are |\mkern| and |\mskip|. This resulted is (sort of) funny single numbers in the token + interface, so we have that now normalized as well (at the cost of a few split functions). Of course + that doesn't change the concept, unless one considers the fact that we have more granularity in + node subtypes (no longer parallel to the codes, as there are more) an issue. (Actually we can now + easily introduce hkern and vkern if we want.) + +*/ + +/*tex + + Each entry in |eqtb| is a |memoryword|. Most of these words are of type |two_halves|, and + subdivided into three fields: + + \startitemize + + \startitem + The |eq_level| (a quarterword) is the level of grouping at which this equivalent was + defined. If the level is |level_zero|, the equivalent has never been defined; + |level_one| refers to the outer level (outside of all groups), and this level is also + used for global definitions that never go away. Higher levels are for equivalents that + will disappear at the end of their group. + \stopitem + + \startitem + The |eq_type| (another quarterword) specifies what kind of entry this is. There are many + types, since each \TEX\ primitive like |\hbox|, |\def|, etc., has its own special code. + The list of command codes above includes all possible settings of the |eq_type| field. + \stopitem + + \startitem + The |equiv| (a halfword) is the current equivalent value. This may be a font number, a + pointer into |mem|, or a variety of other things. + \stopitem + + \stopitemize + + Many locations in |eqtb| have symbolic names. The purpose of the next paragraphs is to define + these names, and to set up the initial values of the equivalents. + + In the first region we have a single entry for the \quote {null csname} of length zero. In + \LUATEX, the active characters and and single-letter control sequence names are part of the + next region. + + Then comes region 2, which corresponds to the hash table that we will define later. The maximum + address in this region is used for a dummy control sequence that is perpetually undefined. + There also are several locations for control sequences that are perpetually defined (since they + are used in error recovery). + + Region 3 of |eqtb| contains the |number_regs| |\skip| registers, as well as the glue parameters + defined here. It is important that the \quote {muskip} parameters have larger numbers than the + others. + + Region 4 of |eqtb| contains the local quantities defined here. The bulk of this region is taken + up by five tables that are indexed by eight-bit characters; these tables are important to both + the syntactic and semantic portions of \TEX. There are also a bunch of special things like font + and token parameters, as well as the tables of |\toks| and |\box| registers. + + Region 5 of |eqtb| contains the integer parameters and registers defined here, as well as the + |del_code| table. The latter table differs from the |cat_code..math_code| tables that precede it, + since delimiter codes are fullword integers while the other kinds of codes occupy at most a + halfword. This is what makes region~5 different from region~4. We will store the |eq_level| + information in an auxiliary array of quarterwords that will be defined later. + + The integer parameters should really be initialized by a macro package; the following + initialization does the minimum to keep \TEX\ from complete failure. + + The final region of |eqtb| contains the dimension parameters defined here, and the |number_regs| + |\dimen| registers. + + Beware: in \LUATEX\ we have so many characters (\UNICODE) that we use a dedicated hash system + for special codes, math properties etc. This means that we have less in the regions than mentioned + here. On the other hand, we do have more registers (attributes) so that makes it a bit larger again. + + The registers get marked as being \quote {undefined} commands. We could actually gove them a the + right commmand code etc.\ bur for now we just use the ranges as traditional \TEX\ does. + + Most of the symbolic names and hard codes numbers are not enumerations. There is still room for + improvement and occasionally I enter a new round of doing that. However, it talkes a lot of time + and checking (more than writing from scratch) as we need to make sure it all behaves like \TEX\ + does. Quite some code went through several stages of reaching this abstraction, just to make sure + that it kept working. These intermediate versions ended up in the \CONTEXT\ distribution to that + any issue would show up soon. A rather major step was splitting the |assign_*_cmd|s into + internal and register commands and ranges. This was a side effect of getting the token interface + at the \LUA\ end a bit nicer; there is really no need to expose the user to codes that demand + catching up with the \TEX\ internals when we can just provide a nice interface. + + The font location is kind of special as it holds a halfword data field that points to a font + accessor and as such doesn't fit into a counter concept. Otherwise we could have made it a + counter. We could probably just use a font id and do a lookup elsewhere because this engine is + already doing it differently. So, eventually this needs checking. + +*/ + +/* + For practical reasons we have the regions a bit different. For instance, we also have attributes, local + boxes, no math characters here, etc. Maybe specification codes sould get their own region. + + HASH FROZEN + [I|R]FONTS + UNDEFINED + [I|R]GLUE + [I|R]MUGLUE + [I|R]TOKS + [I|R]BOXES + [I|R]INT + [I|R]ATTR + [I|R]DIMEN + SPECIFICATIONS + EQUIVPLUS + + When I'd done a bit of clean up and abstraction (actually it took quite some time because the only + reliable way to do it is stepwise with lots of testing) I wondered why there is a difference in + the way the level is kept track of. For those entries that store a value directly, a separate + |xeq_level| array is used. So, after \quote {following the code}, taking a look at the original + implementation, and a walk, I came to the conclusion that because \LUATEX\ uses 64 memory words, + we actually don't need that parallel array: we have plenty of room and, the level fields are not + shared. In traditional \TEX\ we have a memory word with two faces: + + [level] [type] + [ value ] + + but in \LUATEX\ it's wider. There is no overlap. + + [level] [type] [value] + + So, we can get rid of that extra array. Actually, in the \PASCAL\ source we see that this + parallel array is smaller because it only covers the value ranges (the first index starts at + the start of the first relevant register range). Keep in mind that the middle part of the hash + is registers and when we have a frozen hash size, that part is not present which is why there + was that parallel array needed; a side effect of the |extra_hash| extension. + + Another side effect of this simplification is that we can store and use the type which can be + handy too. + + For the changes, look for |xeq simplification| comments in the files and for the cleaned up + precursor in the archives of luametatex (in case there is doubt). When the save stack was made + more efficient the old commented |xeq| code has been removed. + + ----------------------------------- + null control sequence + hash entries (hash_size) + multiple frozen control sequences + special sequences (font, undefined) + ----------------------------------- + glue registers + mu glue registers + token registers + box registers + integer registers + attribute registers + dimension registers + specifications + ---------- eqtb size -------------- + extra hash entries + ----------------------------------- + + eqtb_top = eqtb_size + hash_extra + hash_top = hash_extra == 0 ? undefined_control_sequence : eqtb_top; + + There used to be a large font area but I moved that to the font record so that we don't waste + space (it saves some 500K on the format file and plenty of memory). + + Todo: split the eqtb and make the register arrays dynamic. We need to change the save/restore + code then and it might have a slight impact on performance (checking what table to use). + +*/ + +/*tex + Maybe we should multiply the following by 2 but there is no real gain. Many entries end up in the extended + area anyway. + + \starttyping + # define hash_size 65536 + # define hash_prime 55711 + \stoptyping + + Here |hash_size| is the maximum number of control sequences; it should be at most about + |(fix_mem_max - fix_mem_min)/10|. The value of |hash_prime| is a prime number equal to about + 85 percent of |hash_size|. + + The hash runs in parallel to the eqtb and a large hash table makes for many holes and that + compresses badly. For instance: + + 590023 => down to 1024 * 512 == 524288 ==> 85% = 445644 => prime 445633/445649 + + will make a much larger format and we gain nothing. Actually, because we have extra hash + anyway, this whole 85\% criterium is irrelevant: we only need to make sure that we have + enough room for the frozen sequences (assuming we stay within the concept). + + primes: + + \starttyping + 65447 65449 65479 65497 65519 65521 => 65536 (85% == 55711) + 131009 131011 131023 131041 131059 131063 => 131072 (85% == 111409) + \stoptyping + + lookups: + + \starttyping + n=131040 cs=46426 indirect= 9173 + n= 65496 cs=46426 indirect=14512 + \stoptyping + +*/ + +// # define hash_size 65536 +// # define hash_prime 65497 + +# define hash_size 131072 /*tex 128K */ +# define hash_prime 131041 /*tex Plenty of room for the frozen. */ + +# define null_cs 1 /*tex equivalent of |\csname\| |\endcsname| */ +# define hash_base (null_cs + 1) /*tex beginning of region 2, for the hash table */ +# define frozen_control_sequence (hash_base + hash_size) /*tex for error recovery */ + +typedef enum deep_frozen_cs_codes { + deep_frozen_cs_protection_code = frozen_control_sequence, /*tex inaccessible but definable */ + deep_frozen_cs_cr_code, /*tex permanent |\cr| */ + deep_frozen_cs_end_group_code, /*tex permanent |\endgroup| */ + deep_frozen_cs_right_code, /*tex permanent |\right| */ + deep_frozen_cs_fi_code, /*tex permanent |\fi| */ + deep_frozen_cs_no_if_code, /*tex hidden |\noif| */ + deep_frozen_cs_always_code, /*tex hidden internalized |\enforces| */ + deep_frozen_cs_end_template_1_code, /*tex permanent |\endtemplate| */ + deep_frozen_cs_end_template_2_code, /*tex second permanent |\endtemplate| */ + deep_frozen_cs_relax_code, /*tex permanent |\relax| */ + deep_frozen_cs_end_write_code, /*tex permanent |\endwrite| */ + deep_frozen_cs_dont_expand_code, /*tex permanent |\notexpanded:| */ + deep_frozen_cs_null_font_code, /*tex permanent |\nullfont| */ + deep_frozen_cs_undefined_code, +} deep_frozen_cs_codes; + +# define first_deep_frozen_cs_location deep_frozen_cs_protection_code +# define last_deep_frozen_cs_location deep_frozen_cs_undefined_code + +typedef enum glue_codes { + line_skip_code, /*tex interline glue if |baseline_skip| is infeasible */ + baseline_skip_code, /*tex desired glue between baselines */ + par_skip_code, /*tex extra glue just above a paragraph */ + above_display_skip_code, /*tex extra glue just above displayed math */ + below_display_skip_code, /*tex extra glue just below displayed math */ + above_display_short_skip_code, /*tex glue above displayed math following short lines */ + below_display_short_skip_code, /*tex glue below displayed math following short lines */ + left_skip_code, /*tex glue at left of justified lines */ + right_skip_code, /*tex glue at right of justified lines */ + top_skip_code, /*tex glue at top of main pages */ + split_top_skip_code, /*tex glue at top of split pages */ + tab_skip_code, /*tex glue between aligned entries */ + space_skip_code, /*tex glue between words (if not |zero_glue|) */ + xspace_skip_code, /*tex glue after sentences (if not |zero_glue|) */ + par_fill_left_skip_code, /*tex glue at the start of the last line of paragraph */ + par_fill_right_skip_code, /*tex glue on last line of paragraph */ + par_init_left_skip_code, + par_init_right_skip_code, + /* indent_skip_code, */ /*tex internal, might go away here */ + /* left_hang_skip_code, */ /*tex internal, might go away here */ + /* right_hang_skip_code, */ /*tex internal, might go away here */ + /* correction_skip_code, */ /*tex internal, might go away here */ + /* inter_math_skip_code, */ /*tex internal, might go away here */ + math_skip_code, /*tex glue before and after inline math */ + math_threshold_code, + /*tex total number of glue parameters */ + number_glue_pars, +} glue_codes; + +# define first_glue_code line_skip_code +# define last_glue_code math_threshold_code + +/*tex + + In addition to the three original predefined muskip registers we have two more. These muskips + are used in a symbolic way: by using a reference we can change their values on the fly and the + engine will pick up the value set at the end of the formula (and use it in the second pass). + In the other engines the threesome are hard coded into the atom pair spacing. + + In \LUAMETATEX\ we have a configurable system so these three registers are only used in the + initialization, can be overloaded in the macro package, and are saved in the format file (as + any other register). But there can be more than these. Before we had a way to link spacing to + arbitrary registers (in the user's register space) we added |\tinymuskip| because we needed it. + It is not used in initializations in the engine but is applied in the \CONTEXT\ format. We + could throw it out and use just a user register now but we consider it part of the (updated) + concept so it will stick around. Even more: we decided that a smaller one makes sense so end + June 2022 Mikael and I decided to also provide |\pettymuskip| for which Mikael saw a good use + case in the spacing in scripts between ordinary symbols and binary as well as relational ones. + + The Cambridge dictionary describes \quote {petty} as \quotation {not important and not worth + giving attention to}, but of course we do! It's just that till not we never saw any request + for an upgrade of the math (sub) engine, let alone that \TEX\ users bothered about the tiny + and petty spacing artifacts (and posibilities) of the engine. Both internal registers are + dedicated to Don Knuth who {\em does} pay a lot attentions to details but who of course will + not use this engine and thereby not spoiled. So, they are there and at the same time they + are not. But: in \CONTEXT\ they {\em are} definitely used! + +*/ + +typedef enum mu_glue_codes { + zero_mu_skip_code, + petty_mu_skip_code, /*tex petty space in math formula */ + tiny_mu_skip_code, /*tex tiny space in math formula */ + thin_mu_skip_code, /*tex thin space in math formula */ + med_mu_skip_code, /*tex medium space in math formula */ + thick_mu_skip_code, /*tex thick space in math formula */ + /*tex total number of mu glue parameters */ + number_mu_glue_pars, +} mu_glue_codes; + +# define first_mu_glue_code petty_mu_skip_code +# define last_mu_glue_code thick_mu_skip_code + +typedef enum tok_codes { + output_routine_code, /*tex points to token list for |\output| */ + every_par_code, /*tex points to token list for |\everypar| */ + every_math_code, /*tex points to token list for |\everymath| */ + every_display_code, /*tex points to token list for |\everydisplay| */ + every_hbox_code, /*tex points to token list for |\everyhbox| */ + every_vbox_code, /*tex points to token list for |\everyvbox| */ + every_math_atom_code, /*tex points to token list for |\everymathatom| */ + every_job_code, /*tex points to token list for |\everyjob|*/ + every_cr_code, /*tex points to token list for |\everycr| */ + every_tab_code, /*tex points to token list for |\everytab| */ + error_help_code, /*tex points to token list for |\errhelp|*/ + every_before_par_code, /*tex points to token list for |\everybeforepar| */ + every_eof_code, /*tex points to token list for |\everyeof| */ + end_of_group_code, /*tex collects end-of-group tokens, internal register */ + // end_of_par_code, + /*tex total number of token parameters */ + number_tok_pars, +} tok_codes; + +# define first_toks_code output_routine_code +# define last_toks_code every_eof_code + +typedef enum specification_codes { + par_shape_code, /*tex specifies paragraph shape, internal register */ + inter_line_penalties_code, /*tex additional penalties between lines */ + club_penalties_code, /*tex penalties for creating club lines */ + widow_penalties_code, /*tex penalties for creating widow lines */ + display_widow_penalties_code, /*tex ditto, just before a display */ + orphan_penalties_code, + math_forward_penalties_code, + math_backward_penalties_code, + number_specification_pars, +} specification_codes; + +# define first_specification_code par_shape_code +# define last_specification_code math_backward_penalties_code + +/*tex Beware: these are indices into |page_builder_state.page_so_far| array! */ + +typedef enum page_property_codes { + page_goal_code, + page_vsize_code, + page_total_code, + page_depth_code, + dead_cycles_code, + insert_penalties_code, + insert_heights_code, + insert_storing_code, /* page */ + insert_distance_code, + insert_multiplier_code, + insert_limit_code, + insert_storage_code, /* per insert */ + insert_penalty_code, + insert_maxdepth_code, + insert_height_code, + insert_depth_code, + insert_width_code, + page_stretch_code, + page_filstretch_code, + page_fillstretch_code, + page_filllstretch_code, + page_shrink_code, +} page_property_codes; + +# define first_page_property_code page_goal_code +# define last_page_property_code insert_width_code + +/*tex + We cheat: these previous bases are to really bases which is why math and del get separated by + one. See usage! Todo: group them better (also elsewhere in switches). +*/ + +typedef enum int_codes { + pre_tolerance_code, /*tex badness tolerance before hyphenation */ + tolerance_code, /*tex badness tolerance after hyphenation */ + line_penalty_code, /*tex added to the badness of every line */ + hyphen_penalty_code, /*tex penalty for break after discretionary hyphen */ + ex_hyphen_penalty_code, /*tex penalty for break after explicit hyphen */ + club_penalty_code, /*tex penalty for creating a club line */ + widow_penalty_code, /*tex penalty for creating a widow line */ + display_widow_penalty_code, /*tex ditto, just before a display */ + broken_penalty_code, /*tex penalty for breaking a page at a broken line */ + post_binary_penalty_code, /*tex penalty for breaking after a binary operation */ + post_relation_penalty_code, /*tex penalty for breaking after a relation */ + pre_display_penalty_code, /*tex penalty for breaking just before a displayed formula */ + post_display_penalty_code, /*tex penalty for breaking just after a displayed formula */ + pre_inline_penalty_code, /*tex penalty for breaking just before an inlined formula */ + post_inline_penalty_code, /*tex penalty for breaking just after an inlined formula */ + inter_line_penalty_code, /*tex additional penalty between lines */ + double_hyphen_demerits_code, /*tex demerits for double hyphen break */ + final_hyphen_demerits_code, /*tex demerits for final hyphen break */ + adj_demerits_code, /*tex demerits for adjacent incompatible lines */ + /* mag_code, */ /*tex magnification ratio */ + delimiter_factor_code, /*tex ratio for variable-size delimiters */ + looseness_code, /*tex change in number of lines for a paragraph */ + time_code, /*tex current time of day */ + day_code, /*tex current day of the month */ + month_code, /*tex current month of the year */ + year_code, /*tex current year of our Lord */ + show_box_breadth_code, /*tex nodes per level in |show_box| */ + show_box_depth_code, /*tex maximum level in |show_box| */ + show_node_details_code, /*tex controls subtype and attribute details */ + hbadness_code, /*tex hboxes exceeding this badness will be shown by |hpack| */ + vbadness_code, /*tex vboxes exceeding this badness will be shown by |vpack| */ + pausing_code, /*tex pause after each line is read from a file */ + tracing_online_code, /*tex show diagnostic output on terminal */ + tracing_macros_code, /*tex show macros as they are being expanded */ + tracing_stats_code, /*tex show memory usage if \TeX\ knows it */ + tracing_paragraphs_code, /*tex show line-break calculations */ + tracing_pages_code, /*tex show page-break calculations */ + tracing_output_code, /*tex show boxes when they are shipped out */ + tracing_lost_chars_code, /*tex show characters that aren't in the font */ + tracing_commands_code, /*tex show command codes at |big_switch| */ + tracing_restores_code, /*tex show equivalents when they are restored */ + tracing_fonts_code, + tracing_assigns_code, /*tex show assignments */ + tracing_groups_code, /*tex show save/restore groups */ + tracing_ifs_code, /*tex show conditionals */ + tracing_math_code, + tracing_levels_code, /*tex show levels when tracing */ + tracing_nesting_code, /*tex show incomplete groups and ifs within files */ + tracing_alignments_code, /*tex show nesting of noalign and preambles */ + tracing_inserts_code, /*tex show some info about insert processing */ + tracing_marks_code, /*tex show state of marks */ + tracing_adjusts_code, /*tex show state of marks */ + tracing_hyphenation_code, /*tex show some info regarding hyphenation */ + tracing_expressions_code, /*tex show some info regarding expressions */ + tracing_nodes_code, /*tex show node numbers too */ + tracing_full_boxes_code, /*tex show [over/under]full boxes in the log */ + tracing_penalties_code, + uc_hyph_code, /*tex hyphenate words beginning with a capital letter */ + output_penalty_code, /*tex penalty found at current page break */ + max_dead_cycles_code, /*tex bound on consecutive dead cycles of output */ + hang_after_code, /*tex hanging indentation changes after this many lines */ + floating_penalty_code, /*tex penalty for insertions heldover after a split */ + global_defs_code, /*tex override |\global| specifications */ + family_code, /*tex current family */ + escape_char_code, /*tex escape character for token output */ + default_hyphen_char_code, /*tex value of |\hyphenchar| when a font is loaded */ + default_skew_char_code, /*tex value of |\skewchar| when a font is loaded */ + end_line_char_code, /*tex character placed at the right end of the buffer */ + new_line_char_code, /*tex character that prints as |print_ln| */ + language_code, /*tex current language */ + font_code, /*tex current font */ + hyphenation_mode_code, + left_hyphen_min_code, /*tex minimum left hyphenation fragment size */ + right_hyphen_min_code, /*tex minimum right hyphenation fragment size */ + holding_inserts_code, /*tex do not remove insertion nodes from |\box255| */ + holding_migrations_code, + error_context_lines_code, /*tex maximum intermediate line pairs shown */ + local_interline_penalty_code, /*tex local |\interlinepenalty| */ + local_broken_penalty_code, /*tex local |\brokenpenalty| */ + disable_spaces_code, + glyph_scale_code, + glyph_x_scale_code, + glyph_y_scale_code, + glyph_data_code, + glyph_state_code, + glyph_script_code, + glyph_options_code, + glyph_text_scale_code, + glyph_script_scale_code, + glyph_scriptscript_scale_code, + /* glue_data_code, */ + cat_code_table_code, + output_box_code, + ex_hyphen_char_code, + adjust_spacing_code, /*tex level of spacing adjusting */ + adjust_spacing_step_code, /*tex level of spacing adjusting step */ + adjust_spacing_stretch_code, /*tex level of spacing adjusting stretch */ + adjust_spacing_shrink_code, /*tex level of spacing adjusting shrink */ + protrude_chars_code, /*tex protrude chars at left/right edge of paragraphs */ + pre_display_direction_code, /*tex text direction preceding a display */ + last_line_fit_code, /*tex adjustment for last line of paragraph */ + saving_vdiscards_code, /*tex save items discarded from vlists */ + saving_hyph_codes_code, /*tex save hyphenation codes for languages */ + math_eqno_gap_step_code, /*tex factor/1000 used for distance between eq and eqno */ + math_display_skip_mode_code, + math_scripts_mode_code, + /* math_script_box_mode_code, */ + /* math_script_char_mode_code, */ + math_limits_mode_code, + math_nolimits_mode_code, + math_rules_mode_code, + math_rules_fam_code, + math_penalties_mode_code, + math_check_fences_mode_code, + /* math_delimiters_mode_code, */ + /* math_fences_mode_code, */ + /* math_rule_thickness_mode_code, */ + math_slack_mode_code, + /* math_flatten_mode_code, */ + math_skip_mode_code, + math_double_script_mode_code, + /* math_control_mode_code, */ + math_font_control_code, + math_display_mode_code, + math_dict_group_code, + math_dict_properties_code, + math_pre_display_gap_factor_code, + pre_binary_penalty_code, + pre_relation_penalty_code, + first_valid_language_code, + automatic_hyphen_penalty_code, + explicit_hyphen_penalty_code, + exception_penalty_code, + copy_lua_input_nodes_code, + auto_migration_mode_code, + normalize_line_mode_code, + normalize_par_mode_code, + math_spacing_mode_code, + math_grouping_mode_code, + math_glue_mode_code, + math_begin_class_code, + math_end_class_code, + math_left_class_code, + math_right_class_code, + sup_mark_mode_code, + par_direction_code, + text_direction_code, + math_direction_code, + line_direction_code, /*tex gets remapped so is no real register */ + overload_mode_code, + auto_paragraph_mode_code, + shaping_penalties_mode_code, + shaping_penalty_code, + orphan_penalty_code, + alignment_cell_source_code, + alignment_wrap_source_code, + /* page_boundary_penalty_code, */ + line_break_criterium_code, + /* those below these are not interfaced via primitives */ + internal_par_state_code, + internal_dir_state_code, + internal_math_style_code, + internal_math_scale_code, + /*tex total number of integer parameters */ + first_math_class_code, + last_math_class_code = first_math_class_code + max_n_of_math_classes, + first_math_atom_code, + last_math_atom_code = first_math_atom_code + max_n_of_math_classes, + first_math_options_code, + last_math_options_code = first_math_options_code + max_n_of_math_classes, + first_math_parent_code, + last_math_parent_code = first_math_parent_code + max_n_of_math_classes, + first_math_pre_penalty_code, + last_math_pre_penalty_code = first_math_pre_penalty_code + max_n_of_math_classes, + first_math_post_penalty_code, + last_math_post_penalty_code = first_math_post_penalty_code + max_n_of_math_classes, + first_math_display_pre_penalty_code, + last_math_display_pre_penalty_code = first_math_display_pre_penalty_code + max_n_of_math_classes, + first_math_display_post_penalty_code, + last_math_display_post_penalty_code = first_math_display_post_penalty_code + max_n_of_math_classes, + first_math_ignore_code, + last_math_ignore_code = first_math_ignore_code + math_parameter_last, + /* */ + number_int_pars, +} int_codes; + +# define first_int_code pre_tolerance_code +# define last_int_code line_break_criterium_code + +typedef enum dimen_codes { + par_indent_code, /*tex indentation of paragraphs */ + math_surround_code, /*tex space around math in text */ + line_skip_limit_code, /*tex threshold for |line_skip| instead of |baseline_skip| */ + hsize_code, /*tex line width in horizontal mode */ + vsize_code, /*tex page height in vertical mode */ + max_depth_code, /*tex maximum depth of boxes on main pages */ + split_max_depth_code, /*tex maximum depth of boxes on split pages */ + box_max_depth_code, /*tex maximum depth of explicit vboxes */ + hfuzz_code, /*tex tolerance for overfull hbox messages */ + vfuzz_code, /*tex tolerance for overfull vbox messages */ + delimiter_shortfall_code, /*tex maximum amount uncovered by variable delimiters */ + null_delimiter_space_code, /*tex blank space in null delimiters */ + script_space_code, /*tex extra space after subscript or superscript */ + pre_display_size_code, /*tex length of text preceding a display */ + display_width_code, /*tex length of line for displayed equation */ + display_indent_code, /*tex indentation of line for displayed equation */ + overfull_rule_code, /*tex width of rule that identifies overfull hboxes */ + hang_indent_code, /*tex amount of hanging indentation */ + /* h_offset_code, */ /*tex amount of horizontal offset when shipping pages out */ + /* v_offset_code, */ /*tex amount of vertical offset when shipping pages out */ + emergency_stretch_code, /*tex reduces badnesses on final pass of line-breaking */ + glyph_x_offset_code, + glyph_y_offset_code, + px_dimen_code, + tab_size_code, + page_extra_goal_code, + /*tex total number of dimension parameters */ + number_dimen_pars, +} dimen_codes; + +# define first_dimen_code par_indent_code +# define last_dimen_code tab_size_code + +typedef enum attribute_codes { + /*tex total number of attribute parameters */ + number_attribute_pars, +} attribute_codes; + +// typedef enum special_sequence_codes { +// // current_font_sequence_code, +// undefined_control_sequence_code, +// n_of_special_sequences, +// } special_sequence_codes; +// +// /* The last one is frozen_null_font. */ +// +// # define special_sequence_base (last_frozen_cs_loc + 1) +// # define current_font_sequence (special_sequence_base + current_font_sequence_code) +// # define undefined_control_sequence (special_sequence_base + undefined_control_sequence_code) +// # define first_register_base (special_sequence_base + n_of_special_sequences) + +# define undefined_control_sequence deep_frozen_cs_undefined_code + +# define special_sequence_base (last_deep_frozen_cs_location + 1) +# define first_register_base (last_deep_frozen_cs_location + 1) + +# define internal_glue_base (first_register_base) +# define register_glue_base (internal_glue_base + number_glue_pars + 1) +# define internal_glue_location(a) (internal_glue_base + (a)) +# define register_glue_location(a) (register_glue_base + (a)) +# define internal_glue_number(a) ((a) - internal_glue_base) +# define register_glue_number(a) ((a) - register_glue_base) + +# define internal_mu_glue_base (register_glue_base + max_n_of_glue_registers) +# define register_mu_glue_base (internal_mu_glue_base + number_mu_glue_pars + 1) +# define internal_mu_glue_location(a) (internal_mu_glue_base + (a)) +# define register_mu_glue_location(a) (register_mu_glue_base + (a)) +# define internal_mu_glue_number(a) ((a) - internal_mu_glue_base) +# define register_mu_glue_number(a) ((a) - register_mu_glue_base) + +# define internal_toks_base (register_mu_glue_base + max_n_of_mu_glue_registers) +# define register_toks_base (internal_toks_base + number_tok_pars + 1) +# define internal_toks_location(a) (internal_toks_base + (a)) +# define register_toks_location(a) (register_toks_base + (a)) +# define internal_toks_number(a) ((a) - internal_toks_base) +# define register_toks_number(a) ((a) - register_toks_base) + +# define internal_box_base (register_toks_base + max_n_of_toks_registers) +# define register_box_base (internal_box_base + number_box_pars + 1) +# define internal_box_location(a) (internal_box_base + (a)) +# define register_box_location(a) (register_box_base + (a)) +# define internal_box_number(a) ((a) - internal_box_base) +# define register_box_number(a) ((a) - register_box_base) + +# define internal_int_base (register_box_base + max_n_of_box_registers) +# define register_int_base (internal_int_base + number_int_pars + 1) +# define internal_int_location(a) (internal_int_base + (a)) +# define register_int_location(a) (register_int_base + (a)) +# define internal_int_number(a) ((a) - internal_int_base) +# define register_int_number(a) ((a) - register_int_base) + +# define internal_attribute_base (register_int_base + max_n_of_int_registers) +# define register_attribute_base (internal_attribute_base + number_attribute_pars + 1) +# define internal_attribute_location(a) (internal_attribute_base + (a)) +# define register_attribute_location(a) (register_attribute_base + (a)) +# define internal_attribute_number(a) ((a) - internal_attribute_base) +# define register_attribute_number(a) ((a) - register_attribute_base) + +# define internal_dimen_base (register_attribute_base + max_n_of_attribute_registers) +# define register_dimen_base (internal_dimen_base + number_dimen_pars + 1) +# define internal_dimen_location(a) (internal_dimen_base + (a)) +# define register_dimen_location(a) (register_dimen_base + (a)) +# define internal_dimen_number(a) ((a) - internal_dimen_base) +# define register_dimen_number(a) ((a) - register_dimen_base) + +# define internal_specification_base (register_dimen_base + max_n_of_dimen_registers) +# define internal_specification_location(a) (internal_specification_base + (a)) +# define internal_specification_number(a) ((a) - internal_specification_base) + +# define eqtb_size (internal_specification_base + number_specification_pars) + +# define eqtb_indirect_range(n) ((n < internal_glue_base) || ((n > eqtb_size) && (n <= lmt_hash_state.hash_data.top))) +# define eqtb_out_of_range(n) ((n >= undefined_control_sequence) && ((n <= eqtb_size) || n > lmt_hash_state.hash_data.top)) +# define eqtb_valid_cs(n) ((n == 0) || (n > lmt_hash_state.hash_data.top) || ((n > frozen_control_sequence) && (n <= eqtb_size))) + +# define character_in_range(i) (i >= 0 && i <= max_character_code) +# define catcode_in_range(i) (i >= 0 && i <= max_category_code) +# define family_in_range(i) (i >= 0 && i <= max_math_family_index) +# define class_in_range(i) (i >= 0 && i <= max_math_class_code) +# define half_in_range(i) (i >= 0 && i <= max_half_value) +# define box_index_in_range(i) (i >= 0 && i <= max_box_index) + +/* These also have funny offsets: */ + +typedef enum align_codes { + tab_mark_code, + span_code, + omit_code, + align_content_code, + no_align_code, + cr_code, + cr_cr_code, +} align_codes; + +/* + typedef struct equivalents_state_info { + } equivalents_state_info ; + + extern equivalents_state_info lmt_equivalents_state; +*/ + +extern void tex_initialize_levels (void); +extern void tex_initialize_equivalents (void); +extern void tex_synchronize_equivalents (void); +extern void tex_initialize_undefined_cs (void); +extern void tex_dump_equivalents_mem (dumpstream f); +extern void tex_undump_equivalents_mem (dumpstream f); + +/*tex + The more low level |_field| shortcuts are used when we (for instance) work with copies, as done + in the save stack entries. In most cases we use the second triplet of shortcuts. We replaced + |equiv(A)| and |equiv_value(A)| by |eq_value(A)}|. +*/ + +# define eq_level_field(A) (A).quart01 +# define eq_full_field(A) (A).quart00 +# define eq_type_field(A) (A).single00 +# define eq_flag_field(A) (A).single01 +# define eq_value_field(A) (A).half1 + +# define eq_level(A) lmt_hash_state.eqtb[(A)].quart01 /*tex level of definition */ +# define eq_full(A) lmt_hash_state.eqtb[(A)].quart00 /*tex command code for equivalent */ +# define eq_type(A) lmt_hash_state.eqtb[(A)].single00 /*tex command code for equivalent */ +# define eq_flag(A) lmt_hash_state.eqtb[(A)].single01 +# define eq_value(A) lmt_hash_state.eqtb[(A)].half1 + +# define set_eq_level(A,B) lmt_hash_state.eqtb[(A)].quart01 = (quarterword) (B) +# define set_eq_type(A,B) lmt_hash_state.eqtb[(A)].single00 = (singleword) (B) +# define set_eq_flag(A,B) lmt_hash_state.eqtb[(A)].single01 = (singleword) (B) +# define set_eq_value(A,B) lmt_hash_state.eqtb[(A)].half1 = (B) + +# define copy_eqtb_entry(target,source) lmt_hash_state.eqtb[target] = lmt_hash_state.eqtb[source] + +# define equal_eqtb_entries(A,B) ( \ + (lmt_hash_state.eqtb[(A)].half0 == lmt_hash_state.eqtb[(B)].half0) \ + && (lmt_hash_state.eqtb[(A)].half1 == lmt_hash_state.eqtb[(B)].half1) \ +) + +/*tex + + Because we operate in 64 bit we padd with a halfword, and because if that we have an extra field. Now, + because we already no longer need the parallel eqtb level table, we can use this field to store the + value alongside which makes that we can turn the dual slot |restore_old_value| and |saved_eqtb| into + one which in turn makes stack usage shrink. The performance gain is probably neglectable. + +*/ + +typedef struct save_record { + quarterword saved_level; + quarterword saved_type; /*tex We need less so we can actually decide to store the offset as check. */ + halfword saved_value; /*tex Started out as padding, is now actually used for value. */ + memoryword saved_word; +} save_record; + +typedef struct save_state_info { + save_record *save_stack; + memory_data save_stack_data; + quarterword current_level; /*tex current nesting level for groups */ + quarterword current_group; /*tex current group type */ + int current_boundary; /*tex where the current level begins */ + int padding; +} save_state_info; + +extern save_state_info lmt_save_state; + +# define cur_level lmt_save_state.current_level +# define cur_group lmt_save_state.current_group +# define cur_boundary lmt_save_state.current_boundary + +/*tex + + We use the notation |saved(k)| to stand for an item that appears in location |save_ptr + k| of + the save stack. + + The level field is also available for other purposes, so maybe we need an alias that is more + generic. + +*/ + +# define save_type(A) lmt_save_state.save_stack[(A)].saved_type /*tex classifies a |save_stack| entry */ +# define save_extra(A) lmt_save_state.save_stack[(A)].saved_level /*tex a more generic alias: to be used */ +# define save_level(A) lmt_save_state.save_stack[(A)].saved_level /*tex saved level for regions 5 and 6, or group code, or ... */ +# define save_value(A) lmt_save_state.save_stack[(A)].saved_value /*tex |eqtb| location or token or |save_stack| location or ... */ +# define save_word(A) lmt_save_state.save_stack[(A)].saved_word /*tex |eqtb| entry */ + +# define saved_valid(A) (lmt_save_state.save_stack_data.ptr + (A) >= 0) +# define saved_type(A) lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_type +# define saved_extra(A) lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_level +# define saved_level(A) lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_level +# define saved_value(A) lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_value +# define saved_word(A) lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_word + +inline void tex_set_saved_record(halfword ptr, quarterword type, quarterword level, halfword value) +{ + saved_type(ptr) = type; + saved_level(ptr) = level; + saved_value(ptr) = value; +} + +# define reserved_save_stack_slots 32 /* was 8 */ + +/*tex + + The rather explicit |save_| items indicate a type. They are sometimes used to lookup a specific + field (when tracing). +*/ + +typedef enum save_types { + restore_old_value, /*tex a value should be restored later */ + restore_zero, /*tex an undefined entry should be restored */ + insert_tokens, + restore_lua, + level_boundary, /*tex the beginning of a group */ + /* */ + saved_line_number, + /* */ + saved_insert_index, + /* */ + saved_discretionary_count, + /* */ + saved_text_direction, + /* */ + saved_equation_number_location, + /* */ + saved_choices_count, + /* */ + saved_fraction_variant, + saved_fraction_auto_style, + saved_fraction_user_style, + saved_operator_variant, + /* */ + saved_attribute_list, + /* */ + saved_math_pointer, + saved_math_class, + /* */ + saved_box_type, + saved_box_context, + saved_box_spec, + saved_box_direction, + saved_box_attr_list, + saved_box_pack, + saved_box_orientation, + saved_box_anchor, + saved_box_geometry, + saved_box_xoffset, + saved_box_yoffset, + saved_box_xmove, + saved_box_ymove, + saved_box_reverse, + saved_box_discard, + saved_box_noskips, + saved_box_callback, + saved_box_container, + saved_box_shift, + saved_box_source, + saved_box_target, + saved_box_axis, + saved_box_class, + saved_box_state, + saved_box_retain, + /* */ + saved_local_box_location, + saved_local_box_index, + saved_local_box_options, + /* */ + saved_adjust_location, + saved_adjust_options, + saved_adjust_index, + saved_adjust_attr_list, + saved_adjust_depth_before, + saved_adjust_depth_after, +} save_types; + +/*tex Nota bena: |equiv_value| is the same as |equiv| but sometimes we use that name instead. */ + +// int_par(A) hash_state.eqtb_i_i[(A)].half1 + +# define int_parameter(A) eq_value(internal_int_location(A)) +# define count_parameter(A) eq_value(internal_int_location(A)) +# define attribute_parameter(A) eq_value(internal_attribute_location(A)) +# define dimen_parameter(A) eq_value(internal_dimen_location(A)) +# define toks_parameter(A) eq_value(internal_toks_location(A)) +# define glue_parameter(A) eq_value(internal_glue_location(A)) +# define mu_glue_parameter(A) eq_value(internal_mu_glue_location(A)) +# define box_parameter(A) eq_value(internal_box_location(A)) +# define specification_parameter(A) eq_value(internal_specification_location(A)) + +/*tex These come from |\ALEPH| aka |\OMEGA|: */ + + +# define is_valid_local_box_code(c) (c >= first_local_box_code && c <= last_local_box_code) + +/*tex + + Here are the group codes that are used to discriminate between different kinds of groups. They + allow \TEX\ to decide what special actions, if any, should be performed when a group ends. + + Some groups are not supposed to be ended by right braces. For example, the |$| that begins a + math formula causes a |math_shift_group| to be started, and this should be terminated by a + matching |$|. Similarly, a group that starts with |\left| should end with |\right|, and one + that starts with |\begingroup| should end with |\endgroup|. + +*/ + +typedef enum tex_group_codes { + bottom_level_group, /*tex group code for the outside world */ + simple_group, /*tex group code for local structure only */ + hbox_group, /*tex code for |\hbox| */ + adjusted_hbox_group, /*tex code for |\hbox| in vertical mode */ + vbox_group, /*tex code for |\vbox| */ + vtop_group, /*tex code for |\vtop| */ + align_group, /*tex code for |\halign|, |\valign| */ + no_align_group, /*tex code for |\noalign| */ + output_group, /*tex code for output routine */ + math_group, /*tex code for, e.g., |\char'136| */ + discretionary_group, /*tex code for |\discretionary|' */ + insert_group, /*tex code for |\insert| */ + vadjust_group, /*tex code for |\vadjust| */ + vcenter_group, /*tex code for |\vcenter| */ + math_fraction_group, /*tex code for |\over| and friends */ + math_operator_group, + math_choice_group, /*tex code for |\mathchoice| */ + also_simple_group, /*tex code for |\begingroup|\unknown|\egroup| */ + semi_simple_group, /*tex code for |\begingroup|\unknown|\endgroup| */ + math_simple_group, /*tex code for |\beginmathgroup|\unknown|\endmathgroup| */ + math_shift_group, /*tex code for |$|\unknown\|$| */ + math_fence_group, /*tex code for fences |\left|\unknown|\right| */ + local_box_group, /*tex code for |\localleftbox|\unknown|localrightbox| */ + split_off_group, /*tex box code for the top part of a |\vsplit| */ + split_keep_group, /*tex box code for the bottom part of a |\vsplit| */ + preamble_group, /*tex box code for the preamble processing in an alignment */ + align_set_group, /*tex box code for the final item pass in an alignment */ + finish_row_group, /*tex box code for a provisory line in an alignment */ + lua_group, +} tex_group_codes; + +typedef enum saved_group_items { + saved_group_line_number = 0, + saved_group_level_boundary = 1, + saved_group_n_of_items = 2, +} saved_group_items; + +/* + In the end I decided to split them into context and begin, but maybe some day + they all merge into one (easier on tracing and reporting in shared helpers). +*/ + +typedef enum tex_par_context_codes { + normal_par_context, + vmode_par_context, + vbox_par_context, + vtop_par_context, + vcenter_par_context, + vadjust_par_context, + insert_par_context, + output_par_context, + align_par_context, + no_align_par_context, + span_par_context, + reset_par_context, +} tex_par_context_codes; + +typedef enum tex_alignment_context_codes { + preamble_pass_alignment_context, + preroll_pass_alignment_context, + package_pass_alignment_context, + wrapup_pass_alignment_context, +} tex_alignment_context_codes; + +typedef enum tex_page_context_codes { + box_page_context, + end_page_context, + vadjust_page_context, + penalty_page_context, + boundary_page_context, + insert_page_context, + hmode_par_page_context, + vmode_par_page_context, + begin_paragraph_page_context, + before_display_page_context, + after_display_page_context, + after_output_page_context, + alignment_page_context, +} tex_page_context_codes; + +typedef enum tex_append_line_context_codes { + box_append_line_context, + pre_box_append_line_context, + pre_adjust_append_line_context, + post_adjust_append_line_context, + pre_migrate_append_line_context, + post_migrate_append_line_context, +} tex_append_line_context_codes; + +typedef enum tex_par_begin_codes { + normal_par_begin, + force_par_begin, + indent_par_begin, + no_indent_par_begin, + math_char_par_begin, + char_par_begin, + boundary_par_begin, + space_par_begin, + math_par_begin, + kern_par_begin, + hskip_par_begin, + un_hbox_char_par_begin, + valign_char_par_begin, + vrule_char_par_begin, +} tex_par_begin_codes; + +typedef enum tex_tracing_levels_codes { + tracing_levels_group = 0x01, + tracing_levels_input = 0x02, + tracing_levels_catcodes = 0x04, +} tex_tracing_levels_codes; + +extern void tex_initialize_save_stack (void); +/* int tex_room_on_save_stack (void); */ +extern void tex_save_halfword_on_stack (quarterword t, halfword v); +extern void tex_show_cmd_chr (halfword cmd, halfword chr); +extern void tex_new_save_level (quarterword c); /*tex begin a new level of grouping */ +extern int tex_saved_line_at_level (void); +extern void tex_eq_define (halfword p, singleword cmd, halfword chr); /*tex new data for |eqtb| */ +extern void tex_eq_word_define (halfword p, int w); +extern void tex_geq_define (halfword p, singleword cmd, halfword chr); /*tex global |eq_define| */ +extern void tex_geq_word_define (halfword p, int w); /*tex global |eq_word_define| */ +extern void tex_save_for_after_group (halfword t); +extern void tex_unsave (void); /*tex pops the top level off the save stack */ +extern void tex_show_save_groups (void); +extern int tex_located_save_value (int id); + +/*tex + + The |prefixed_command| does not have to adjust |a| so that |a mod 4 = 0|, since the following + routines test for the |\global| prefix as follows. Anyway, in the meantime we reshuffled the + bits and changed a lot. + + When we need more bits, we will do this: + + One one of these: + + \starttyping + primitive_flag = 00000001 : cannot be changed system set + permanent_flag = 00000010 : cannot be changed \permanent + immutable_flag = 00000011 : cannot be changed \immutable + frozen_flag = 00000100 : can be overloaded \frozen and \overloaded + mutable_flag = 00000101 : never checked \mutable + reserved_1_flag = 00000110 + \stoptyping + + Independent, not used combined: + + \starttyping + noaligned_flag = 00001000 : valid align peek \noaligned (can be more generic: \alignpeekable or \alignable, also span and omit?) + reserved_3_flag = 00010000 : maybe obsolete indicator + \stoptyping + + Informative: + + \starttyping + instance_flag = 00100000 : just a tag \instance + symbol_flag = 01000000 : just a tag \symbolic (or character) + c_quantity_flag = 01100000 + d_quantity-flag = 10000000 + reserved_4_flag = 10100000 + reserved_5_flag = 11100000 + \stoptyping + + Maybe names like \flaginstance \flagpermanent etc are better? Now we run out of meaningful + prefixes. Also testing the prefix then becomes more work. + +*/ + +typedef enum flag_bit { + /* properties and prefixes */ + frozen_flag_bit = 0x00001, + permanent_flag_bit = 0x00002, + immutable_flag_bit = 0x00004, + primitive_flag_bit = 0x00008, + mutable_flag_bit = 0x00010, + noaligned_flag_bit = 0x00020, + instance_flag_bit = 0x00040, + untraced_flag_bit = 0x00080, + /* prefixes */ + global_flag_bit = 0x00100, + tolerant_flag_bit = 0x00200, + protected_flag_bit = 0x00400, + overloaded_flag_bit = 0x00800, + aliased_flag_bit = 0x01000, + immediate_flag_bit = 0x02000, + conditional_flag_bit = 0x04000, + value_flag_bit = 0x08000, + semiprotected_flag_bit = 0x10000, + inherited_flag_bit = 0x20000, +} flag_bits; + +/*tex Flags: */ + +# define add_flag(a,b) ((a) | (b)) + +# define add_frozen_flag(a) ((a) | frozen_flag_bit) +# define add_permanent_flag(a) ((a) | permanent_flag_bit) +# define add_immutable_flag(a) ((a) | immutable_flag_bit) +# define add_primitive_flag(a) ((a) | primitive_flag_bit) +# define add_mutable_flag(a) ((a) | mutable_flag_bit) +# define add_noaligned_flag(a) ((a) | noaligned_flag_bit) +# define add_instance_flag(a) ((a) | instance_flag_bit) +# define add_untraced_flag(a) ((a) | untraced_flag_bit) + +# define add_global_flag(a) ((a) | global_flag_bit) +# define add_tolerant_flag(a) ((a) | tolerant_flag_bit) +# define add_protected_flag(a) ((a) | protected_flag_bit) +# define add_semiprotected_flag(a) ((a) | semiprotected_flag_bit) +# define add_overloaded_flag(a) ((a) | overloaded_flag_bit) +# define add_aliased_flag(a) ((a) | aliased_flag_bit) +# define add_immediate_flag(a) ((a) | immediate_flag_bit) +# define add_conditional_flag(a) ((a) | conditional_flag_bit) +# define add_value_flag(a) ((a) | value_flag_bit) +# define add_inherited_flag(a) ((a) | inherited_flag_bit) + +# define remove_flag(a,b) ((a) & ~(b)) + +# define remove_frozen_flag(a) ((a) & ~frozen_flag_bit) +# define remove_permanent_flag(a) ((a) & ~permanent_flag_bit) +# define remove_immutable_flag(a) ((a) & ~immutable_flag_bit) +# define remove_primitive_flag(a) ((a) & ~primitive_flag_bit) +# define remove_mutable_flag(a) ((a) & ~mutable_flag_bit) +# define remove_noaligned_flag(a) ((a) & ~noaligned_flag_bit) +# define remove_instance_flag(a) ((a) & ~instance_flag_bit) +# define remove_untraced_flag(a) ((a) & ~untraced_flag_bit) + +# define remove_global_flag(a) ((a) & ~global_flag_bit) +# define remove_tolerant_flag(a) ((a) & ~tolerant_flag_bit) +# define remove_protected_flag(a) ((a) & ~protected_flag_bit) +# define remove_overloaded_flag(a) ((a) & ~overloaded_flag_bit) +# define remove_aliased_flag(a) ((a) & ~aliased_flag_bit) +# define remove_immediate_flag(a) ((a) & ~immediate_flag_bit) +# define remove_conditional_flag(a) ((a) & ~conditional_flag_bit) +# define remove_value_flag(a) ((a) & ~value_flag_bit) + +# define is_frozen(a) (((a) & frozen_flag_bit) == frozen_flag_bit) +# define is_permanent(a) (((a) & permanent_flag_bit) == permanent_flag_bit) +# define is_immutable(a) (((a) & immutable_flag_bit) == immutable_flag_bit) +# define is_primitive(a) (((a) & primitive_flag_bit) == primitive_flag_bit) +# define is_mutable(a) (((a) & mutable_flag_bit) == mutable_flag_bit) +# define is_noaligned(a) (((a) & noaligned_flag_bit) == noaligned_flag_bit) +# define is_instance(a) (((a) & instance_flag_bit) == instance_flag_bit) +# define is_untraced(a) (((a) & untraced_flag_bit) == untraced_flag_bit) + +# define is_global(a) (((a) & global_flag_bit) == global_flag_bit) +# define is_tolerant(a) (((a) & tolerant_flag_bit) == tolerant_flag_bit) +# define is_protected(a) (((a) & protected_flag_bit) == protected_flag_bit) +# define is_semiprotected(a) (((a) & semiprotected_flag_bit) == semiprotected_flag_bit) +# define is_overloaded(a) (((a) & overloaded_flag_bit) == overloaded_flag_bit) +# define is_aliased(a) (((a) & aliased_flag_bit) == aliased_flag_bit) +# define is_immediate(a) (((a) & immediate_flag_bit) == immediate_flag_bit) +# define is_conditional(a) (((a) & conditional_flag_bit) == conditional_flag_bit) +# define is_value(a) (((a) & value_flag_bit) == value_flag_bit) +# define is_inherited(a) (((a) & inherited_flag_bit) == inherited_flag_bit) + +# define is_expandable(cmd) (cmd > max_command_cmd) + +# define global_or_local(a) (is_global(a) ? level_one : cur_level) + +# define has_flag_bits(p,a) ((p) & (a)) + +# define remove_overload_flags(a) ((a) & ~(permanent_flag_bit | immutable_flag_bit | primitive_flag_bit)) + +# define make_eq_flag_bits(a) ((singleword) ((a) & 0xFF)) +# define has_eq_flag_bits(p,a) (eq_flag(p) & (a)) +# define set_eq_flag_bits(p,a) set_eq_flag(p, make_eq_flag_bits(a)) + +inline static singleword tex_flags_to_cmd(int flags) +{ + if (is_tolerant(flags)) { + return is_protected (flags) ? tolerant_protected_call_cmd : + (is_semiprotected(flags) ? tolerant_semi_protected_call_cmd : tolerant_call_cmd); + } else { + return is_protected (flags) ? protected_call_cmd : + (is_semiprotected(flags) ? semi_protected_call_cmd : call_cmd); + } +} + +/*tex + The macros and functions for the frozen, tolerant, protected cmd codes are gone but + can be found in the archive. We now have just one |call_cmd| with properties stored + elsewhere. + + int g -> singleword g +*/ + +extern int tex_define_permitted (halfword cs, halfword prefixes); +extern void tex_define (int g, halfword p, singleword cmd, halfword chr); +extern void tex_define_inherit (int g, halfword p, singleword flag, singleword cmd, halfword chr); +extern void tex_define_swapped (int g, halfword p1, halfword p2, int force); +extern void tex_forced_define (int g, halfword p, singleword flag, singleword cmd, halfword chr); +extern void tex_word_define (int g, halfword p, halfword w); +extern void tex_forced_word_define (int g, halfword p, singleword flag, halfword w); + +/*tex + + The |*_par| macros expand to the variables that are (in most cases) also accessible at the users + end. Most are registers but some are in the (stack) lists. More |*_par| will move here: there is + no real need for these macros but because there were already a bunch and because they were defined + all over the place we moved them here. + +*/ + +# define space_skip_par glue_parameter(space_skip_code) +# define xspace_skip_par glue_parameter(xspace_skip_code) +# define math_skip_par glue_parameter(math_skip_code) +# define math_skip_mode_par count_parameter(math_skip_mode_code) +# define math_double_script_mode_par count_parameter(math_double_script_mode_code) +/*define math_control_mode_par count_parameter(math_control_mode_code) */ +# define math_font_control_par count_parameter(math_font_control_code) +# define math_display_mode_par count_parameter(math_display_mode_code) +# define math_dict_group_par count_parameter(math_dict_group_code) +# define math_dict_properties_par count_parameter(math_dict_properties_code) +# define math_threshold_par glue_parameter(math_threshold_code) +# define page_extra_goal_par dimen_parameter(page_extra_goal_code) + +# define pre_display_size_par dimen_parameter(pre_display_size_code) +# define display_width_par dimen_parameter(display_width_code) +# define display_indent_par dimen_parameter(display_indent_code) +# define math_surround_par dimen_parameter(math_surround_code) + +# define display_skip_mode_par count_parameter(math_display_skip_mode_code) +# define math_eqno_gap_step_par count_parameter(math_eqno_gap_step_code) + +# define par_direction_par count_parameter(par_direction_code) +# define text_direction_par count_parameter(text_direction_code) +# define math_direction_par count_parameter(math_direction_code) + +# define first_valid_language_par count_parameter(first_valid_language_code) + +# define hsize_par dimen_parameter(hsize_code) +# define vsize_par dimen_parameter(vsize_code) +# define hfuzz_par dimen_parameter(hfuzz_code) +# define vfuzz_par dimen_parameter(vfuzz_code) +# define hbadness_par count_parameter(hbadness_code) +# define vbadness_par count_parameter(vbadness_code) + +# define baseline_skip_par glue_parameter(baseline_skip_code) +# define line_skip_par glue_parameter(line_skip_code) +# define par_indent_par dimen_parameter(par_indent_code) +# define hang_indent_par dimen_parameter(hang_indent_code) +# define hang_after_par count_parameter(hang_after_code) +# define left_skip_par glue_parameter(left_skip_code) +# define right_skip_par glue_parameter(right_skip_code) +# define par_fill_left_skip_par glue_parameter(par_fill_left_skip_code) +# define par_fill_right_skip_par glue_parameter(par_fill_right_skip_code) +# define par_init_left_skip_par glue_parameter(par_init_left_skip_code) +# define par_init_right_skip_par glue_parameter(par_init_right_skip_code) +# define tab_skip_par glue_parameter(tab_skip_code) + +# define emergency_stretch_par dimen_parameter(emergency_stretch_code) +# define pre_tolerance_par count_parameter(pre_tolerance_code) +# define tolerance_par count_parameter(tolerance_code) +# define looseness_par count_parameter(looseness_code) +# define adjust_spacing_par count_parameter(adjust_spacing_code) +# define adjust_spacing_step_par count_parameter(adjust_spacing_step_code) +# define adjust_spacing_stretch_par count_parameter(adjust_spacing_stretch_code) +# define adjust_spacing_shrink_par count_parameter(adjust_spacing_shrink_code) +# define adj_demerits_par count_parameter(adj_demerits_code) +# define protrude_chars_par count_parameter(protrude_chars_code) +# define line_penalty_par count_parameter(line_penalty_code) +# define last_line_fit_par count_parameter(last_line_fit_code) +# define double_hyphen_demerits_par count_parameter(double_hyphen_demerits_code) +# define final_hyphen_demerits_par count_parameter(final_hyphen_demerits_code) +# define inter_line_penalty_par count_parameter(inter_line_penalty_code) +# define club_penalty_par count_parameter(club_penalty_code) +# define widow_penalty_par count_parameter(widow_penalty_code) +# define display_widow_penalty_par count_parameter(display_widow_penalty_code) +# define orphan_penalty_par count_parameter(orphan_penalty_code) +/*define page_boundary_penalty_par count_parameter(page_boundary_penalty_code) */ /* now in |\pageboundary| */ +# define line_break_criterium_par count_parameter(line_break_criterium_code) +# define broken_penalty_par count_parameter(broken_penalty_code) +# define line_skip_limit_par dimen_parameter(line_skip_limit_code) + +# define alignment_cell_source_par count_parameter(alignment_cell_source_code) +# define alignment_wrap_source_par count_parameter(alignment_wrap_source_code) + +# define delimiter_shortfall_par dimen_parameter(delimiter_shortfall_code) +# define null_delimiter_space_par dimen_parameter(null_delimiter_space_code) +# define script_space_par dimen_parameter(script_space_code) +# define max_depth_par dimen_parameter(max_depth_code) +# define box_max_depth_par dimen_parameter(box_max_depth_code) +# define split_max_depth_par dimen_parameter(split_max_depth_code) +# define overfull_rule_par dimen_parameter(overfull_rule_code) +# define box_max_depth_par dimen_parameter(box_max_depth_code) +# define top_skip_par glue_parameter(top_skip_code) +# define split_top_skip_par glue_parameter(split_top_skip_code) + +# define cur_fam_par count_parameter(family_code) +# define pre_display_direction_par count_parameter(pre_display_direction_code) +# define pre_display_penalty_par count_parameter(pre_display_penalty_code) +# define post_display_penalty_par count_parameter(post_display_penalty_code) +# define pre_inline_penalty_par count_parameter(pre_inline_penalty_code) +# define post_inline_penalty_par count_parameter(post_inline_penalty_code) + +# define local_interline_penalty_par count_parameter(local_interline_penalty_code) +# define local_broken_penalty_par count_parameter(local_broken_penalty_code) +# define local_left_box_par box_parameter(local_left_box_code) +# define local_right_box_par box_parameter(local_right_box_code) +# define local_middle_box_par box_parameter(local_middle_box_code) + +# define end_line_char_par count_parameter(end_line_char_code) +# define new_line_char_par count_parameter(new_line_char_code) +# define escape_char_par count_parameter(escape_char_code) + +# define end_line_char_inactive ((end_line_char_par < 0) || (end_line_char_par > 127)) + +# define delimiter_factor_par count_parameter(delimiter_factor_code) +/*define post_binary_penalty_par count_parameter(post_binary_penalty_code) */ +/*define post_relation_penalty_par count_parameter(post_relation_penalty_code) */ +/*define pre_binary_penalty_par count_parameter(pre_binary_penalty_code) */ +/*define pre_relation_penalty_par count_parameter(pre_relation_penalty_code) */ +# define math_penalties_mode_par count_parameter(math_penalties_mode_code) +# define math_check_fences_par count_parameter(math_check_fences_mode_code) +/*define math_delimiters_mode_par count_parameter(math_delimiters_mode_code) */ +/*define math_fences_mode_par count_parameter(math_fences_mode_code) */ +/*define math_rule_thickness_mode_par count_parameter(math_rule_thickness_mode_code) */ +# define math_slack_mode_par count_parameter(math_slack_mode_code) +/*define math_flatten_mode_par count_parameter(math_flatten_mode_code) */ +# define null_delimiter_space_par dimen_parameter(null_delimiter_space_code) +# define disable_spaces_par count_parameter(disable_spaces_code) +# define glyph_options_par count_parameter(glyph_options_code) +# define glyph_scale_par count_parameter(glyph_scale_code) +# define glyph_text_scale_par count_parameter(glyph_text_scale_code) +# define glyph_script_scale_par count_parameter(glyph_script_scale_code) +# define glyph_scriptscript_scale_par count_parameter(glyph_scriptscript_scale_code) +# define glyph_x_scale_par count_parameter(glyph_x_scale_code) +# define glyph_y_scale_par count_parameter(glyph_y_scale_code) +# define glyph_x_offset_par dimen_parameter(glyph_x_offset_code) +# define glyph_y_offset_par dimen_parameter(glyph_y_offset_code) +# define math_scripts_mode_par count_parameter(math_scripts_mode_code) +/*define math_script_box_mode_par count_parameter(math_script_box_mode_code) */ +/*define math_script_char_mode_par count_parameter(math_script_char_mode_code) */ +# define math_limits_mode_par count_parameter(math_limits_mode_code) +# define math_nolimits_mode_par count_parameter(math_nolimits_mode_code) +# define math_rules_mode_par count_parameter(math_rules_mode_code) +# define math_rules_fam_par count_parameter(math_rules_fam_code) +# define math_glue_mode_par count_parameter(math_glue_mode_code) + +typedef enum math_glue_modes { + math_glue_stretch_code = 0x01, + math_glue_shrink_code = 0x02, +} math_glue_modes; + +# define math_glue_stretch_enabled ((math_glue_mode_par & math_glue_stretch_code) == math_glue_stretch_code) +# define math_glue_shrink_enabled ((math_glue_mode_par & math_glue_shrink_code) == math_glue_shrink_code) +# define default_math_glue_mode (math_glue_stretch_code | math_glue_shrink_code) + +# define petty_mu_skip_par mu_glue_parameter(petty_mu_skip_code) +# define tiny_mu_skip_par mu_glue_parameter(tiny_mu_skip_code) +# define thin_mu_skip_par mu_glue_parameter(thin_mu_skip_code) +# define med_mu_skip_par mu_glue_parameter(med_mu_skip_code) +# define thick_mu_skip_par mu_glue_parameter(thick_mu_skip_code) + +# define every_math_par toks_parameter(every_math_code) +# define every_display_par toks_parameter(every_display_code) +# define every_cr_par toks_parameter(every_cr_code) +# define every_tab_par toks_parameter(every_tab_code) +# define every_hbox_par toks_parameter(every_hbox_code) +# define every_vbox_par toks_parameter(every_vbox_code) +# define every_math_atom_par toks_parameter(every_math_atom_code) +# define every_eof_par toks_parameter(every_eof_code) +# define every_par_par toks_parameter(every_par_code) +# define every_before_par_par toks_parameter(every_before_par_code) +# define every_job_par toks_parameter(every_job_code) +# define error_help_par toks_parameter(error_help_code) +# define end_of_group_par toks_parameter(end_of_group_code) +/*define end_of_par_par toks_parameter(end_of_par_code) */ + +# define internal_par_state_par count_parameter(internal_par_state_code) +# define internal_dir_state_par count_parameter(internal_dir_state_code) +# define internal_math_style_par count_parameter(internal_math_style_code) +# define internal_math_scale_par count_parameter(internal_math_scale_code) + +# define overload_mode_par count_parameter(overload_mode_code) + +# define auto_paragraph_mode_par count_parameter(auto_paragraph_mode_code) + +typedef enum auto_paragraph_modes { + auto_paragraph_text = 0x01, + auto_paragraph_macro = 0x02, + auto_paragraph_go_on = 0x04, +} auto_paragraph_modes; + +# define auto_paragraph_mode(flag) ((auto_paragraph_mode_par) & (flag)) + +# define shaping_penalties_mode_par count_parameter(shaping_penalties_mode_code) +# define shaping_penalty_par count_parameter(shaping_penalty_code) + +typedef enum shaping_penalties_mode_bits { + inter_line_penalty_shaping = 0x01, + widow_penalty_shaping = 0x02, + club_penalty_shaping = 0x04, + broken_penalty_shaping = 0x08, +} shaping_penalties_mode_bits; + +# define is_shaping_penalties_mode(what,flag) ((what) & (flag)) + +# define tab_size_par dimen_parameter(tab_size_code) + +/*define prev_graf_par cur_list.prev_graf */ +/*define prev_depth_par cur_list.prev_depth */ +/*define space_factor_par cur_list.space_factor */ + +/*define tail_par cur_list.tail */ +/*define head_par cur_list.head */ +/*define mode_par cur_list.mode */ +/*define dirs_par cur_list.dirs */ + +/*define incompleat_noad_par cur_list.incompleat_noad */ +/*define mode_line_par cur_list.mode_line */ +/*define delim_par cur_list.delim */ + +# define par_shape_par specification_parameter(par_shape_code) +# define inter_line_penalties_par specification_parameter(inter_line_penalties_code) +# define club_penalties_par specification_parameter(club_penalties_code) +# define widow_penalties_par specification_parameter(widow_penalties_code) +# define display_widow_penalties_par specification_parameter(display_widow_penalties_code) +# define orphan_penalties_par specification_parameter(orphan_penalties_code) +# define math_forward_penalties_par specification_parameter(math_forward_penalties_code) +# define math_backward_penalties_par specification_parameter(math_backward_penalties_code) + +/*define h_offset_par dimen_parameter(h_offset_code) */ +/*define v_offset_par dimen_parameter(v_offset_code) */ +# define px_dimen_par dimen_parameter(px_dimen_code) +/*define mag_par count_parameter(mag_code) */ + +# define max_dead_cycles_par count_parameter(max_dead_cycles_code) +# define output_box_par count_parameter(output_box_code) +# define holding_inserts_par count_parameter(holding_inserts_code) +# define holding_migrations_par count_parameter(holding_migrations_code) +# define output_routine_par toks_parameter(output_routine_code) +# define floating_penalty_par count_parameter(floating_penalty_code) + +# define global_defs_par count_parameter(global_defs_code) +# define cat_code_table_par count_parameter(cat_code_table_code) +# define saving_vdiscards_par count_parameter(saving_vdiscards_code) + +# define tracing_output_par count_parameter(tracing_output_code) +# define tracing_stats_par count_parameter(tracing_stats_code) +# define tracing_online_par count_parameter(tracing_online_code) +# define tracing_paragraphs_par count_parameter(tracing_paragraphs_code) +# define tracing_levels_par count_parameter(tracing_levels_code) +# define tracing_nesting_par count_parameter(tracing_nesting_code) +# define tracing_alignments_par count_parameter(tracing_alignments_code) +# define tracing_inserts_par count_parameter(tracing_inserts_code) +# define tracing_marks_par count_parameter(tracing_marks_code) +# define tracing_adjusts_par count_parameter(tracing_adjusts_code) +# define tracing_lost_chars_par count_parameter(tracing_lost_chars_code) +# define tracing_ifs_par count_parameter(tracing_ifs_code) +# define tracing_commands_par count_parameter(tracing_commands_code) +# define tracing_macros_par count_parameter(tracing_macros_code) +# define tracing_assigns_par count_parameter(tracing_assigns_code) +# define tracing_fonts_par count_parameter(tracing_fonts_code) +# define tracing_pages_par count_parameter(tracing_pages_code) +# define tracing_restores_par count_parameter(tracing_restores_code) +# define tracing_groups_par count_parameter(tracing_groups_code) +# define tracing_math_par count_parameter(tracing_math_code) +# define tracing_hyphenation_par count_parameter(tracing_hyphenation_code) +# define tracing_expressions_par count_parameter(tracing_expressions_code) +# define tracing_nodes_par count_parameter(tracing_nodes_code) +# define tracing_full_boxes_par count_parameter(tracing_full_boxes_code) +# define tracing_penalties_par count_parameter(tracing_penalties_code) + +# define show_box_depth_par count_parameter(show_box_depth_code) +# define show_box_breadth_par count_parameter(show_box_breadth_code) +# define show_node_details_par count_parameter(show_node_details_code) + +# define pausing_par count_parameter(pausing_code) + +# define error_context_lines_par count_parameter(error_context_lines_code) +# define copy_lua_input_nodes_par count_parameter(copy_lua_input_nodes_code) + +# define math_pre_display_gap_factor_par count_parameter(math_pre_display_gap_factor_code) + +# define time_par count_parameter(time_code) +# define day_par count_parameter(day_code) +# define month_par count_parameter(month_code) +# define year_par count_parameter(year_code) + +typedef enum hyphenation_mode_bits { + normal_hyphenation_mode = 0x00001, + automatic_hyphenation_mode = 0x00002, + explicit_hyphenation_mode = 0x00004, + syllable_hyphenation_mode = 0x00008, + uppercase_hyphenation_mode = 0x00010, + compound_hyphenation_mode = 0x00020, + strict_start_hyphenation_mode = 0x00040, + strict_end_hyphenation_mode = 0x00080, + automatic_penalty_hyphenation_mode = 0x00100, + explicit_penalty_hyphenation_mode = 0x00200, + permit_glue_hyphenation_mode = 0x00400, + permit_all_hyphenation_mode = 0x00800, + permit_math_replace_hyphenation_mode = 0x01000, + force_check_hyphenation_mode = 0x02000, + lazy_ligatures_hyphenation_mode = 0x04000, + force_handler_hyphenation_mode = 0x08000, + feedback_compound_hyphenation_mode = 0x10000, + ignore_bounds_hyphenation_mode = 0x20000, + collapse_hyphenation_mode = 0x40000, +} hyphenation_mode_bits; + +# define hyphenation_permitted(a,b) (((a) & (b)) == (b)) +# define set_hyphenation_mode(a,b) ((a) | (b)) +# define unset_hyphenation_mode(a,b) ((a) & ~(b)) +# define flip_hyphenation_mode(a,b) ((b) ? set_hyphenation_mode(a,b) : unset_hyphenation_mode(a,b)) +# define default_hyphenation_mode (normal_hyphenation_mode | automatic_hyphenation_mode | explicit_hyphenation_mode | syllable_hyphenation_mode | compound_hyphenation_mode | force_handler_hyphenation_mode | feedback_compound_hyphenation_mode) + +# define language_par count_parameter(language_code) +# define hyphenation_mode_par count_parameter(hyphenation_mode_code) +# define uc_hyph_par count_parameter(uc_hyph_code) +# define left_hyphen_min_par count_parameter(left_hyphen_min_code) +# define right_hyphen_min_par count_parameter(right_hyphen_min_code) +# define ex_hyphen_char_par count_parameter(ex_hyphen_char_code) +# define hyphen_penalty_par count_parameter(hyphen_penalty_code) +# define ex_hyphen_penalty_par count_parameter(ex_hyphen_penalty_code) +# define default_hyphen_char_par count_parameter(default_hyphen_char_code) +# define default_skew_char_par count_parameter(default_skew_char_code) +# define saving_hyph_codes_par count_parameter(saving_hyph_codes_code) + +# define automatic_hyphen_penalty_par count_parameter(automatic_hyphen_penalty_code) +# define explicit_hyphen_penalty_par count_parameter(explicit_hyphen_penalty_code) +# define exception_penalty_par count_parameter(exception_penalty_code) + +# define math_spacing_mode_par count_parameter(math_spacing_mode_code) +# define math_grouping_mode_par count_parameter(math_grouping_mode_code) +# define math_begin_class_par count_parameter(math_begin_class_code) +# define math_end_class_par count_parameter(math_end_class_code) +# define math_left_class_par count_parameter(math_left_class_code) +# define math_right_class_par count_parameter(math_right_class_code) +# define sup_mark_mode_par count_parameter(sup_mark_mode_code) + +# define glyph_data_par count_parameter(glyph_data_code) +# define glyph_state_par count_parameter(glyph_state_code) +# define glyph_script_par count_parameter(glyph_script_code) + +/*define glue_data_par count_parameter(glue_data_code) */ + +# define cur_lang_par count_parameter(language_code) +/*define cur_font_par eq_value(current_font_sequence) */ +# define cur_font_par count_parameter(font_code) + +typedef enum normalize_line_mode_bits { + normalize_line_mode = 0x0001, + parindent_skip_mode = 0x0002, + swap_hangindent_mode = 0x0004, + swap_parshape_mode = 0x0008, + break_after_dir_mode = 0x0010, + remove_margin_kerns_mode = 0x0020, /*tex When unpacking an hbox \unknown\ a \PDFTEX\ leftover. */ + clip_width_mode = 0x0040, + flatten_discretionaries_mode = 0x0080, + discard_zero_tab_skips_mode = 0x0100, + flatten_h_leaders_mode = 0x0200, +} normalize_line_mode_bits; + +typedef enum normalize_par_mode_bits { + normalize_par_mode = 0x0001, + flatten_v_leaders_mode = 0x0002, /* used to be 0x200 */ +} normalize_par_mode_bits; + +# define normalize_line_mode_permitted(a,b) ((a & b) == b) +# define normalize_par_mode_permitted(a,b) ((a & b) == b) + +# define normalize_line_mode_par count_parameter(normalize_line_mode_code) +# define normalize_par_mode_par count_parameter(normalize_par_mode_code) +# define auto_migration_mode_par count_parameter(auto_migration_mode_code) + +typedef enum auto_migration_mode_bits { + auto_migrate_mark = 0x01, + auto_migrate_insert = 0x02, + auto_migrate_adjust = 0x04, + auto_migrate_pre = 0x08, + auto_migrate_post = 0x10, +} auto_migration_mode_bits; + +# define auto_migrating_mode_permitted(what,flag) ((what & flag) == flag) + +# define attribute_register(j) eq_value(register_attribute_location(j)) +# define box_register(j) eq_value(register_box_location(j)) +# define count_register(j) eq_value(register_int_location(j)) +# define dimen_register(j) eq_value(register_dimen_location(j)) +# define mu_skip_register(j) eq_value(register_mu_glue_location(j)) +# define skip_register(j) eq_value(register_glue_location(j)) +# define toks_register(j) eq_value(register_toks_location(j)) + +/* + Injecting these frozen tokens can for instance happen when we scan for an integer or dimension + and run into an |\else| or |\fi| because (guess what) these scanners gobble trailing spaces! In + that case the |deep_frozen_relax_token| gets pushed back and can for instance end up in an + expansion (macro, write, etc) because we only look ahead. However, we can catch this side effect + in the scanners (that we redefined anyway). Removing those |\relax|'s was on the todo list and + now happens in the scanners. Actually it's one reason why we often use constants in tests + because these don't have that side effect because the scanner then quite earlier.) Another place + where that happens is in the |\input| command but there we can use braces. It is a typical + example of a more cosmetic adaptation that got a bit more priority when we converted the + \CONTEXT\ codebase from \MKIV\ to \LMTX, where testing involved checking the results. I also have + to check the other frozen tokens that can get reported when we have for instance alignments. It + is also why some of these tokens have an associated (private but serialized) |\csname|. + + For the record: we can these tokens deep_frozen because we don't want them to be confused with + the |\frozen| user macros and the ones below are really deeply hidden, although sometimes they + do surface. + +*/ + +typedef enum deep_frozen_cs_tokens { + deep_frozen_protection_token = cs_token_flag + deep_frozen_cs_protection_code, + deep_frozen_cr_token = cs_token_flag + deep_frozen_cs_cr_code, + deep_frozen_end_group_token = cs_token_flag + deep_frozen_cs_end_group_code, + deep_frozen_right_token = cs_token_flag + deep_frozen_cs_right_code, + deep_frozen_fi_token = cs_token_flag + deep_frozen_cs_fi_code, + deep_frozen_end_template_1_token = cs_token_flag + deep_frozen_cs_end_template_1_code, + deep_frozen_end_template_2_token = cs_token_flag + deep_frozen_cs_end_template_2_code, + deep_frozen_relax_token = cs_token_flag + deep_frozen_cs_relax_code, + deep_frozen_end_write_token = cs_token_flag + deep_frozen_cs_end_write_code, + deep_frozen_dont_expand_token = cs_token_flag + deep_frozen_cs_dont_expand_code, + deep_frozen_null_font_token = cs_token_flag + deep_frozen_cs_null_font_code, + deep_frozen_undefined_token = cs_token_flag + deep_frozen_cs_undefined_code, +} deep_frozen_cs_tokens; + +/*tex + + The next has been simplified and replaced by |\hyphenatiomode| but we keep it as reminder: + + \starttabulate[|T|T|T|] + \NC hyphen_penalty_mode_par \NC automatic_disc (-) \NC explicit_disc (\-) \NC \NR + \HL + \NC 0 (default) \NC ex_hyphen_penalty_par \NC ex_hyphen_penalty_par \NC \NR + \NC 1 \NC hyphen_penalty_par \NC hyphen_penalty_par \NC \NR + \NC 2 \NC ex_hyphen_penalty_par \NC hyphen_penalty_par \NC \NR + \NC 3 \NC hyphen_penalty_par \NC ex_hyphen_penalty_par \NC \NR + \NC 4 \NC automatic_hyphen_penalty_par \NC explicit_disc_penalty_par \NC \NR + \NC 5 \NC ex_hyphen_penalty_par \NC explicit_disc_penalty_par \NC \NR + \NC 6 \NC hyphen_penalty_par \NC explicit_disc_penalty_par \NC \NR + \NC 7 \NC automatic_hyphen_penalty_par \NC ex_hyphen_penalty_par \NC \NR + \NC 8 \NC automatic_hyphen_penalty_par \NC hyphen_penalty_par \NC \NR + \stoptabulate + +*/ + +extern halfword tex_automatic_disc_penalty (halfword mode); +extern halfword tex_explicit_disc_penalty (halfword mode); + +/*tex + + We add a bit more abstraction when setting the system parameters. This is not really + needed but it move all the |eq_| assignments to a place where we can keep an eye on + them. + +*/ + +# define update_tex_glyph_data(a,v) tex_word_define(a, internal_int_location(glyph_data_code), v) +# define update_tex_glyph_state(a,v) tex_word_define(a, internal_int_location(glyph_state_code), v) +# define update_tex_glyph_script(a,v) tex_word_define(a, internal_int_location(glyph_script_code), v) +# define update_tex_family(a,v) tex_word_define(a, internal_int_location(family_code), v) +# define update_tex_language(a,v) tex_word_define(a, internal_int_location(language_code), v) +# define update_tex_font(a,v) tex_word_define(a, internal_int_location(font_code), v) + +/*define update_tex_glue_data(a,v) tex_word_define(a, internal_int_location(glue_data_code), v) */ + +# define update_tex_display_indent(v) tex_eq_word_define(internal_dimen_location(display_indent_code), v) +# define update_tex_display_width(v) tex_eq_word_define(internal_dimen_location(display_width_code), v) +# define update_tex_hang_after(v) tex_eq_word_define(internal_int_location(hang_after_code), v) +# define update_tex_hang_indent(v) tex_eq_word_define(internal_dimen_location(hang_indent_code), v) +# define update_tex_looseness(v) tex_eq_word_define(internal_int_location(looseness_code), v) +# define update_tex_math_direction(v) tex_eq_word_define(internal_int_location(math_direction_code), v) +# define update_tex_internal_par_state(v) tex_eq_word_define(internal_int_location(internal_par_state_code), v) +# define update_tex_internal_dir_state(v) tex_eq_word_define(internal_int_location(internal_dir_state_code), v) +# define update_tex_internal_math_style(v) tex_eq_word_define(internal_int_location(internal_math_style_code), v) +# define update_tex_internal_math_scale(v) tex_eq_word_define(internal_int_location(internal_math_scale_code), v) +# define update_tex_output_penalty(v) tex_geq_word_define(internal_int_location(output_penalty_code), v) +# define update_tex_par_direction(v) tex_eq_word_define(internal_int_location(par_direction_code), v) +# define update_tex_pre_display_direction(v) tex_eq_word_define(internal_int_location(pre_display_direction_code), v) +# define update_tex_pre_display_size(v) tex_eq_word_define(internal_dimen_location(pre_display_size_code), v) +# define update_tex_text_direction(v) tex_eq_word_define(internal_int_location(text_direction_code), v) + +# define update_tex_font_identifier(v) tex_eq_word_define(internal_int_location(font_code), v) +# define update_tex_glyph_scale(v) tex_eq_word_define(internal_int_location(glyph_scale_code), v) +# define update_tex_glyph_x_scale(v) tex_eq_word_define(internal_int_location(glyph_x_scale_code), v) +# define update_tex_glyph_y_scale(v) tex_eq_word_define(internal_int_location(glyph_y_scale_code), v) + +# define update_tex_math_left_class(v) tex_eq_word_define(internal_int_location(math_left_class_code), v) +# define update_tex_math_right_class(v) tex_eq_word_define(internal_int_location(math_right_class_code), v) + +# define update_tex_par_shape(v) tex_eq_define(internal_specification_location(par_shape_code), specification_reference_cmd, v) +# define update_tex_inter_line_penalties(v) tex_eq_define(internal_specification_location(inter_line_penalties_code), specification_reference_cmd, v) +/*define update_tex_club_penalties(v) eq_define(internal_specification_location(club_penalties_code), specification_reference_cmd, v) */ +/*define update_tex_widow_penalties(v) eq_define(internal_specification_location(widow_penalties_code), specification_reference_cmd, v) */ +/*define update_tex_display_widow_penalties(v) eq_define(internal_specification_location(display_widow_penalties_code), specification_reference_cmd, v) */ +/*define update_tex_orphan_penalties(v) eq_define(internal_specification_location(orphan_penalties_code), specification_reference_cmd, v) */ + +# define update_tex_end_of_group(v) tex_eq_define(internal_toks_location(end_of_group_code), internal_toks_reference_cmd, v) +/*define update_tex_end_of_par(v) eq_define(internal_toks_location(end_of_par_code), internal_toks_cmd, v) */ + +# define update_tex_local_left_box(v) tex_eq_define(internal_box_location(local_left_box_code), internal_box_reference_cmd, v); +# define update_tex_local_right_box(v) tex_eq_define(internal_box_location(local_right_box_code), internal_box_reference_cmd, v); +# define update_tex_local_middle_box(v) tex_eq_define(internal_box_location(local_middle_box_code), internal_box_reference_cmd, v); + +# define update_tex_font_local(f,v) tex_eq_define(f, set_font_cmd, v); /* Here |f| already has the right offset. */ +# define update_tex_font_global(f,v) tex_geq_define(f, set_font_cmd, v); /* Here |f| already has the right offset. */ + +# define update_tex_tab_skip_local(v) tex_eq_define(internal_glue_location(tab_skip_code), internal_glue_reference_cmd, v); +# define update_tex_tab_skip_global(v) tex_geq_define(internal_glue_location(tab_skip_code), internal_glue_reference_cmd, v); + +# define update_tex_box_local(n,v) tex_eq_define(register_box_location(n) - box_flag, register_box_reference_cmd, v); +# define update_tex_box_global(n,v) tex_geq_define(register_box_location(n) - global_box_flag, register_box_reference_cmd, v); + +# define update_tex_insert_mode(a,v) tex_word_define(a, internal_int_location(insert_mode_code), v) + +/*tex For the moment here; a preparation for a dedicated insert structure. */ + +# define insert_content(A) box_register(A) +# define insert_multiplier(A) count_register(A) +# define insert_maxheight(A) dimen_register(A) +# define insert_distance(A) skip_register(A) + +# endif |