texequivalents.h /size: 103 Kb    last modification: 2024-01-16 10:22
1/*
2    See license.txt in the root of this project.
3*/
4
5# ifndef LMT_EQUIVALENTS_H
6# define LMT_EQUIVALENTS_H
7
8# include "tex/textypes.h"
9
10/*tex
11
12    Like the preceding parameters, the following quantities can be changed at compile time to extend
13    or reduce \TEX's capacity. But if they are changed, it is necessary to rerun the initialization
14    program |INITEX| to generate new tables for the production \TEX\ program. One can't simply make
15    helter-skelter changes to the following constants, since certain rather complex initialization
16    numbers are computed from them. They are defined here using \WEB\ macros, instead of being put
17    into \PASCAL's |const| list, in order to emphasize this distinction.
18
19    The original token interface at the \LUA\ end used the \quote {real} chr values that are offsets
20    into the table of equivalents. However, that is sort of fragile when one also provides ways to
21    construct tokens. For that reason the \LUAMETATEX\ interface is a bit more abstract and therefore
22    can do some testing. After all, the real numbers don't matter. This means that registers for
23    instance run from |0..65535| (without the region offsets).
24
25    In order to make this easier the token registers are now more consistent with the other registers
26    in the sense that there is no longer a special cmd for those registers. This was not that hard to
27    do because most code already was sort of prepared for that move.
28
29    Now, there is one \quote {complication}: integers, dimensions etc references can be registers but
30    also internal variables. This means that we cannot simply remap the eq slots they refer to. When
31    we offset by some base (the first register) we end up with negative indices for the internal ones
32    because they come before this 64K range. So, this is why the \LUA\ interface works with negative
33    numbers for internal variables.
34
35    Another side effect is that we now have the mu glue internals in the muglue region. This is
36    possible because we have separated the subtypes from the chr codes. I might also relocate the
37    special things (like penalties) some day.
38
39    In a couple of cases a specific chr was used that made it possible to share for instance setters.
40    Examples are |\mkern| and |\mskip|. This resulted is (sort of) funny single numbers in the token
41    interface, so we have that now normalized as well (at the cost of a few split functions). Of course
42    that doesn't change the concept, unless one considers the fact that we have more granularity in
43    node subtypes (no longer parallel to the codes, as there are more) an issue. (Actually we can now
44    easily introduce hkern and vkern if we want.)
45
46*/
47
48/*tex
49
50    Each entry in |eqtb| is a |memoryword|. Most of these words are of type |two_halves|, and
51    subdivided into three fields:
52
53    \startitemize
54
55    \startitem
56        The |eq_level| (a quarterword) is the level of grouping at which this equivalent was
57        defined. If the level is |level_zero|, the equivalent has never been defined;
58        |level_one| refers to the outer level (outside of all groups), and this level is also
59        used for global definitions that never go away. Higher levels are for equivalents that
60        will disappear at the end of their group.
61    \stopitem
62
63    \startitem
64        The |eq_type| (another quarterword) specifies what kind of entry this is. There are many
65        types, since each \TEX\ primitive like |\hbox|, |\def|, etc., has its own special code.
66        The list of command codes above includes all possible settings of the |eq_type| field.
67    \stopitem
68
69    \startitem
70        The |equiv| (a halfword) is the current equivalent value. This may be a font number, a
71        pointer into |mem|, or a variety of other things.
72    \stopitem
73
74    \stopitemize
75
76    Many locations in |eqtb| have symbolic names. The purpose of the next paragraphs is to define
77    these names, and to set up the initial values of the equivalents.
78
79    In the first region we have a single entry for the \quote {null csname} of length zero. In
80    \LUATEX, the active characters and and single-letter control sequence names are part of the
81    next region.
82
83    Then comes region 2, which corresponds to the hash table that we will define later. The maximum
84    address in this region is used for a dummy control sequence that is perpetually undefined.
85    There also are several locations for control sequences that are perpetually defined (since they
86    are used in error recovery).
87
88    Region 3 of |eqtb| contains the |number_regs| |\skip| registers, as well as the glue parameters
89    defined here. It is important that the \quote {muskip} parameters have larger numbers than the
90    others.
91
92    Region 4 of |eqtb| contains the local quantities defined here. The bulk of this region is taken
93    up by five tables that are indexed by eight-bit characters; these tables are important to both
94    the syntactic and semantic portions of \TEX. There are also a bunch of special things like font
95    and token parameters, as well as the tables of |\toks| and |\box| registers.
96
97    Region 5 of |eqtb| contains the integer parameters and registers defined here, as well as the
98    |del_code| table. The latter table differs from the |cat_code..math_code| tables that precede it,
99    since delimiter codes are fullword integers while the other kinds of codes occupy at most a
100    halfword. This is what makes region~5 different from region~4. We will store the |eq_level|
101    information in an auxiliary array of quarterwords that will be defined later.
102
103    The integer parameters should really be initialized by a macro package; the following
104    initialization does the minimum to keep \TEX\ from complete failure.
105
106    The final region of |eqtb| contains the dimension parameters defined here, and the |number_regs|
107    |\dimen| registers.
108
109    Beware: in \LUATEX\ we have so many characters (\UNICODE) that we use a dedicated hash system
110    for special codes, math properties etc. This means that we have less in the regions than mentioned
111    here. On the other hand, we do have more registers (attributes) so that makes it a bit larger again.
112
113    The registers get marked as being \quote {undefined} commands. We could actually gove them a the
114    right commmand code etc.\ bur for now we just use the ranges as traditional \TEX\ does.
115
116    Most of the symbolic names and hard codes numbers are not enumerations. There is still room for
117    improvement and occasionally I enter a new round of doing that. However, it talkes a lot of time
118    and checking (more than writing from scratch) as we need to make sure it all behaves like \TEX\
119    does. Quite some code went through several stages of reaching this abstraction, just to make sure
120    that it kept working. These intermediate versions ended up in the \CONTEXT\ distribution to that
121    any issue would show up soon. A rather major step was splitting the |assign_*_cmd|s into
122    internal and register commands and ranges. This was a side effect of getting the token interface
123    at the \LUA\ end a bit nicer; there is really no need to expose the user to codes that demand
124    catching up with the \TEX\ internals when we can just provide a nice interface.
125
126    The font location is kind of special as it holds a halfword data field that points to a font
127    accessor and as such doesn't fit into a counter concept. Otherwise we could have made it a
128    counter. We could probably just use a font id and do a lookup elsewhere because this engine is
129    already doing it differently. So, eventually this needs checking.
130
131*/
132
133/*
134    For practical reasons we have the regions a bit different. For instance, we also have attributes, local
135    boxes, no math characters here, etc. Maybe specification codes sould get their own region.
136
137    HASH FROZEN
138    [I|R]FONTS
139    UNDEFINED
140    [I|R]GLUE
141    [I|R]MUGLUE
142    [I|R]TOKS
143    [I|R]BOXES
144    [I|R]INT
145    [I|R]ATTR
146    [I|R]DIMEN
147    SPECIFICATIONS
148    EQUIVPLUS
149
150    When I'd done a bit of clean up and abstraction (actually it took quite some time because the only
151    reliable way to do it is stepwise with lots of testing) I wondered why there is a difference in
152    the way the level is kept track of. For those entries that store a value directly, a separate
153    |xeq_level| array is used. So, after \quote {following the code}, taking a look at the original
154    implementation, and a walk, I came to the conclusion that because \LUATEX\ uses 64 memory words,
155    we actually don't need that parallel array: we have plenty of room and, the level fields are not
156    shared. In traditional \TEX\ we have a memory word with two faces:
157
158    [level] [type]
159    [    value   ]
160
161    but in \LUATEX\ it's wider. There is no overlap.
162
163    [level] [type] [value]
164
165    So, we can get rid of that extra array. Actually, in the \PASCAL\ source we see that this
166    parallel array is smaller because it only covers the value ranges (the first index starts at
167    the start of the first relevant register range). Keep in mind that the middle part of the hash
168    is registers and when we have a frozen hash size, that part is not present which is why there
169    was that parallel array needed; a side effect of the |extra_hash| extension.
170
171    Another side effect of this simplification is that we can store and use the type which can be
172    handy too.
173
174    For the changes, look for |xeq simplification| comments in the files and for the cleaned up
175    precursor in the archives of luametatex (in case there is doubt). When the save stack was made
176    more efficient the old commented |xeq| code has been removed.
177
178    -----------------------------------
179    null control sequence
180    hash entries (hash_size)
181    multiple frozen control sequences
182    special sequences (font, undefined)
183    -----------------------------------
184    glue registers
185    mu glue registers
186    token registers
187    box registers
188    integer registers
189    attribute registers
190    dimension registers
191    specifications
192    ---------- eqtb size --------------
193    extra hash entries
194    -----------------------------------
195
196    eqtb_top = eqtb_size + hash_extra
197    hash_top = hash_extra == 0 ? undefined_control_sequence : eqtb_top;
198
199    There used to be a large font area but I moved that to the font record so that we don't waste
200    space (it saves some 500K on the format file and plenty of memory).
201
202    Todo: split the eqtb and make the register arrays dynamic. We need to change the save/restore
203    code then and it might have a slight impact on performance (checking what table to use).
204
205*/
206
207/*tex
208    Maybe we should multiply the following by 2 but there is no real gain. Many entries end up in the extended
209    area anyway.
210
211    \starttyping
212    # define hash_size  65536
213    # define hash_prime 55711
214    \stoptyping
215
216    Here |hash_size| is the maximum number of control sequences; it should be at most about
217    |(fix_mem_max - fix_mem_min)/10|. The value of |hash_prime| is a prime number equal to about
218    85 percent of |hash_size|.
219
220    The hash runs in parallel to the eqtb and a large hash table makes for many holes and that
221    compresses badly. For instance:
222
223    590023 => down to 1024 * 512 == 524288 ==> 85% = 445644 => prime 445633/445649
224
225    will make a much larger format and we gain nothing. Actually, because we have extra hash
226    anyway, this whole 85\% criterion is irrelevant: we only need to make sure that we have
227    enough room for the frozen sequences (assuming we stay within the concept).
228
229    primes:
230
231    \starttyping
232     65447  65449  65479  65497  65519  65521 =>  65536 (85% ==  55711)
233    131009 131011 131023 131041 131059 131063 => 131072 (85% == 111409)
234    \stoptyping
235
236    lookups:
237
238    \starttyping
239    n=131040 cs=46426 indirect= 9173
240    n= 65496 cs=46426 indirect=14512
241    \stoptyping
242
243    We don't use the 85% prime (and we % the accumulated hash. Somehow this also performs better, 
244    but of course I migbe be wrong. 
245
246*/
247
248//define hash_size  65536
249//define hash_prime 65497
250
251# define hash_size  131072                               /*tex 128K */
252# define hash_prime 131041                               /*tex not the 85% prime */
253
254//define hash_size  262144                               /*tex 256K */
255//define hash_prime 262103                               /*tex not the 85% prime */
256
257# define null_cs                 1                       /*tex equivalent of |\csname\| |\endcsname| */
258# define hash_base               (null_cs   + 1)         /*tex beginning of region 2, for the hash table */
259# define frozen_control_sequence (hash_base + hash_size) /*tex for error recovery */
260
261typedef enum deep_frozen_cs_codes {
262    deep_frozen_cs_protection_code = frozen_control_sequence, /*tex inaccessible but definable */
263    deep_frozen_cs_cr_code,                                   /*tex permanent |\cr| */
264    deep_frozen_cs_end_group_code,                            /*tex permanent |\endgroup| */
265    deep_frozen_cs_right_code,                                /*tex permanent |\right| */
266    deep_frozen_cs_fi_code,                                   /*tex permanent |\fi| */
267    deep_frozen_cs_no_if_code,                                /*tex hidden |\noif| */
268    deep_frozen_cs_always_code,                               /*tex hidden internalized |\enforces| */
269    deep_frozen_cs_end_template_code,                         /*tex permanent |\endtemplate| */
270    deep_frozen_cs_relax_code,                                /*tex permanent |\relax| */
271    deep_frozen_cs_end_write_code,                            /*tex permanent |\endwrite| */
272    deep_frozen_cs_dont_expand_code,                          /*tex permanent |\notexpanded:| */
273    deep_frozen_cs_keep_constant_code,                        /*tex permanent |\notexpanded:| */
274    deep_frozen_cs_null_font_code,                            /*tex permanent |\nullfont| */
275    deep_frozen_cs_undefined_code,
276} deep_frozen_cs_codes;
277
278# define first_deep_frozen_cs_location deep_frozen_cs_protection_code
279# define last_deep_frozen_cs_location  deep_frozen_cs_undefined_code
280
281typedef enum glue_codes {
282    /* special ones */
283    additional_page_skip_code, 
284    /* normal ones */
285    initial_page_skip_code, 
286    initial_top_skip_code, 
287    line_skip_code,                /*tex interline glue if |baseline_skip| is infeasible */
288    baseline_skip_code,            /*tex desired glue between baselines */
289    par_skip_code,                 /*tex extra glue just above a paragraph */
290    above_display_skip_code,       /*tex extra glue just above displayed math */
291    below_display_skip_code,       /*tex extra glue just below displayed math */
292    above_display_short_skip_code, /*tex glue above displayed math following short lines */
293    below_display_short_skip_code, /*tex glue below displayed math following short lines */
294    left_skip_code,                /*tex glue at left of justified lines */
295    right_skip_code,               /*tex glue at right of justified lines */
296    top_skip_code,                 /*tex glue at top of main pages */
297    split_top_skip_code,           /*tex glue at top of split pages */
298    tab_skip_code,                 /*tex glue between aligned entries */
299    space_skip_code,               /*tex glue between words (if not |zero_glue|) */
300    xspace_skip_code,              /*tex glue after sentences (if not |zero_glue|) */
301    par_fill_left_skip_code,       /*tex glue at the start of the last line of paragraph */
302    par_fill_right_skip_code,      /*tex glue on last line of paragraph */
303    par_init_left_skip_code,
304    par_init_right_skip_code,
305    emergency_left_skip_code, 
306    emergency_right_skip_code,
307 /* indent_skip_code,           */ /*tex internal, might go away here */
308 /* left_hang_skip_code,        */ /*tex internal, might go away here */
309 /* right_hang_skip_code,       */ /*tex internal, might go away here */
310 /* correction_skip_code,       */ /*tex internal, might go away here */
311 /* inter_math_skip_code,       */ /*tex internal, might go away here */
312    math_skip_code,                /*tex glue before and after inline math */
313    math_threshold_code,
314    /*tex total number of glue parameters */
315    number_glue_pars,
316} glue_codes;
317
318# define first_glue_code line_skip_code
319# define last_glue_code  math_threshold_code
320
321/*tex 
322
323    In addition to the three original predefined muskip registers we have two more. These muskips 
324    are used in a symbolic way: by using a reference we can change their values on the fly and the 
325    engine will pick up the value set at the end of the formula (and use it in the second pass). 
326    In the other engines the threesome are hard coded into the atom pair spacing. 
327
328    In \LUAMETATEX\ we have a configurable system so these three registers are only used in the 
329    initialization, can be overloaded in the macro package, and are saved in the format file (as 
330    any other register). But there can be more than these. Before we had a way to link spacing to 
331    arbitrary registers (in the user's register space) we added |\tinymuskip| because we needed it. 
332    It is not used in initializations in the engine but is applied in the \CONTEXT\ format. We 
333    could throw it out and use just a user register now but we consider it part of the (updated) 
334    concept so it will stick around. Even more: we decided that a smaller one makes sense so end 
335    June 2022 Mikael and I decided to also provide |\pettymuskip| for which Mikael saw a good use 
336    case in the spacing in scripts between ordinary symbols and binary as well as relational ones. 
337
338    The Cambridge dictionary describes \quote {petty} as \quotation {not important and not worth 
339    giving attention to}, but of course we do! It's just that till not we never saw any request 
340    for an upgrade of the math (sub) engine, let alone that \TEX\ users bothered about the tiny 
341    and petty spacing artifacts (and posibilities) of the engine. Both internal registers are 
342    dedicated to Don Knuth who {\em does} pay a lot attentions to details but who of course will 
343    not use this engine and thereby not spoiled. So, they are there and at the same time they 
344    are not. But: in \CONTEXT\ they {\em are} definitely used!
345
346*/
347
348typedef enum muglue_codes {
349    zero_muskip_code,
350    petty_muskip_code,            /*tex petty space in math formula */
351    tiny_muskip_code,             /*tex tiny space in math formula */
352    thin_muskip_code,             /*tex thin space in math formula */
353    med_muskip_code,              /*tex medium space in math formula */
354    thick_muskip_code,            /*tex thick space in math formula */
355    /*tex total number of muskip parameters */
356    number_muglue_pars,
357} muglue_codes;
358
359# define first_muglue_code  petty_muskip_code
360# define last_muglue_code   thick_muskip_code
361
362typedef enum tok_codes {
363    output_routine_code,          /*tex points to token list for |\output| */
364    every_par_code,               /*tex points to token list for |\everypar| */
365    every_math_code,              /*tex points to token list for |\everymath| */
366    every_display_code,           /*tex points to token list for |\everydisplay| */
367    every_hbox_code,              /*tex points to token list for |\everyhbox| */
368    every_vbox_code,              /*tex points to token list for |\everyvbox| */
369    every_math_atom_code,         /*tex points to token list for |\everymathatom| */
370    every_job_code,               /*tex points to token list for |\everyjob|*/
371    every_cr_code,                /*tex points to token list for |\everycr| */
372    every_tab_code,               /*tex points to token list for |\everytab| */
373    error_help_code,              /*tex points to token list for |\errhelp|*/
374    every_before_par_code,        /*tex points to token list for |\everybeforepar| */
375    every_eof_code,               /*tex points to token list for |\everyeof| */
376    end_of_group_code,            /*tex collects end-of-group tokens, internal register */
377 // end_of_par_code,
378    /*tex total number of token parameters */
379    number_tok_pars,
380} tok_codes;
381
382# define first_toks_code output_routine_code
383# define last_toks_code  every_eof_code
384
385typedef enum specification_codes {
386    par_shape_code,               /*tex specifies paragraph shape, internal register */
387    par_passes_code,      
388    inter_line_penalties_code,    /*tex additional penalties between lines */
389    club_penalties_code,          /*tex penalties for creating club lines */
390    widow_penalties_code,         /*tex penalties for creating widow lines */
391    display_widow_penalties_code, /*tex ditto, just before a display */
392    orphan_penalties_code,
393    math_forward_penalties_code,
394    math_backward_penalties_code,
395    number_specification_pars,
396} specification_codes;
397
398# define first_specification_code par_shape_code
399# define last_specification_code  math_backward_penalties_code
400
401/*tex Beware: these are indices into |page_builder_state.page_so_far| array! */
402
403typedef enum page_property_codes {
404    page_goal_code,
405    page_vsize_code,
406    page_total_code,
407    page_depth_code,
408    page_excess_code,
409    page_last_height_code, /*tex These might become unsettable */
410    page_last_depth_code,  /*tex These might become unsettable */
411    dead_cycles_code,
412    insert_penalties_code,
413    insert_heights_code,
414    insert_storing_code, /* page */
415    insert_distance_code,
416    insert_multiplier_code,
417    insert_limit_code,
418    insert_storage_code, /* per insert */
419    insert_penalty_code,
420    insert_maxdepth_code,
421    insert_height_code,
422    insert_depth_code,
423    insert_width_code,
424    /*tex These can't be set: */
425    page_stretch_code,
426    page_fistretch_code,
427    page_filstretch_code,
428    page_fillstretch_code,
429    page_filllstretch_code,
430    page_shrink_code,
431    page_last_stretch_code,
432    page_last_fistretch_code,
433    page_last_filstretch_code,
434    page_last_fillstretch_code,
435    page_last_filllstretch_code,
436    page_last_shrink_code,
437} page_property_codes;
438
439# define first_page_property_code page_goal_code
440# define last_page_property_code  insert_width_code
441
442/*tex
443    We cheat: these previous bases are to really bases which is why math and del get separated by
444    one. See usage! Todo: group them better (also elsewhere in switches).
445*/
446
447typedef enum int_codes {
448    /* special ones */
449    par_direction_code,
450    math_direction_code,
451    text_direction_code,
452    line_direction_code,
453    cat_code_table_code,
454    glyph_scale_code,
455    glyph_x_scale_code,
456    glyph_y_scale_code,
457    glyph_slant_code,
458    glyph_weight_code,
459    glyph_text_scale_code,
460    glyph_script_scale_code,
461    glyph_scriptscript_scale_code,
462    math_begin_class_code,
463    math_end_class_code,
464    math_left_class_code,
465    math_right_class_code,
466    output_box_code,
467    new_line_char_code,
468    end_line_char_code,
469    language_code,
470    font_code,
471    hyphenation_mode_code,
472    uc_hyph_code,
473    local_interline_penalty_code,
474    local_broken_penalty_code,
475    local_tolerance_code,
476    local_pre_tolerance_code,
477    adjust_spacing_code,
478    protrude_chars_code,
479    glyph_options_code,
480    discretionary_options_code,
481    overload_mode_code,
482    post_binary_penalty_code,
483    post_relation_penalty_code,
484    pre_binary_penalty_code,
485    pre_relation_penalty_code,
486    eu_factor_code,
487    /* normal ones */
488    pre_tolerance_code,                 /*tex badness tolerance before hyphenation */
489    tolerance_code,                     /*tex badness tolerance after hyphenation */
490    line_penalty_code,                  /*tex added to the badness of every line */
491    hyphen_penalty_code,                /*tex penalty for break after discretionary hyphen */
492    ex_hyphen_penalty_code,             /*tex penalty for break after explicit hyphen */
493    club_penalty_code,                  /*tex penalty for creating a club line */
494    widow_penalty_code,                 /*tex penalty for creating a widow line */
495    display_widow_penalty_code,         /*tex ditto, just before a display */
496    broken_penalty_code,                /*tex penalty for breaking a page at a broken line */
497 // post_binary_penalty_code,           /*tex penalty for breaking after a binary operation */
498 // post_relation_penalty_code,         /*tex penalty for breaking after a relation */
499    pre_display_penalty_code,           /*tex penalty for breaking just before a displayed formula */
500    post_display_penalty_code,          /*tex penalty for breaking just after a displayed formula */
501    pre_inline_penalty_code,            /*tex penalty for breaking just before an inlined formula */
502    post_inline_penalty_code,           /*tex penalty for breaking just after an inlined formula */
503    pre_short_inline_penalty_code,      /*tex penalty for breaking just before a single character inlined formula */
504    post_short_inline_penalty_code,     /*tex penalty for breaking just after a single character inlined formula */
505    short_inline_orphan_penalty_code,
506    inter_line_penalty_code,            /*tex additional penalty between lines */
507    double_hyphen_demerits_code,        /*tex demerits for double hyphen break */
508    final_hyphen_demerits_code,         /*tex demerits for final hyphen break */
509    adj_demerits_code,                  /*tex demerits for adjacent incompatible lines with distance > 1 */
510    double_adj_demerits_code,           /*tex demerits for adjacent incompatible lines with distance > 0 */
511 /* mag_code,                        */ /*tex magnification ratio */
512    delimiter_factor_code,              /*tex ratio for variable-size delimiters */
513    looseness_code,                     /*tex change in number of lines for a paragraph */
514    time_code,                          /*tex current time of day */
515    day_code,                           /*tex current day of the month */
516    month_code,                         /*tex current month of the year */
517    year_code,                          /*tex current year of our Lord */
518    show_box_breadth_code,              /*tex nodes per level in |show_box| */
519    show_box_depth_code,                /*tex maximum level in |show_box| */
520    show_node_details_code,             /*tex controls subtype and attribute details */
521    hbadness_code,                      /*tex hboxes exceeding this badness will be shown by |hpack| */
522    vbadness_code,                      /*tex vboxes exceeding this badness will be shown by |vpack| */
523    pausing_code,                       /*tex pause after each line is read from a file */
524    tracing_online_code,                /*tex show diagnostic output on terminal */
525    tracing_macros_code,                /*tex show macros as they are being expanded */
526    tracing_stats_code,                 /*tex show memory usage if \TeX\ knows it */
527    tracing_paragraphs_code,            /*tex show line-break calculations */
528    tracing_pages_code,                 /*tex show page-break calculations */
529    tracing_output_code,                /*tex show boxes when they are shipped out */
530    tracing_lost_chars_code,            /*tex show characters that aren't in the font */
531    tracing_commands_code,              /*tex show command codes at |big_switch| */
532    tracing_restores_code,              /*tex show equivalents when they are restored */
533 // tracing_fonts_code,                   
534    tracing_assigns_code,               /*tex show assignments */
535    tracing_groups_code,                /*tex show save/restore groups */
536    tracing_ifs_code,                   /*tex show conditionals */
537    tracing_math_code,
538    tracing_levels_code,                /*tex show levels when tracing */
539    tracing_nesting_code,               /*tex show incomplete groups and ifs within files */
540    tracing_alignments_code,            /*tex show nesting of noalign and preambles */
541    tracing_inserts_code,               /*tex show some info about insert processing */
542    tracing_marks_code,                 /*tex show state of marks */
543    tracing_adjusts_code,               /*tex show state of marks */
544    tracing_hyphenation_code,           /*tex show some info regarding hyphenation */
545    tracing_expressions_code,           /*tex show some info regarding expressions */
546    tracing_nodes_code,                 /*tex show node numbers too */
547    tracing_full_boxes_code,            /*tex show [over/under]full boxes in the log */
548    tracing_penalties_code,   
549    tracing_lists_code,   
550    tracing_passes_code,   
551 // uc_hyph_code,                       /*tex hyphenate words beginning with a capital letter */
552    output_penalty_code,                /*tex penalty found at current page break */
553    max_dead_cycles_code,               /*tex bound on consecutive dead cycles of output */
554    hang_after_code,                    /*tex hanging indentation changes after this many lines */
555    floating_penalty_code,              /*tex penalty for insertions heldover after a split */
556    global_defs_code,                   /*tex override |\global| specifications */
557    family_code,                        /*tex current family */
558    escape_char_code,                   /*tex escape character for token output */
559    default_hyphen_char_code,           /*tex value of |\hyphenchar| when a font is loaded */
560    default_skew_char_code,             /*tex value of |\skewchar| when a font is loaded */
561 // end_line_char_code,                 /*tex character placed at the right end of the buffer */
562 // new_line_char_code,                 /*tex character that prints as |print_ln| */
563 // language_code,                      /*tex current language */
564 // font_code,                          /*tex current font */
565 // hyphenation_mode_code,
566    left_hyphen_min_code,               /*tex minimum left hyphenation fragment size */
567    right_hyphen_min_code,              /*tex minimum right hyphenation fragment size */
568    holding_inserts_code,               /*tex do not remove insertion nodes from |\box255| */
569    holding_migrations_code, 
570    error_context_lines_code,           /*tex maximum intermediate line pairs shown */
571 // local_interline_penalty_code,       /*tex local |\interlinepenalty| */
572 // local_broken_penalty_code,          /*tex local |\brokenpenalty| */
573 // local_tolerance_code,
574 // local_pre_tolerance_code,
575    no_spaces_code,
576    parameter_mode_code,
577 // glyph_scale_code,
578 // glyph_x_scale_code,
579 // glyph_y_scale_code,
580    glyph_data_code,
581    glyph_state_code,
582    glyph_script_code,
583 // glyph_options_code,
584 // glyph_text_scale_code,
585 // glyph_script_scale_code,
586 // glyph_scriptscript_scale_code,
587 // discretionary_options_code,
588 /* glue_data_code, */
589 // cat_code_table_code,
590 // output_box_code,
591    ex_hyphen_char_code,
592 // adjust_spacing_code,                /*tex level of spacing adjusting */
593    adjust_spacing_step_code,           /*tex level of spacing adjusting step */
594    adjust_spacing_stretch_code,        /*tex level of spacing adjusting stretch */
595    adjust_spacing_shrink_code,         /*tex level of spacing adjusting shrink */
596 // protrude_chars_code,                /*tex protrude chars at left/right edge of paragraphs */
597    pre_display_direction_code,         /*tex text direction preceding a display */
598    last_line_fit_code,                 /*tex adjustment for last line of paragraph */
599    saving_vdiscards_code,              /*tex save items discarded from vlists */
600    saving_hyph_codes_code,             /*tex save hyphenation codes for languages */
601    math_eqno_gap_step_code,            /*tex factor/1000 used for distance between eq and eqno */
602    math_display_skip_mode_code,
603    math_scripts_mode_code,
604    math_limits_mode_code,
605    math_nolimits_mode_code,
606    math_rules_mode_code,
607    math_rules_fam_code,
608    math_penalties_mode_code,
609    math_check_fences_mode_code,
610    math_slack_mode_code,
611    math_skip_mode_code,
612    math_double_script_mode_code,
613    math_font_control_code,
614    math_display_mode_code,
615    math_dict_group_code,
616    math_dict_properties_code,
617    math_pre_display_gap_factor_code,
618 // pre_binary_penalty_code,
619 // pre_relation_penalty_code,
620    first_valid_language_code,
621    automatic_hyphen_penalty_code,
622    explicit_hyphen_penalty_code,
623    exception_penalty_code,
624    copy_lua_input_nodes_code,
625    auto_migration_mode_code,
626    normalize_line_mode_code,
627    normalize_par_mode_code,
628    math_spacing_mode_code,
629    math_grouping_mode_code,
630    math_glue_mode_code,
631 // math_begin_class_code,
632 // math_end_class_code,
633 // math_left_class_code,
634 // math_right_class_code,
635    math_inline_penalty_factor_code,
636    math_display_penalty_factor_code,
637    sup_mark_mode_code,
638 // par_direction_code,
639 // text_direction_code,
640 // math_direction_code,
641 // line_direction_code, /*tex gets remapped so is no real register */
642 // overload_mode_code,
643    auto_paragraph_mode_code,
644    shaping_penalties_mode_code,
645    shaping_penalty_code,
646    orphan_penalty_code,
647    single_line_penalty_code,
648    alignment_cell_source_code,
649    alignment_wrap_source_code,
650 /* page_boundary_penalty_code, */
651    line_break_criterion_code,
652    line_break_passes_code,
653    line_break_optional_code,
654    /* 
655        This one was added as experiment to \LUATEX\ (answer to a forwarded question) but as it 
656        didn't get tested it will go away. \CONTEXT\ doesn't need it and we don't need to be 
657        compatible anyway. Lesson learned.
658    */
659    variable_family_code,
660 // eu_factor_code,
661    math_pre_tolerance_code,                
662    math_tolerance_code,                    
663    space_factor_mode,
664    space_factor_shrink_limit_code,
665    space_factor_stretch_limit_code,
666    box_limit_mode_code,
667    /* those below these are not interfaced via primitives */
668    internal_par_state_code,
669    internal_dir_state_code,
670    internal_math_style_code,
671    internal_math_scale_code,
672    /*tex total number of integer parameters */
673    first_math_class_code,
674    last_math_class_code = first_math_class_code + max_n_of_math_classes,
675    first_math_atom_code,
676    last_math_atom_code = first_math_atom_code + max_n_of_math_classes,
677    first_math_options_code,
678    last_math_options_code = first_math_options_code + max_n_of_math_classes,
679    first_math_parent_code,
680    last_math_parent_code = first_math_parent_code + max_n_of_math_classes,
681    first_math_pre_penalty_code,
682    last_math_pre_penalty_code = first_math_pre_penalty_code + max_n_of_math_classes,
683    first_math_post_penalty_code,
684    last_math_post_penalty_code = first_math_post_penalty_code + max_n_of_math_classes,
685    first_math_display_pre_penalty_code,
686    last_math_display_pre_penalty_code = first_math_display_pre_penalty_code + max_n_of_math_classes,
687    first_math_display_post_penalty_code,
688    last_math_display_post_penalty_code = first_math_display_post_penalty_code + max_n_of_math_classes,
689    first_math_ignore_code,
690    last_math_ignore_code = first_math_ignore_code + math_parameter_last,
691    /* */
692    number_integer_pars,
693} int_codes;
694
695# define first_integer_code pre_tolerance_code
696# define last_integer_code  box_limit_mode_code
697
698typedef enum dimension_codes {
699    /* normal ones */
700    par_indent_code,               /*tex indentation of paragraphs */
701    math_surround_code,            /*tex space around math in text */
702    line_skip_limit_code,          /*tex threshold for |line_skip| instead of |baseline_skip| */
703    hsize_code,                    /*tex line width in horizontal mode */
704    vsize_code,                    /*tex page height in vertical mode */
705    max_depth_code,                /*tex maximum depth of boxes on main pages */
706    split_max_depth_code,          /*tex maximum depth of boxes on split pages */
707    box_max_depth_code,            /*tex maximum depth of explicit vboxes */
708    hfuzz_code,                    /*tex tolerance for overfull hbox messages */
709    vfuzz_code,                    /*tex tolerance for overfull vbox messages */
710    delimiter_shortfall_code,      /*tex maximum amount uncovered by variable delimiters */
711    null_delimiter_space_code,     /*tex blank space in null delimiters */
712    script_space_code,             /*tex extra space after subscript or superscript */
713    pre_display_size_code,         /*tex length of text preceding a display */
714    display_width_code,            /*tex length of line for displayed equation */
715    display_indent_code,           /*tex indentation of line for displayed equation */
716    overfull_rule_code,            /*tex width of rule that identifies overfull hboxes */
717    hang_indent_code,              /*tex amount of hanging indentation */
718 /* h_offset_code,          */     /*tex amount of horizontal offset when shipping pages out */
719 /* v_offset_code,          */     /*tex amount of vertical offset when shipping pages out */
720    emergency_stretch_code,        /*tex reduces badnesses on final pass of line-breaking */
721    emergency_extra_stretch_code,  
722    glyph_x_offset_code,
723    glyph_y_offset_code,
724    px_dimension_code,             /*tex This is a historic one, not used but we keep it. */  
725    tab_size_code,
726    page_extra_goal_code,
727    ignore_depth_criterion_code,
728    short_inline_math_threshold_code,
729    /*tex total number of dimension parameters */
730    number_dimension_pars,
731} dimension_codes;
732
733# define first_dimension_code par_indent_code
734# define last_dimension_code  short_inline_math_threshold_code
735
736typedef enum attribute_codes {
737    /*tex total number of attribute parameters */
738    number_attribute_pars,
739} attribute_codes;
740
741typedef enum posit_codes {
742    /*tex total number of posit parameters */
743    number_posit_pars,
744} posit_codes;
745
746typedef enum unit_codes {
747    /*tex total number of unit parameters */
748    number_unit_pars,
749} unit_codes;
750
751
752// typedef enum special_sequence_codes {
753//  // current_font_sequence_code,
754//     undefined_control_sequence_code,
755//     n_of_special_sequences,
756// } special_sequence_codes;
757//
758// /* The last one is frozen_null_font. */
759//
760// # define special_sequence_base         (last_frozen_cs_loc + 1)
761// # define current_font_sequence         (special_sequence_base + current_font_sequence_code)
762// # define undefined_control_sequence    (special_sequence_base + undefined_control_sequence_code)
763// # define first_register_base           (special_sequence_base + n_of_special_sequences)
764
765# define undefined_control_sequence     deep_frozen_cs_undefined_code
766
767# define special_sequence_base          (last_deep_frozen_cs_location + 1)
768# define first_register_base            (last_deep_frozen_cs_location + 1)
769
770# define internal_glue_base             (first_register_base)
771# define register_glue_base             (internal_glue_base + number_glue_pars + 1)
772# define internal_glue_location(a)      (internal_glue_base + (a))
773# define register_glue_location(a)      (register_glue_base + (a))
774# define internal_glue_number(a)        ((a) - internal_glue_base)
775# define register_glue_number(a)        ((a) - register_glue_base)
776
777# define internal_muglue_base           (register_glue_base + max_n_of_glue_registers)
778# define register_muglue_base           (internal_muglue_base + number_muglue_pars + 1)
779# define internal_muglue_location(a)    (internal_muglue_base + (a))
780# define register_muglue_location(a)    (register_muglue_base + (a))
781# define internal_muglue_number(a)      ((a) - internal_muglue_base)
782# define register_muglue_number(a)      ((a) - register_muglue_base)
783
784# define internal_toks_base             (register_muglue_base + max_n_of_muglue_registers)
785# define register_toks_base             (internal_toks_base + number_tok_pars + 1)
786# define internal_toks_location(a)      (internal_toks_base + (a))
787# define register_toks_location(a)      (register_toks_base + (a))
788# define internal_toks_number(a)        ((a) - internal_toks_base)
789# define register_toks_number(a)        ((a) - register_toks_base)
790
791# define internal_box_base              (register_toks_base + max_n_of_toks_registers)
792# define register_box_base              (internal_box_base + number_box_pars + 1)
793# define internal_box_location(a)       (internal_box_base + (a))
794# define register_box_location(a)       (register_box_base + (a))
795# define internal_box_number(a)         ((a) - internal_box_base)
796# define register_box_number(a)         ((a) - register_box_base)
797
798# define internal_integer_base          (register_box_base + max_n_of_box_registers)
799# define register_integer_base          (internal_integer_base + number_integer_pars + 1)
800# define internal_integer_location(a)   (internal_integer_base + (a))
801# define register_integer_location(a)   (register_integer_base + (a))
802# define internal_integer_number(a)     ((a) - internal_integer_base)
803# define register_integer_number(a)     ((a) - register_integer_base)
804
805# define internal_attribute_base        (register_integer_base + max_n_of_integer_registers)
806# define register_attribute_base        (internal_attribute_base + number_attribute_pars + 1)
807# define internal_attribute_location(a) (internal_attribute_base + (a))
808# define register_attribute_location(a) (register_attribute_base + (a))
809# define internal_attribute_number(a)   ((a) - internal_attribute_base)
810# define register_attribute_number(a)   ((a) - register_attribute_base)
811
812# define internal_dimension_base        (register_attribute_base + max_n_of_attribute_registers)
813# define register_dimension_base        (internal_dimension_base + number_dimension_pars + 1)
814# define internal_dimension_location(a) (internal_dimension_base + (a))
815# define register_dimension_location(a) (register_dimension_base + (a))
816# define internal_dimension_number(a)   ((a) - internal_dimension_base)
817# define register_dimension_number(a)   ((a) - register_dimension_base)
818
819# define internal_posit_base            (register_dimension_base + max_n_of_dimension_registers)
820# define register_posit_base            (internal_posit_base + number_posit_pars + 1)
821# define internal_posit_location(a)     (internal_posit_base + (a))
822# define register_posit_location(a)     (register_posit_base + (a))
823# define internal_posit_number(a)       ((a) - internal_posit_base)
824# define register_posit_number(a)       ((a) - register_posit_base)
825
826# define internal_unit_base             (register_posit_base + max_n_of_posit_registers)
827# define internal_unit_location(a)      (internal_unit_base + (a))
828# define internal_unit_number(a)        ((a) - internal_unit_base)
829
830# define internal_specification_base        (internal_unit_base + max_n_of_unit_registers)
831# define internal_specification_location(a) (internal_specification_base + (a))
832# define internal_specification_number(a)   ((a) - internal_specification_base)
833
834# define eqtb_size       (internal_specification_base + number_specification_pars)
835# define eqtb_max_so_far (eqtb_size + lmt_hash_state.hash_data.ptr + 1)
836
837/* below: top or ptr +1 ? */
838
839# define eqtb_indirect_range(n) ((n < internal_glue_base) || ((n > eqtb_size) && (n <= lmt_hash_state.hash_data.top)))
840# define eqtb_out_of_range(n)   ((n >= undefined_control_sequence) && ((n <= eqtb_size) || n > lmt_hash_state.hash_data.top))
841# define eqtb_invalid_cs(n)     ((n == 0) || (n > lmt_hash_state.hash_data.top) || ((n > frozen_control_sequence) && (n <= eqtb_size)))
842
843# define character_in_range(i)  (i >= 0 && i <= max_character_code)
844# define catcode_in_range(i)    (i >= 0 && i <= max_category_code)
845# define family_in_range(i)     (i >= 0 && i <= max_math_family_index)
846# define class_in_range(i)      (i >= 0 && i <= max_math_class_code)
847# define half_in_range(i)       (i >= 0 && i <= max_half_value)
848# define box_index_in_range(i)  (i >= 0 && i <= max_box_index)
849
850/* These also have funny offsets: */
851
852typedef enum align_codes  {
853    tab_mark_code,
854    span_code,
855    omit_code,
856    align_content_code,
857    no_align_code,
858    cr_code,
859    cr_cr_code,
860} align_codes;
861
862/*
863    typedef struct equivalents_state_info {
864    } equivalents_state_info ;
865
866    extern equivalents_state_info lmt_equivalents_state;
867*/
868
869extern void tex_initialize_levels       (void);
870extern void tex_initialize_equivalents  (void);
871extern void tex_synchronize_equivalents (void);
872extern void tex_initialize_undefined_cs (void);
873extern void tex_dump_equivalents_mem    (dumpstream f);
874extern void tex_undump_equivalents_mem  (dumpstream f);
875
876/*tex
877    The more low level |_field| shortcuts are used when we (for instance) work with copies, as done
878    in the save stack entries. In most cases we use the second triplet of shortcuts. We replaced
879    |equiv(A)| and |equiv_value(A)| by |eq_value(A)}|.
880*/
881
882# define eq_level_field(A) (A).quart01
883# define eq_full_field(A)  (A).quart00
884# define eq_type_field(A)  (A).single00
885# define eq_flag_field(A)  (A).single01
886# define eq_value_field(A) (A).half1
887
888# define eq_level(A)       lmt_hash_state.eqtb[(A)].quart01  /*tex level of definition */
889# define eq_full(A)        lmt_hash_state.eqtb[(A)].quart00  /*tex command code for equivalent */
890# define eq_type(A)        lmt_hash_state.eqtb[(A)].single00 /*tex command code for equivalent */
891# define eq_flag(A)        lmt_hash_state.eqtb[(A)].single01
892# define eq_value(A)       lmt_hash_state.eqtb[(A)].half1
893
894# define set_eq_level(A,B) lmt_hash_state.eqtb[(A)].quart01  = (quarterword) (B)
895# define set_eq_type(A,B)  lmt_hash_state.eqtb[(A)].single00 = (singleword) (B)
896# define set_eq_flag(A,B)  lmt_hash_state.eqtb[(A)].single01 = (singleword) (B)
897# define set_eq_value(A,B) lmt_hash_state.eqtb[(A)].half1    = (B)
898
899# define copy_eqtb_entry(target,source) lmt_hash_state.eqtb[target] = lmt_hash_state.eqtb[source]
900
901# define equal_eqtb_entries(A,B) ( \
902    (lmt_hash_state.eqtb[(A)].half0 == lmt_hash_state.eqtb[(B)].half0) \
903 && (lmt_hash_state.eqtb[(A)].half1 == lmt_hash_state.eqtb[(B)].half1) \
904)
905
906/*tex
907
908    Because we operate in 64 bit we padd with a halfword, and because if that we have an extra field. Now,
909    because we already no longer need the parallel eqtb level table, we can use this field to store the
910    value alongside which makes that we can turn the dual slot |restore_old_value| and |saved_eqtb| into
911    one which in turn makes stack usage shrink. The performance gain is probably neglectable.
912
913*/
914
915typedef struct save_record {
916    union { 
917        quarterword saved_level; 
918        quarterword saved_group; 
919        quarterword saved_record; 
920    };
921    quarterword saved_type;    
922    union { 
923        halfword saved_value;  
924        halfword saved_value_1; 
925    };
926    union { 
927        memoryword saved_word;
928        struct { 
929            halfword saved_value_2;
930            halfword saved_value_3;
931        };
932    };
933} save_record;
934
935typedef struct save_state_info {
936    save_record *save_stack;
937    memory_data  save_stack_data;
938    quarterword  current_level;        /*tex current nesting level for groups */
939    quarterword  current_group;        /*tex current group type */
940    int          current_boundary;     /*tex where the current level begins */
941 // int          padding;
942} save_state_info;
943
944extern save_state_info lmt_save_state;
945
946# define cur_level    lmt_save_state.current_level
947# define cur_group    lmt_save_state.current_group
948# define cur_boundary lmt_save_state.current_boundary
949
950/*tex
951
952    We use the notation |saved(k)| to stand for an item that appears in location |save_ptr + k| of
953    the save stack. The level field is also available for other purposes, so we have |extra| as an 
954    more generic alias.
955
956*/
957
958# define save_type(A)    lmt_save_state.save_stack[A].saved_type     /*tex classifies a |save_stack| entry */
959# define save_record(A)  lmt_save_state.save_stack[A].saved_record
960# define save_level(A)   lmt_save_state.save_stack[A].saved_level    /*tex saved level for regions 5 and 6, or group code, or ...  */
961# define save_group(A)   lmt_save_state.save_stack[A].saved_group 
962
963# define save_value(A)   lmt_save_state.save_stack[A].saved_value    /*tex |eqtb| location or token or |save_stack| location or ... */
964# define save_word(A)    lmt_save_state.save_stack[A].saved_word     /*tex |eqtb| entry */
965
966# define save_value_1(A) lmt_save_state.save_stack[A].saved_value_1
967# define save_value_2(A) lmt_save_state.save_stack[A].saved_value_2
968# define save_value_3(A) lmt_save_state.save_stack[A].saved_value_3
969
970# define saved_type(A)    lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_type
971# define saved_record(A)  lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_record
972# define saved_level(A)   lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_level
973# define saved_group(A)   lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_group
974
975# define saved_value_1(A) lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_value_1
976# define saved_value_2(A) lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_value_2
977# define saved_value_3(A) lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_value_3
978
979# define reserved_save_stack_slots 32 /* plenty reserve */
980
981/*tex
982
983    The rather explicit |save_| items indicate a type. They are sometimes used to lookup a specific
984    field (when tracing).
985
986    The save stack is now a bit more hybrid because we use |memoryword| for |value_2| and |value_3|
987    so this will be cleaned up a bit.  
988
989*/
990
991typedef enum save_types {
992    /* recovery entries */
993    restore_old_value_save_type, /*tex a value should be restored later */
994    restore_zero_save_type,      /*tex an undefined entry should be restored */
995    insert_tokens_save_type,
996    restore_lua_save_type,
997    level_boundary_save_type,    /*tex the beginning of a group */
998    /* data entries */
999    saved_record_0,
1000    saved_record_1,
1001    saved_record_2,
1002    saved_record_3,
1003    saved_record_4,
1004    saved_record_5,
1005    saved_record_6,
1006    saved_record_7,
1007    saved_record_8,
1008    saved_record_9,
1009} save_types;
1010
1011typedef enum save_record_types {
1012    unknown_save_type,
1013    box_save_type,
1014    local_box_save_type,
1015    alignment_save_type,
1016    adjust_save_type,
1017    math_save_type,
1018    fraction_save_type,
1019    radical_save_type,
1020    operator_save_type,
1021    math_group_save_type,
1022    choice_save_type,
1023    number_save_type,
1024    insert_save_type,
1025    discretionary_save_type,
1026} save_record_types;
1027
1028/*tex Nota bena: |equiv_value| is the same as |equiv| but sometimes we use that name instead. */
1029
1030// int_par(A) hash_state.eqtb_i_i[(A)].half1
1031
1032# define integer_parameter(A)       eq_value(internal_integer_location(A))
1033# define posit_parameter(A)         eq_value(internal_posit_location(A))
1034# define attribute_parameter(A)     eq_value(internal_attribute_location(A))
1035# define dimension_parameter(A)     eq_value(internal_dimension_location(A))
1036# define toks_parameter(A)          eq_value(internal_toks_location(A))
1037# define glue_parameter(A)          eq_value(internal_glue_location(A))
1038# define muglue_parameter(A)        eq_value(internal_muglue_location(A))
1039# define box_parameter(A)           eq_value(internal_box_location(A))
1040# define specification_parameter(A) eq_value(internal_specification_location(A))
1041# define unit_parameter(A)          eq_value(internal_unit_location(A))
1042
1043# define count_parameter   integer_parameter
1044# define dimen_parameter   dimension_parameter
1045# define skip_parameter    glue_parameter
1046# define muskip_parameter  muglue_parameter
1047
1048# define unit_parameter_hash(l,r)   (26 * (l - 'a') + (r - 'a'))
1049
1050typedef enum unit_classes {
1051    unset_unit_class      = 0, 
1052    tex_unit_class        = 1, 
1053    pdftex_unit_class     = 2, 
1054    luametatex_unit_class = 3, 
1055    user_unit_class       = 4, 
1056} unit_classes;
1057
1058inline static int unit_parameter_index(int l, int r) {
1059    if (l >= 'a' && l <= 'z' && r >= 'a' && r <= 'z') { 
1060        return unit_parameter_hash(l,r);
1061    } else { 
1062        l |= 0x60;
1063        r |= 0x60;
1064        if (l >= 'a' && l <= 'z' && r >= 'a' && r <= 'z') { 
1065            return unit_parameter_hash(l,r);
1066        } else { 
1067            return -1;
1068        }
1069    }
1070}
1071
1072/*tex These come from |\ALEPH| aka |\OMEGA|: */
1073
1074# define is_valid_local_box_code(c) (c >= first_local_box_code && c <= last_local_box_code)
1075
1076/*tex
1077
1078    Here are the group codes that are used to discriminate between different kinds of groups. They
1079    allow \TEX\ to decide what special actions, if any, should be performed when a group ends.
1080
1081    Some groups are not supposed to be ended by right braces. For example, the |$| that begins a
1082    math formula causes a |math_shift_group| to be started, and this should be terminated by a
1083    matching |$|. Similarly, a group that starts with |\left| should end with |\right|, and one
1084    that starts with |\begingroup| should end with |\endgroup|.
1085
1086*/
1087
1088typedef enum tex_group_codes {
1089    bottom_level_group,  /*tex group code for the outside world */
1090    simple_group,        /*tex group code for local structure only */
1091    hbox_group,          /*tex code for |\hbox| */
1092    adjusted_hbox_group, /*tex code for |\hbox| in vertical mode */
1093    vbox_group,          /*tex code for |\vbox| */
1094    vtop_group,          /*tex code for |\vtop| */
1095    dbox_group,          /*tex code for |\dbox| */
1096    align_group,         /*tex code for |\halign|, |\valign| */
1097    no_align_group,      /*tex code for |\noalign| */
1098    output_group,        /*tex code for output routine */
1099    math_group,          /*tex code for, e.g., |\char'136| */
1100    math_stack_group,
1101    math_component_group,
1102    discretionary_group, /*tex code for |\discretionary|' */
1103    insert_group,        /*tex code for |\insert| */
1104    vadjust_group,       /*tex code for |\vadjust| */
1105    vcenter_group,       /*tex code for |\vcenter| */
1106    math_fraction_group, /*tex code for |\over| and friends */
1107    math_operator_group,
1108    math_radical_group,
1109    math_choice_group,   /*tex code for |\mathchoice| */
1110    also_simple_group,   /*tex code for |\begingroup|\unknown|\egroup| */
1111    semi_simple_group,   /*tex code for |\begingroup|\unknown|\endgroup| */
1112    math_simple_group,   /*tex code for |\beginmathgroup|\unknown|\endmathgroup| */
1113    math_fence_group,    /*tex code for fences |\left|\unknown|\right| */
1114    math_inline_group,   
1115    math_display_group,  
1116    math_number_group,     
1117    local_box_group,     /*tex code for |\localleftbox|\unknown|localrightbox| */
1118    split_off_group,     /*tex box code for the top part of a |\vsplit| */
1119    split_keep_group,    /*tex box code for the bottom part of a |\vsplit| */
1120    preamble_group,      /*tex box code for the preamble processing  in an alignment */
1121    align_set_group,     /*tex box code for the final item pass in an alignment */
1122    finish_row_group,    /*tex box code for a provisory line in an alignment */
1123    lua_group,
1124} tex_group_codes;
1125
1126inline static void tex_aux_show_group_count(int n)
1127{
1128    for (int i = 1; i <= n; i++) {
1129        tex_print_str("{}");
1130    }
1131}
1132
1133/*
1134    In the end I decided to split them into context and begin, but maybe some day
1135    they all merge into one (easier on tracing and reporting in shared helpers).
1136*/
1137
1138typedef enum tex_par_context_codes {
1139    normal_par_context,
1140    vmode_par_context,
1141    vbox_par_context,
1142    vtop_par_context,
1143    dbox_par_context,
1144    vcenter_par_context,
1145    vadjust_par_context,
1146    insert_par_context,
1147    output_par_context,
1148    align_par_context,
1149    no_align_par_context,
1150    span_par_context,
1151    reset_par_context,
1152} tex_par_context_codes;
1153
1154typedef enum tex_alignment_context_codes {
1155    preamble_pass_alignment_context,
1156    preroll_pass_alignment_context,
1157    package_pass_alignment_context,
1158    wrapup_pass_alignment_context,
1159} tex_alignment_context_codes;
1160
1161typedef enum tex_breaks_context_codes {
1162    initialize_show_breaks_context,
1163    start_show_breaks_context,
1164    list_show_breaks_context,
1165    stop_show_breaks_context,
1166    collect_show_breaks_context,
1167    line_show_breaks_context,
1168    delete_show_breaks_context,
1169    report_show_breaks_context,
1170    wrapup_show_breaks_context,
1171} tex_breaks_context_codes;
1172
1173typedef enum tex_build_context_codes {
1174    initialize_show_build_context,
1175    step_show_build_context,
1176    check_show_build_context,
1177    skip_show_build_context,
1178    move_show_build_context,
1179    fireup_show_build_context,
1180    wrapup_show_build_context,
1181} tex_build_context_codes;
1182
1183typedef enum tex_page_context_codes {
1184    box_page_context,
1185    end_page_context,
1186    vadjust_page_context,
1187    penalty_page_context,
1188    boundary_page_context,
1189    insert_page_context,
1190    hmode_par_page_context,
1191    vmode_par_page_context,
1192    begin_paragraph_page_context,
1193    before_display_page_context,
1194    after_display_page_context,
1195    after_output_page_context,
1196    alignment_page_context,
1197    triggered_page_context
1198} tex_page_context_codes;
1199
1200typedef enum tex_append_line_context_codes {
1201    box_append_line_context,
1202    pre_box_append_line_context,
1203    pre_adjust_append_line_context,
1204    post_adjust_append_line_context,
1205    pre_migrate_append_line_context,
1206    post_migrate_append_line_context,
1207} tex_append_line_context_codes;
1208
1209typedef enum tex_par_trigger_codes {
1210    normal_par_trigger,
1211    force_par_trigger,
1212    indent_par_trigger,
1213    no_indent_par_trigger,
1214    math_char_par_trigger,
1215    char_par_trigger,
1216    boundary_par_trigger,
1217    space_par_trigger,
1218    math_par_trigger,
1219    kern_par_trigger,
1220    hskip_par_trigger,
1221    un_hbox_char_par_trigger,
1222    valign_char_par_trigger,
1223    vrule_char_par_trigger,
1224} tex_par_trigger_codes;
1225
1226typedef enum tex_tracing_levels_codes {
1227    tracing_levels_group    = 0x01,
1228    tracing_levels_input    = 0x02,
1229    tracing_levels_catcodes = 0x04,
1230} tex_tracing_levels_codes;
1231
1232extern void tex_initialize_save_stack  (void);
1233/*     int  tex_room_on_save_stack     (void); */
1234extern void tex_save_halfword_on_stack (quarterword t, halfword v);
1235extern void tex_show_cmd_chr           (halfword cmd, halfword chr);
1236extern void tex_new_save_level         (quarterword group);                        /*tex begin a new level of grouping */
1237extern int  tex_saved_line_at_level    (void);
1238extern void tex_eq_define              (halfword p, singleword cmd, halfword chr); /*tex new data for |eqtb| */
1239extern void tex_eq_word_define         (halfword p, int w);
1240extern void tex_geq_define             (halfword p, singleword cmd, halfword chr); /*tex global |eq_define| */
1241extern void tex_geq_word_define        (halfword p, int w);                        /*tex global |eq_word_define| */
1242extern void tex_save_for_after_group   (halfword t);
1243extern void tex_unsave                 (void);                                     /*tex pops the top level off the save stack */
1244extern void tex_show_save_groups       (void);
1245extern int  tex_located_save_value     (int id);
1246extern void tex_show_save_stack        (void);
1247
1248/*tex
1249
1250    The |prefixed_command| does not have to adjust |a| so that |a mod 4 = 0|, since the following
1251    routines test for the |\global| prefix as follows. Anyway, in the meantime we reshuffled the
1252    bits and changed a lot.
1253
1254    When we need more bits, we will do this:
1255
1256    One one of these:
1257
1258    \starttyping
1259    primitive_flag   = 00000001 : cannot be changed  system set
1260    permanent_flag   = 00000010 : cannot be changed  \permanent
1261    immutable_flag   = 00000011 : cannot be changed  \immutable
1262    frozen_flag      = 00000100 : can be overloaded  \frozen and \overloaded
1263    mutable_flag     = 00000101 : never checked      \mutable
1264    reserved_1_flag  = 00000110
1265    \stoptyping
1266
1267    Independent, not used combined:
1268
1269    \starttyping
1270    noaligned_flag   = 00001000 : valid align peek   \noaligned (can be more generic: \alignpeekable or \alignable, also span and omit?)
1271    reserved_3_flag  = 00010000 : maybe obsolete indicator
1272    \stoptyping
1273
1274    Informative:
1275
1276    \starttyping
1277    instance_flag    = 00100000 : just a tag         \instance
1278    symbol_flag      = 01000000 : just a tag         \symbolic (or character)
1279    c_quantity_flag  = 01100000
1280    d_quantity-flag  = 10000000
1281    reserved_4_flag  = 10100000
1282    reserved_5_flag  = 11100000
1283    \stoptyping
1284
1285    Maybe names like \flaginstance \flagpermanent etc are better? Now we run out of meaningful
1286    prefixes. Also testing the prefix then becomes more work.
1287
1288*/
1289
1290typedef enum flag_bit {
1291    /* properties and prefixes */
1292    frozen_flag_bit        = 0x000001,
1293    permanent_flag_bit     = 0x000002,
1294    immutable_flag_bit     = 0x000004,
1295    primitive_flag_bit     = 0x000008,
1296    mutable_flag_bit       = 0x000010,
1297    noaligned_flag_bit     = 0x000020,
1298    instance_flag_bit      = 0x000040,
1299    untraced_flag_bit      = 0x000080,
1300    /* prefixes */
1301    global_flag_bit        = 0x000100,
1302    tolerant_flag_bit      = 0x000200,
1303    protected_flag_bit     = 0x000400,
1304    overloaded_flag_bit    = 0x000800,
1305    aliased_flag_bit       = 0x001000,
1306    immediate_flag_bit     = 0x002000,
1307    conditional_flag_bit   = 0x004000,
1308    value_flag_bit         = 0x008000,
1309    semiprotected_flag_bit = 0x010000,
1310    inherited_flag_bit     = 0x020000,
1311    constant_flag_bit      = 0x040000,
1312    deferred_flag_bit      = 0x080000, /* this might move up */
1313    retained_flag_bit      = 0x100000,
1314    constrained_flag_bit   = 0x200000,
1315} flag_bits;
1316
1317/*tex Flags: */
1318
1319# define add_flag(a,b)              ((a) | (b))
1320
1321# define add_frozen_flag(a)         ((a) | frozen_flag_bit)
1322# define add_permanent_flag(a)      ((a) | permanent_flag_bit)
1323# define add_immutable_flag(a)      ((a) | immutable_flag_bit)
1324# define add_primitive_flag(a)      ((a) | primitive_flag_bit)
1325# define add_mutable_flag(a)        ((a) | mutable_flag_bit)
1326# define add_noaligned_flag(a)      ((a) | noaligned_flag_bit)
1327# define add_instance_flag(a)       ((a) | instance_flag_bit)
1328# define add_untraced_flag(a)       ((a) | untraced_flag_bit)
1329
1330# define add_global_flag(a)         ((a) | global_flag_bit)
1331# define add_tolerant_flag(a)       ((a) | tolerant_flag_bit)
1332# define add_protected_flag(a)      ((a) | protected_flag_bit)
1333# define add_semiprotected_flag(a)  ((a) | semiprotected_flag_bit)
1334# define add_overloaded_flag(a)     ((a) | overloaded_flag_bit)
1335# define add_aliased_flag(a)        ((a) | aliased_flag_bit)
1336# define add_immediate_flag(a)      ((a) | immediate_flag_bit)
1337# define add_deferred_flag(a)       ((a) | deferred_flag_bit)
1338# define add_conditional_flag(a)    ((a) | conditional_flag_bit)
1339# define add_value_flag(a)          ((a) | value_flag_bit)
1340# define add_inherited_flag(a)      ((a) | inherited_flag_bit)
1341# define add_constant_flag(a)       ((a) | constant_flag_bit)
1342# define add_retained_flag(a)       ((a) | retained_flag_bit)
1343# define add_constrained_flag(a)    ((a) | constrained_flag_bit)
1344
1345# define remove_flag(a,b)           ((a) & ~(b))
1346
1347# define remove_frozen_flag(a)      ((a) & ~frozen_flag_bit)
1348# define remove_permanent_flag(a)   ((a) & ~permanent_flag_bit)
1349# define remove_immutable_flag(a)   ((a) & ~immutable_flag_bit)
1350# define remove_primitive_flag(a)   ((a) & ~primitive_flag_bit)
1351# define remove_mutable_flag(a)     ((a) & ~mutable_flag_bit)
1352# define remove_noaligned_flag(a)   ((a) & ~noaligned_flag_bit)
1353# define remove_instance_flag(a)    ((a) & ~instance_flag_bit)
1354# define remove_untraced_flag(a)    ((a) & ~untraced_flag_bit)
1355
1356# define remove_global_flag(a)      ((a) & ~global_flag_bit)
1357# define remove_tolerant_flag(a)    ((a) & ~tolerant_flag_bit)
1358# define remove_protected_flag(a)   ((a) & ~protected_flag_bit)
1359# define remove_overloaded_flag(a)  ((a) & ~overloaded_flag_bit)
1360# define remove_aliased_flag(a)     ((a) & ~aliased_flag_bit)
1361# define remove_immediate_flag(a)   ((a) & ~immediate_flag_bit)
1362# define remove_deferred_flag(a)    ((a) & ~deferred_flag_bit)
1363# define remove_conditional_flag(a) ((a) & ~conditional_flag_bit)
1364# define remove_value_flag(a)       ((a) & ~value_flag_bit)
1365
1366# define is_frozen(a)               (((a) & frozen_flag_bit))
1367# define is_permanent(a)            (((a) & permanent_flag_bit))
1368# define is_immutable(a)            (((a) & immutable_flag_bit))
1369# define is_primitive(a)            (((a) & primitive_flag_bit))
1370# define is_mutable(a)              (((a) & mutable_flag_bit))
1371# define is_noaligned(a)            (((a) & noaligned_flag_bit))
1372# define is_instance(a)             (((a) & instance_flag_bit))
1373# define is_untraced(a)             (((a) & untraced_flag_bit))
1374
1375# define is_global(a)               (((a) & global_flag_bit))
1376# define is_tolerant(a)             (((a) & tolerant_flag_bit))
1377# define is_protected(a)            (((a) & protected_flag_bit))
1378# define is_semiprotected(a)        (((a) & semiprotected_flag_bit))
1379# define is_overloaded(a)           (((a) & overloaded_flag_bit))
1380# define is_aliased(a)              (((a) & aliased_flag_bit))
1381# define is_immediate(a)            (((a) & immediate_flag_bit))
1382# define is_deferred(a)             (((a) & deferred_flag_bit))
1383# define is_conditional(a)          (((a) & conditional_flag_bit))
1384# define is_value(a)                (((a) & value_flag_bit))
1385# define is_inherited(a)            (((a) & inherited_flag_bit))
1386# define is_constant(a)             (((a) & constant_flag_bit))
1387# define is_retained(a)             (((a) & retained_flag_bit))
1388# define is_constrained(a)          (((a) & constrained_flag_bit))
1389
1390# define is_expandable(cmd)         (cmd > max_command_cmd)
1391
1392# define global_or_local(a)         (is_global(a) ? level_one : cur_level)
1393
1394# define has_flag_bits(p,a)         ((p) & (a))
1395
1396# define remove_overload_flags(a)   ((a) & ~(permanent_flag_bit | immutable_flag_bit | primitive_flag_bit))
1397
1398# define make_eq_flag_bits(a)       ((singleword) ((a) & 0xFF))
1399# define has_eq_flag_bits(p,a)      (eq_flag(p) & (a))
1400# define set_eq_flag_bits(p,a)      set_eq_flag(p, make_eq_flag_bits(a))
1401
1402static inline singleword tex_flags_to_cmd(int flags)
1403{
1404    if (is_constant(flags)) {
1405        return constant_call_cmd;
1406    } else if (is_tolerant(flags)) {
1407        return is_protected    (flags) ? tolerant_protected_call_cmd :
1408              (is_semiprotected(flags) ? tolerant_semi_protected_call_cmd : tolerant_call_cmd);
1409    } else {
1410        return is_protected    (flags) ? protected_call_cmd :
1411              (is_semiprotected(flags) ? semi_protected_call_cmd : call_cmd);
1412    }
1413}
1414
1415/*tex
1416    The macros and functions for the frozen, tolerant, protected cmd codes are gone but
1417    can be found in the archive. We now have just one |call_cmd| with properties stored
1418    elsewhere.
1419
1420    int g -> singleword g
1421*/
1422
1423extern int  tex_define_permitted   (halfword cs, halfword prefixes);
1424extern void tex_define             (int g, halfword p, singleword cmd, halfword chr);
1425extern void tex_define_again       (int g, halfword p, singleword cmd, halfword chr);
1426extern void tex_define_inherit     (int g, halfword p, singleword flag, singleword cmd, halfword chr);
1427extern void tex_define_swapped     (int g, halfword p1, halfword p2, int force);
1428extern void tex_forced_define      (int g, halfword p, singleword flag, singleword cmd, halfword chr);
1429extern void tex_word_define        (int g, halfword p, halfword w);
1430/*     void tex_forced_word_define (int g, halfword p, singleword flag, halfword w); */
1431
1432/*tex
1433
1434    The |*_par| macros expand to the variables that are (in most cases) also accessible at the users
1435    end. Most are registers but some are in the (stack) lists. More |*_par| will move here: there is
1436    no real need for these macros but because there were already a bunch and because they were defined
1437    all over the place we moved them here.
1438
1439*/
1440
1441# define space_skip_par                  glue_parameter(space_skip_code)
1442# define xspace_skip_par                 glue_parameter(xspace_skip_code)
1443# define math_skip_par                   glue_parameter(math_skip_code)
1444# define math_skip_mode_par              integer_parameter(math_skip_mode_code)
1445# define math_double_script_mode_par     integer_parameter(math_double_script_mode_code)
1446# define math_font_control_par           integer_parameter(math_font_control_code)
1447# define math_display_mode_par           integer_parameter(math_display_mode_code)
1448# define math_dict_group_par             integer_parameter(math_dict_group_code)
1449# define math_dict_properties_par        integer_parameter(math_dict_properties_code)
1450# define math_threshold_par              glue_parameter(math_threshold_code)
1451# define page_extra_goal_par             dimension_parameter(page_extra_goal_code)
1452# define initial_page_skip_par           glue_parameter(initial_page_skip_code)
1453# define initial_top_skip_par            glue_parameter(initial_top_skip_code)
1454# define additional_page_skip_par        glue_parameter(additional_page_skip_code)
1455
1456# define pre_display_size_par            dimension_parameter(pre_display_size_code)
1457# define display_width_par               dimension_parameter(display_width_code)
1458# define display_indent_par              dimension_parameter(display_indent_code)
1459# define math_surround_par               dimension_parameter(math_surround_code)
1460
1461# define display_skip_mode_par           integer_parameter(math_display_skip_mode_code)
1462# define math_eqno_gap_step_par          integer_parameter(math_eqno_gap_step_code)
1463
1464# define par_direction_par               integer_parameter(par_direction_code)
1465# define text_direction_par              integer_parameter(text_direction_code)
1466# define math_direction_par              integer_parameter(math_direction_code)
1467
1468# define first_valid_language_par        integer_parameter(first_valid_language_code)
1469
1470# define hsize_par                       dimension_parameter(hsize_code)
1471# define vsize_par                       dimension_parameter(vsize_code)
1472# define hfuzz_par                       dimension_parameter(hfuzz_code)
1473# define vfuzz_par                       dimension_parameter(vfuzz_code)
1474# define hbadness_par                    integer_parameter(hbadness_code)
1475# define vbadness_par                    integer_parameter(vbadness_code)
1476
1477# define baseline_skip_par               glue_parameter(baseline_skip_code)
1478# define line_skip_par                   glue_parameter(line_skip_code)
1479# define par_indent_par                  dimension_parameter(par_indent_code)
1480# define hang_indent_par                 dimension_parameter(hang_indent_code)
1481# define hang_after_par                  integer_parameter(hang_after_code)
1482# define left_skip_par                   glue_parameter(left_skip_code)
1483# define right_skip_par                  glue_parameter(right_skip_code)
1484# define par_fill_left_skip_par          glue_parameter(par_fill_left_skip_code)
1485# define par_fill_right_skip_par         glue_parameter(par_fill_right_skip_code)
1486# define par_init_left_skip_par          glue_parameter(par_init_left_skip_code)
1487# define par_init_right_skip_par         glue_parameter(par_init_right_skip_code)
1488# define emergency_left_skip_par         glue_parameter(emergency_left_skip_code)
1489# define emergency_right_skip_par        glue_parameter(emergency_right_skip_code)
1490# define tab_skip_par                    glue_parameter(tab_skip_code)
1491
1492# define emergency_stretch_par           dimension_parameter(emergency_stretch_code)
1493# define emergency_extra_stretch_par     dimension_parameter(emergency_extra_stretch_code)
1494# define pre_tolerance_par               integer_parameter(pre_tolerance_code)
1495# define tolerance_par                   integer_parameter(tolerance_code)
1496# define looseness_par                   integer_parameter(looseness_code)
1497# define math_pre_tolerance_par          integer_parameter(math_pre_tolerance_code)
1498# define math_tolerance_par              integer_parameter(math_tolerance_code)
1499# define adjust_spacing_par              integer_parameter(adjust_spacing_code)
1500# define adjust_spacing_step_par         integer_parameter(adjust_spacing_step_code)
1501# define adjust_spacing_stretch_par      integer_parameter(adjust_spacing_stretch_code)
1502# define adjust_spacing_shrink_par       integer_parameter(adjust_spacing_shrink_code)
1503# define adj_demerits_par                integer_parameter(adj_demerits_code)
1504# define double_adj_demerits_par         integer_parameter(double_adj_demerits_code)
1505# define protrude_chars_par              integer_parameter(protrude_chars_code)
1506# define line_penalty_par                integer_parameter(line_penalty_code)
1507# define last_line_fit_par               integer_parameter(last_line_fit_code)
1508# define double_hyphen_demerits_par      integer_parameter(double_hyphen_demerits_code)
1509# define final_hyphen_demerits_par       integer_parameter(final_hyphen_demerits_code)
1510# define inter_line_penalty_par          integer_parameter(inter_line_penalty_code)
1511# define club_penalty_par                integer_parameter(club_penalty_code)
1512# define widow_penalty_par               integer_parameter(widow_penalty_code)
1513# define display_widow_penalty_par       integer_parameter(display_widow_penalty_code)
1514# define orphan_penalty_par              integer_parameter(orphan_penalty_code)
1515# define single_line_penalty_par         integer_parameter(single_line_penalty_code)
1516/*define page_boundary_penalty_par       integer_parameter(page_boundary_penalty_code) */ /* now in |\pageboundary| */
1517# define line_break_criterion_par        integer_parameter(line_break_criterion_code)
1518# define line_break_passes_par           integer_parameter(line_break_passes_code)
1519# define line_break_optional_par         integer_parameter(line_break_optional_code)
1520# define broken_penalty_par              integer_parameter(broken_penalty_code)
1521# define line_skip_limit_par             dimension_parameter(line_skip_limit_code)
1522
1523# define alignment_cell_source_par       integer_parameter(alignment_cell_source_code)
1524# define alignment_wrap_source_par       integer_parameter(alignment_wrap_source_code)
1525
1526# define delimiter_shortfall_par         dimension_parameter(delimiter_shortfall_code)
1527# define null_delimiter_space_par        dimension_parameter(null_delimiter_space_code)
1528# define script_space_par                dimension_parameter(script_space_code)
1529# define max_depth_par                   dimension_parameter(max_depth_code)
1530# define box_max_depth_par               dimension_parameter(box_max_depth_code)
1531# define split_max_depth_par             dimension_parameter(split_max_depth_code)
1532# define overfull_rule_par               dimension_parameter(overfull_rule_code)
1533# define box_max_depth_par               dimension_parameter(box_max_depth_code)
1534# define ignore_depth_criterion_par      dimension_parameter(ignore_depth_criterion_code)
1535# define short_inline_math_threshold_par dimension_parameter(short_inline_math_threshold_code)
1536
1537# define top_skip_par                    glue_parameter(top_skip_code)
1538# define split_top_skip_par              glue_parameter(split_top_skip_code)
1539
1540# define cur_fam_par                     integer_parameter(family_code)
1541# define variable_family_par             integer_parameter(variable_family_code)
1542# define eu_factor_par                   integer_parameter(eu_factor_code)
1543# define space_factor_mode_par           integer_parameter(space_factor_mode)
1544# define space_factor_shrink_limit_par   integer_parameter(space_factor_shrink_limit_code)
1545# define space_factor_stretch_limit_par  integer_parameter(space_factor_stretch_limit_code)
1546# define box_limit_mode_par              integer_parameter(box_limit_mode_code)
1547# define pre_display_direction_par       integer_parameter(pre_display_direction_code)
1548# define pre_display_penalty_par         integer_parameter(pre_display_penalty_code)
1549# define post_display_penalty_par        integer_parameter(post_display_penalty_code)
1550# define pre_inline_penalty_par          integer_parameter(pre_inline_penalty_code)
1551# define post_inline_penalty_par         integer_parameter(post_inline_penalty_code)
1552# define pre_short_inline_penalty_par    integer_parameter(pre_short_inline_penalty_code)
1553# define post_short_inline_penalty_par   integer_parameter(post_short_inline_penalty_code)
1554# define short_inline_orphan_penalty_par integer_parameter(short_inline_orphan_penalty_code)
1555
1556# define local_interline_penalty_par     integer_parameter(local_interline_penalty_code)
1557# define local_broken_penalty_par        integer_parameter(local_broken_penalty_code)
1558# define local_tolerance_par             integer_parameter(local_tolerance_code)
1559# define local_pre_tolerance_par         integer_parameter(local_pre_tolerance_code)
1560# define local_left_box_par              box_parameter(local_left_box_code)
1561# define local_right_box_par             box_parameter(local_right_box_code)
1562# define local_middle_box_par            box_parameter(local_middle_box_code)
1563
1564# define end_line_char_par               integer_parameter(end_line_char_code)
1565# define new_line_char_par               integer_parameter(new_line_char_code)
1566# define escape_char_par                 integer_parameter(escape_char_code)
1567
1568# define end_line_char_inactive          ((end_line_char_par < 0) || (end_line_char_par > max_endline_character))
1569
1570/*tex
1571    We keep these as reference but they are no longer equivalent to regular \TEX\ because we have
1572    class based penalties instead.
1573*/
1574
1575/*define post_binary_penalty_par         integer_parameter(post_binary_penalty_code)   */
1576/*define post_relation_penalty_par       integer_parameter(post_relation_penalty_code) */
1577/*define pre_binary_penalty_par          integer_parameter(pre_binary_penalty_code)    */
1578/*define pre_relation_penalty_par        integer_parameter(pre_relation_penalty_code)  */
1579
1580# define delimiter_factor_par            integer_parameter(delimiter_factor_code)
1581# define math_penalties_mode_par         integer_parameter(math_penalties_mode_code)
1582# define math_check_fences_par           integer_parameter(math_check_fences_mode_code)
1583# define math_slack_mode_par             integer_parameter(math_slack_mode_code)
1584# define null_delimiter_space_par        dimension_parameter(null_delimiter_space_code)
1585# define no_spaces_par                   integer_parameter(no_spaces_code)
1586# define glyph_options_par               integer_parameter(glyph_options_code)
1587# define glyph_scale_par                 integer_parameter(glyph_scale_code)
1588# define glyph_text_scale_par            integer_parameter(glyph_text_scale_code)
1589# define glyph_script_scale_par          integer_parameter(glyph_script_scale_code)
1590# define glyph_scriptscript_scale_par    integer_parameter(glyph_scriptscript_scale_code)
1591# define glyph_x_scale_par               integer_parameter(glyph_x_scale_code)
1592# define glyph_y_scale_par               integer_parameter(glyph_y_scale_code)
1593# define glyph_slant_par                 integer_parameter(glyph_slant_code)
1594# define glyph_weight_par                integer_parameter(glyph_weight_code)
1595# define glyph_x_offset_par              dimension_parameter(glyph_x_offset_code)
1596# define glyph_y_offset_par              dimension_parameter(glyph_y_offset_code)
1597# define discretionary_options_par       integer_parameter(discretionary_options_code)
1598# define math_scripts_mode_par           integer_parameter(math_scripts_mode_code)
1599# define math_limits_mode_par            integer_parameter(math_limits_mode_code)
1600# define math_nolimits_mode_par          integer_parameter(math_nolimits_mode_code)
1601# define math_rules_mode_par             integer_parameter(math_rules_mode_code)
1602# define math_rules_fam_par              integer_parameter(math_rules_fam_code)
1603# define math_glue_mode_par              integer_parameter(math_glue_mode_code)
1604
1605typedef enum math_glue_modes {
1606    math_glue_stretch_code = 0x01,
1607    math_glue_shrink_code  = 0x02,
1608    math_glue_limit_code   = 0x04,
1609} math_glue_modes;
1610
1611# define math_glue_stretch_enabled       ((math_glue_mode_par & math_glue_stretch_code) == math_glue_stretch_code)
1612# define math_glue_shrink_enabled        ((math_glue_mode_par & math_glue_shrink_code) == math_glue_shrink_code)
1613# define math_glue_limit_enabled         ((math_glue_mode_par & math_glue_limit_code) == math_glue_limit_code)
1614# define default_math_glue_mode          (math_glue_stretch_code | math_glue_shrink_code)
1615
1616# define petty_muskip_par                muglue_parameter(petty_muskip_code)
1617# define tiny_muskip_par                 muglue_parameter(tiny_muskip_code)
1618# define thin_muskip_par                 muglue_parameter(thin_muskip_code)
1619# define med_muskip_par                  muglue_parameter(med_muskip_code)
1620# define thick_muskip_par                muglue_parameter(thick_muskip_code)
1621
1622# define every_math_par                  toks_parameter(every_math_code)
1623# define every_display_par               toks_parameter(every_display_code)
1624# define every_cr_par                    toks_parameter(every_cr_code)
1625# define every_tab_par                   toks_parameter(every_tab_code)
1626# define every_hbox_par                  toks_parameter(every_hbox_code)
1627# define every_vbox_par                  toks_parameter(every_vbox_code)
1628# define every_math_atom_par             toks_parameter(every_math_atom_code)
1629# define every_eof_par                   toks_parameter(every_eof_code)
1630# define every_par_par                   toks_parameter(every_par_code)
1631# define every_before_par_par            toks_parameter(every_before_par_code)
1632# define every_job_par                   toks_parameter(every_job_code)
1633# define error_help_par                  toks_parameter(error_help_code)
1634# define end_of_group_par                toks_parameter(end_of_group_code)
1635/*define end_of_par_par                  toks_parameter(end_of_par_code) */
1636
1637# define internal_par_state_par          integer_parameter(internal_par_state_code)
1638# define internal_dir_state_par          integer_parameter(internal_dir_state_code)
1639# define internal_math_style_par         integer_parameter(internal_math_style_code)
1640# define internal_math_scale_par         integer_parameter(internal_math_scale_code)
1641
1642# define overload_mode_par               integer_parameter(overload_mode_code)
1643
1644# define auto_paragraph_mode_par         integer_parameter(auto_paragraph_mode_code)
1645
1646typedef enum auto_paragraph_modes {
1647    auto_paragraph_text  = 0x01,
1648    auto_paragraph_macro = 0x02,
1649    auto_paragraph_go_on = 0x04,
1650} auto_paragraph_modes;
1651
1652# define auto_paragraph_mode(flag) ((auto_paragraph_mode_par) & (flag))
1653
1654# define shaping_penalties_mode_par      integer_parameter(shaping_penalties_mode_code)
1655# define shaping_penalty_par             integer_parameter(shaping_penalty_code)
1656
1657typedef enum shaping_penalties_mode_bits {
1658    inter_line_penalty_shaping = 0x01,
1659    widow_penalty_shaping      = 0x02,
1660    club_penalty_shaping       = 0x04,
1661    broken_penalty_shaping     = 0x08,
1662} shaping_penalties_mode_bits;
1663
1664# define is_shaping_penalties_mode(what,flag) ((what) & (flag))
1665
1666# define tab_size_par                    dimension_parameter(tab_size_code)
1667
1668# define par_shape_par                   specification_parameter(par_shape_code)
1669# define par_passes_par                  specification_parameter(par_passes_code)
1670# define inter_line_penalties_par        specification_parameter(inter_line_penalties_code)
1671# define club_penalties_par              specification_parameter(club_penalties_code)
1672# define widow_penalties_par             specification_parameter(widow_penalties_code)
1673# define display_widow_penalties_par     specification_parameter(display_widow_penalties_code)
1674# define orphan_penalties_par            specification_parameter(orphan_penalties_code)
1675# define math_forward_penalties_par      specification_parameter(math_forward_penalties_code)
1676# define math_backward_penalties_par     specification_parameter(math_backward_penalties_code)
1677
1678/*tex 
1679    We keep these three as reference but because they are backend related they are basically 
1680    no-ops and ignored. 
1681*/
1682
1683/*define h_offset_par                    dimension_parameter(h_offset_code) */
1684/*define v_offset_par                    dimension_parameter(v_offset_code) */
1685/*define mag_par                         integer_parameter(mag_code) */
1686
1687# define px_dimension_par                dimension_parameter(px_dimension_code)
1688
1689# define max_dead_cycles_par             integer_parameter(max_dead_cycles_code)
1690# define output_box_par                  integer_parameter(output_box_code)
1691# define holding_inserts_par             integer_parameter(holding_inserts_code)
1692# define holding_migrations_par          integer_parameter(holding_migrations_code)
1693# define output_routine_par              toks_parameter(output_routine_code)
1694# define floating_penalty_par            integer_parameter(floating_penalty_code)
1695
1696# define global_defs_par                 integer_parameter(global_defs_code)
1697# define cat_code_table_par              integer_parameter(cat_code_table_code)
1698# define saving_vdiscards_par            integer_parameter(saving_vdiscards_code)
1699
1700# define tracing_output_par              integer_parameter(tracing_output_code)
1701# define tracing_stats_par               integer_parameter(tracing_stats_code)
1702# define tracing_online_par              integer_parameter(tracing_online_code)
1703# define tracing_paragraphs_par          integer_parameter(tracing_paragraphs_code)
1704# define tracing_levels_par              integer_parameter(tracing_levels_code)
1705# define tracing_nesting_par             integer_parameter(tracing_nesting_code)
1706# define tracing_alignments_par          integer_parameter(tracing_alignments_code)
1707# define tracing_inserts_par             integer_parameter(tracing_inserts_code)
1708# define tracing_marks_par               integer_parameter(tracing_marks_code)
1709# define tracing_adjusts_par             integer_parameter(tracing_adjusts_code)
1710# define tracing_lost_chars_par          integer_parameter(tracing_lost_chars_code)
1711# define tracing_ifs_par                 integer_parameter(tracing_ifs_code)
1712# define tracing_commands_par            integer_parameter(tracing_commands_code)
1713# define tracing_macros_par              integer_parameter(tracing_macros_code)
1714# define tracing_assigns_par             integer_parameter(tracing_assigns_code)
1715//define tracing_fonts_par               integer_parameter(tracing_fonts_code)
1716# define tracing_pages_par               integer_parameter(tracing_pages_code)
1717# define tracing_restores_par            integer_parameter(tracing_restores_code)
1718# define tracing_groups_par              integer_parameter(tracing_groups_code)
1719# define tracing_math_par                integer_parameter(tracing_math_code)
1720# define tracing_hyphenation_par         integer_parameter(tracing_hyphenation_code)
1721# define tracing_expressions_par         integer_parameter(tracing_expressions_code)
1722# define tracing_nodes_par               integer_parameter(tracing_nodes_code)
1723# define tracing_full_boxes_par          integer_parameter(tracing_full_boxes_code)
1724# define tracing_penalties_par           integer_parameter(tracing_penalties_code)
1725# define tracing_lists_par               integer_parameter(tracing_lists_code)
1726# define tracing_passes_par              integer_parameter(tracing_passes_code)
1727
1728/*tex 
1729    This tracer is mostly there for debugging purposes. Therefore what gets traced and how might
1730    change depending on my needs. 
1731*/
1732
1733typedef enum tracing_lists_codes {
1734    trace_direction_list_code = 0x0001, 
1735    trace_paragraph_list_code = 0x0002, 
1736    trace_linebreak_list_code = 0x0004, 
1737} tracing_lists_codes;
1738
1739# define tracing_direction_lists         ((tracing_lists_par & trace_direction_list_code) == trace_direction_list_code)
1740# define tracing_paragraph_lists         ((tracing_lists_par & trace_paragraph_list_code) == trace_paragraph_list_code)
1741# define tracing_linebreak_lists         ((tracing_lists_par & trace_linebreak_list_code) == trace_linebreak_list_code)
1742
1743# define show_box_depth_par              integer_parameter(show_box_depth_code)
1744# define show_box_breadth_par            integer_parameter(show_box_breadth_code)
1745# define show_node_details_par           integer_parameter(show_node_details_code)
1746
1747# define pausing_par                     integer_parameter(pausing_code)
1748
1749# define error_context_lines_par         integer_parameter(error_context_lines_code)
1750# define copy_lua_input_nodes_par        integer_parameter(copy_lua_input_nodes_code)
1751
1752# define math_pre_display_gap_factor_par integer_parameter(math_pre_display_gap_factor_code)
1753
1754# define time_par                        integer_parameter(time_code)
1755# define day_par                         integer_parameter(day_code)
1756# define month_par                       integer_parameter(month_code)
1757# define year_par                        integer_parameter(year_code)
1758
1759typedef enum hyphenation_mode_bits {
1760    normal_hyphenation_mode              = 0x00001,
1761    automatic_hyphenation_mode           = 0x00002,
1762    explicit_hyphenation_mode            = 0x00004,
1763    syllable_hyphenation_mode            = 0x00008,
1764    uppercase_hyphenation_mode           = 0x00010,
1765    compound_hyphenation_mode            = 0x00020,
1766    strict_start_hyphenation_mode        = 0x00040,
1767    strict_end_hyphenation_mode          = 0x00080,
1768    automatic_penalty_hyphenation_mode   = 0x00100,
1769    explicit_penalty_hyphenation_mode    = 0x00200,
1770    permit_glue_hyphenation_mode         = 0x00400,
1771    permit_all_hyphenation_mode          = 0x00800,
1772    permit_math_replace_hyphenation_mode = 0x01000,
1773    force_check_hyphenation_mode         = 0x02000,
1774    lazy_ligatures_hyphenation_mode      = 0x04000,
1775    force_handler_hyphenation_mode       = 0x08000,
1776    feedback_compound_hyphenation_mode   = 0x10000,
1777    ignore_bounds_hyphenation_mode       = 0x20000,
1778    collapse_hyphenation_mode            = 0x40000,
1779} hyphenation_mode_bits;
1780
1781# define hyphenation_permitted(a,b)   (((a) & (b)) == (b))
1782# define set_hyphenation_mode(a,b)    ((a) | (b))
1783# define unset_hyphenation_mode(a,b)  ((a) & ~(b))
1784# define flip_hyphenation_mode(a,b)   ((b) ? set_hyphenation_mode(a,b) : unset_hyphenation_mode(a,b))
1785# 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)
1786
1787# define language_par                    integer_parameter(language_code)
1788# define hyphenation_mode_par            integer_parameter(hyphenation_mode_code)
1789# define uc_hyph_par                     integer_parameter(uc_hyph_code)
1790# define left_hyphen_min_par             integer_parameter(left_hyphen_min_code)
1791# define right_hyphen_min_par            integer_parameter(right_hyphen_min_code)
1792# define ex_hyphen_char_par              integer_parameter(ex_hyphen_char_code)
1793# define hyphen_penalty_par              integer_parameter(hyphen_penalty_code)
1794# define ex_hyphen_penalty_par           integer_parameter(ex_hyphen_penalty_code)
1795# define default_hyphen_char_par         integer_parameter(default_hyphen_char_code)
1796# define default_skew_char_par           integer_parameter(default_skew_char_code)
1797# define saving_hyph_codes_par           integer_parameter(saving_hyph_codes_code)
1798
1799# define automatic_hyphen_penalty_par    integer_parameter(automatic_hyphen_penalty_code)
1800# define explicit_hyphen_penalty_par     integer_parameter(explicit_hyphen_penalty_code)
1801# define exception_penalty_par           integer_parameter(exception_penalty_code)
1802
1803# define math_spacing_mode_par           integer_parameter(math_spacing_mode_code)
1804# define math_grouping_mode_par          integer_parameter(math_grouping_mode_code)
1805# define math_begin_class_par            integer_parameter(math_begin_class_code)
1806# define math_end_class_par              integer_parameter(math_end_class_code)
1807# define math_left_class_par             integer_parameter(math_left_class_code)
1808# define math_right_class_par            integer_parameter(math_right_class_code)
1809# define sup_mark_mode_par               integer_parameter(sup_mark_mode_code)
1810# define math_display_penalty_factor_par integer_parameter(math_display_penalty_factor_code)
1811# define math_inline_penalty_factor_par  integer_parameter(math_inline_penalty_factor_code)
1812
1813# define glyph_data_par                  integer_parameter(glyph_data_code)
1814# define glyph_state_par                 integer_parameter(glyph_state_code)
1815# define glyph_script_par                integer_parameter(glyph_script_code)
1816
1817/*define glue_data_par                   integer_parameter(glue_data_code) */
1818
1819# define cur_lang_par                    integer_parameter(language_code)
1820# define cur_font_par                    integer_parameter(font_code)
1821
1822typedef enum normalize_line_mode_bits {
1823    normalize_line_mode          = 0x0001,
1824    parindent_skip_mode          = 0x0002,
1825    swap_hangindent_mode         = 0x0004,
1826    swap_parshape_mode           = 0x0008,
1827    break_after_dir_mode         = 0x0010,
1828    remove_margin_kerns_mode     = 0x0020, /*tex When unpacking an hbox \unknown\ a \PDFTEX\ leftover. */
1829    clip_width_mode              = 0x0040,
1830    flatten_discretionaries_mode = 0x0080,
1831    discard_zero_tab_skips_mode  = 0x0100,
1832    flatten_h_leaders_mode       = 0x0200,
1833} normalize_line_mode_bits;
1834
1835typedef enum normalize_par_mode_bits {
1836    normalize_par_mode     = 0x0001,
1837    flatten_v_leaders_mode = 0x0002, /* used to be 0x200 */
1838    limit_prev_graf_mode   = 0x0004,
1839} normalize_par_mode_bits;
1840
1841# define normalize_line_mode_permitted(a,b) ((a & b) == b)
1842# define normalize_par_mode_permitted(a,b) ((a & b) == b)
1843
1844typedef enum parameter_mode_bits {
1845    parameter_escape_mode = 0x0001,
1846} parameter_mode_bits;
1847
1848# define normalize_line_mode_par  integer_parameter(normalize_line_mode_code)
1849# define normalize_par_mode_par   integer_parameter(normalize_par_mode_code)
1850# define auto_migration_mode_par  integer_parameter(auto_migration_mode_code)
1851
1852# define parameter_mode_par       integer_parameter(parameter_mode_code)  
1853
1854typedef enum auto_migration_mode_bits {
1855     auto_migrate_mark   = 0x01,
1856     auto_migrate_insert = 0x02,
1857     auto_migrate_adjust = 0x04,
1858     auto_migrate_pre    = 0x08,
1859     auto_migrate_post   = 0x10,
1860} auto_migration_mode_bits;
1861
1862# define auto_migrating_mode_permitted(what,flag) ((what & flag) == flag)
1863
1864# define attribute_register(j) eq_value(register_attribute_location(j))
1865# define posit_register(j)     eq_value(register_posit_location(j))
1866# define box_register(j)       eq_value(register_box_location(j))
1867# define integer_register(j)   eq_value(register_integer_location(j))
1868# define dimension_register(j) eq_value(register_dimension_location(j))
1869# define muglue_register(j)    eq_value(register_muglue_location(j))
1870# define glue_register(j)      eq_value(register_glue_location(j))
1871# define toks_register(j)      eq_value(register_toks_location(j))
1872//define unit_register(j)      eq_value(register_unit_location(j))
1873
1874# define count_register  integer_register
1875# define dimen_register  dimension_register
1876# define skip_register   glue_register
1877# define muskip_register muglue_register
1878
1879/*
1880    Injecting these frozen tokens can for instance happen when we scan for an integer or dimension
1881    and run into an |\else| or |\fi| because (guess what) these scanners gobble trailing spaces! In
1882    that case the |deep_frozen_relax_token| gets pushed back and can for instance end up in an
1883    expansion (macro, write, etc) because we only look ahead. However, we can catch this side effect
1884    in the scanners (that we redefined anyway). Removing those |\relax|'s was on the todo list and
1885    now happens in the scanners. Actually it's one reason why we often use constants in tests
1886    because these don't have that side effect because the scanner then quite earlier.) Another place
1887    where that happens is in the |\input| command but there we can use braces. It is a typical
1888    example of a more cosmetic adaptation that got a bit more priority when we converted the
1889    \CONTEXT\ codebase from \MKIV\ to \LMTX, where testing involved checking the results. I also have
1890    to check the other frozen tokens that can get reported when we have for instance alignments. It
1891    is also why some of these tokens have an associated (private but serialized) |\csname|.
1892
1893    For the record: we can these tokens deep_frozen because we don't want them to be confused with
1894    the |\frozen| user macros and the ones below are really deeply hidden, although sometimes they
1895    do surface.
1896
1897*/
1898
1899typedef enum deep_frozen_cs_tokens {
1900    deep_frozen_protection_token   = cs_token_flag + deep_frozen_cs_protection_code,
1901    deep_frozen_cr_token           = cs_token_flag + deep_frozen_cs_cr_code,
1902    deep_frozen_end_group_token    = cs_token_flag + deep_frozen_cs_end_group_code,
1903    deep_frozen_right_token        = cs_token_flag + deep_frozen_cs_right_code,
1904    deep_frozen_fi_token           = cs_token_flag + deep_frozen_cs_fi_code,
1905    deep_frozen_end_template_token = cs_token_flag + deep_frozen_cs_end_template_code,
1906    deep_frozen_relax_token        = cs_token_flag + deep_frozen_cs_relax_code,
1907    deep_frozen_end_write_token    = cs_token_flag + deep_frozen_cs_end_write_code,
1908    deep_frozen_dont_expand_token  = cs_token_flag + deep_frozen_cs_dont_expand_code,
1909    deep_frozen_null_font_token    = cs_token_flag + deep_frozen_cs_null_font_code,
1910    deep_frozen_undefined_token    = cs_token_flag + deep_frozen_cs_undefined_code,
1911} deep_frozen_cs_tokens;
1912
1913/*tex
1914
1915    The next has been simplified and replaced by |\hyphenatiomode| but we keep it as reminder:
1916
1917    \starttabulate[|T|T|T|]
1918    \NC hyphen_penalty_mode_par \NC automatic_disc (-)           \NC explicit_disc (\-) \NC \NR
1919    \HL
1920    \NC 0 (default)             \NC ex_hyphen_penalty_par        \NC ex_hyphen_penalty_par \NC \NR
1921    \NC 1                       \NC hyphen_penalty_par           \NC hyphen_penalty_par \NC \NR
1922    \NC 2                       \NC ex_hyphen_penalty_par        \NC hyphen_penalty_par \NC \NR
1923    \NC 3                       \NC hyphen_penalty_par           \NC ex_hyphen_penalty_par \NC \NR
1924    \NC 4                       \NC automatic_hyphen_penalty_par \NC explicit_disc_penalty_par \NC \NR
1925    \NC 5                       \NC ex_hyphen_penalty_par        \NC explicit_disc_penalty_par \NC \NR
1926    \NC 6                       \NC hyphen_penalty_par           \NC explicit_disc_penalty_par \NC \NR
1927    \NC 7                       \NC automatic_hyphen_penalty_par \NC ex_hyphen_penalty_par \NC \NR
1928    \NC 8                       \NC automatic_hyphen_penalty_par \NC hyphen_penalty_par \NC \NR
1929    \stoptabulate
1930
1931*/
1932
1933extern halfword tex_automatic_disc_penalty (halfword mode);
1934extern halfword tex_explicit_disc_penalty  (halfword mode);
1935
1936/*tex
1937
1938    We add a bit more abstraction when setting the system parameters. This is not really
1939    needed but it move all the |eq_| assignments to a place where we can keep an eye on
1940    them.
1941
1942*/
1943
1944# define update_tex_glyph_data(a,v)            tex_word_define(a, internal_integer_location(glyph_data_code), v)
1945# define update_tex_glyph_state(a,v)           tex_word_define(a, internal_integer_location(glyph_state_code), v)
1946# define update_tex_glyph_script(a,v)          tex_word_define(a, internal_integer_location(glyph_script_code), v)
1947# define update_tex_family(a,v)                tex_word_define(a, internal_integer_location(family_code), v)
1948# define update_tex_variable_family(a,v)       tex_word_define(a, internal_integer_location(variable_family_code), v)
1949# define update_tex_language(a,v)              tex_word_define(a, internal_integer_location(language_code), v)
1950# define update_tex_font(a,v)                  tex_word_define(a, internal_integer_location(font_code), v)
1951
1952/*define update_tex_glue_data(a,v)             tex_word_define(a, internal_integer_location(glue_data_code), v) */
1953
1954# define update_tex_display_indent(v)          tex_eq_word_define(internal_dimension_location(display_indent_code), v)
1955# define update_tex_display_width(v)           tex_eq_word_define(internal_dimension_location(display_width_code), v)
1956# define update_tex_hang_after(v)              tex_eq_word_define(internal_integer_location(hang_after_code), v)
1957# define update_tex_hang_indent(v)             tex_eq_word_define(internal_dimension_location(hang_indent_code), v)
1958# define update_tex_looseness(v)               tex_eq_word_define(internal_integer_location(looseness_code), v)
1959# define update_tex_inter_line_penalties(v)    tex_eq_word_define(internal_integer_location(inter_line_penalties_code), v)
1960# define update_tex_single_line_penalty(v)     tex_eq_word_define(internal_integer_location(single_line_penalty_code), v)
1961# define update_tex_math_direction(v)          tex_eq_word_define(internal_integer_location(math_direction_code), v)
1962# define update_tex_internal_par_state(v)      tex_eq_word_define(internal_integer_location(internal_par_state_code), v)
1963# define update_tex_internal_dir_state(v)      tex_eq_word_define(internal_integer_location(internal_dir_state_code), v)
1964# define update_tex_internal_math_style(v)     tex_eq_word_define(internal_integer_location(internal_math_style_code), v)
1965# define update_tex_internal_math_scale(v)     tex_eq_word_define(internal_integer_location(internal_math_scale_code), v)
1966# define update_tex_output_penalty(v)          tex_geq_word_define(internal_integer_location(output_penalty_code), v)
1967# define update_tex_par_direction(v)           tex_eq_word_define(internal_integer_location(par_direction_code), v)
1968# define update_tex_pre_display_direction(v)   tex_eq_word_define(internal_integer_location(pre_display_direction_code), v)
1969# define update_tex_pre_display_size(v)        tex_eq_word_define(internal_dimension_location(pre_display_size_code), v)
1970# define update_tex_text_direction(v)          tex_eq_word_define(internal_integer_location(text_direction_code), v)
1971
1972# define update_tex_font_identifier(v)         tex_eq_word_define(internal_integer_location(font_code), v)
1973# define update_tex_glyph_scale(v)             tex_eq_word_define(internal_integer_location(glyph_scale_code), v)
1974# define update_tex_glyph_x_scale(v)           tex_eq_word_define(internal_integer_location(glyph_x_scale_code), v)
1975# define update_tex_glyph_y_scale(v)           tex_eq_word_define(internal_integer_location(glyph_y_scale_code), v)
1976# define update_tex_glyph_slant(v)             tex_eq_word_define(internal_integer_location(glyph_slant_code), v)
1977# define update_tex_glyph_weight(v)            tex_eq_word_define(internal_integer_location(glyph_weight_code), v)
1978
1979# define update_tex_math_left_class(v)         tex_eq_word_define(internal_integer_location(math_left_class_code), v)
1980# define update_tex_math_right_class(v)        tex_eq_word_define(internal_integer_location(math_right_class_code), v)
1981
1982# define update_tex_par_shape(v)               tex_eq_define(internal_specification_location(par_shape_code),            specification_reference_cmd, v)
1983# define update_tex_par_passes(v)              tex_eq_define(internal_specification_location(par_passes_code),           specification_reference_cmd, v)
1984/*define update_tex_club_penalties(v)          eq_define(internal_specification_location(club_penalties_code),           specification_reference_cmd, v) */
1985/*define update_tex_widow_penalties(v)         eq_define(internal_specification_location(widow_penalties_code),          specification_reference_cmd, v) */
1986/*define update_tex_display_widow_penalties(v) eq_define(internal_specification_location(display_widow_penalties_code),  specification_reference_cmd, v) */
1987/*define update_tex_orphan_penalties(v)        eq_define(internal_specification_location(orphan_penalties_code),         specification_reference_cmd, v) */
1988
1989# define update_tex_end_of_group(v)            tex_eq_define(internal_toks_location(end_of_group_code), internal_toks_reference_cmd, v)
1990/*define update_tex_end_of_par(v)              eq_define(internal_toks_location(end_of_par_code), internal_toks_cmd, v) */
1991
1992# define update_tex_local_left_box(v)          tex_eq_define(internal_box_location(local_left_box_code),  internal_box_reference_cmd, v);
1993# define update_tex_local_right_box(v)         tex_eq_define(internal_box_location(local_right_box_code), internal_box_reference_cmd, v);
1994# define update_tex_local_middle_box(v)        tex_eq_define(internal_box_location(local_middle_box_code), internal_box_reference_cmd, v);
1995
1996# define update_tex_font_local(f,v)            tex_eq_define(f, set_font_cmd, v); /* Here |f| already has the right offset. */
1997# define update_tex_font_global(f,v)          tex_geq_define(f, set_font_cmd, v); /* Here |f| already has the right offset. */
1998
1999# define update_tex_tab_skip_local(v)          tex_eq_define(internal_glue_location(tab_skip_code), internal_glue_reference_cmd, v);
2000# define update_tex_tab_skip_global(v)        tex_geq_define(internal_glue_location(tab_skip_code), internal_glue_reference_cmd, v);
2001
2002# define update_tex_box_local(n,v)             tex_eq_define(register_box_location(n), register_box_reference_cmd, v);
2003# define update_tex_box_global(n,v)           tex_geq_define(register_box_location(n), register_box_reference_cmd, v);
2004
2005# define update_tex_insert_mode(a,v)           tex_word_define(a, internal_integer_location(insert_mode_code), v)
2006
2007# define update_tex_emergency_left_skip(v)     tex_eq_define(internal_glue_location(emergency_left_skip_code), internal_glue_reference_cmd, v);
2008# define update_tex_emergency_right_skip(v)    tex_eq_define(internal_glue_location(emergency_right_skip_code), internal_glue_reference_cmd, v);
2009
2010# define update_tex_additional_page_skip(v)    tex_geq_define(internal_glue_location(additional_page_skip_code), internal_glue_reference_cmd, v)
2011
2012# define update_tex_local_interline_penalty(v) tex_eq_word_define(internal_integer_location(local_interline_penalty_code), v);
2013# define update_tex_local_broken_penalty(v)    tex_eq_word_define(internal_integer_location(local_broken_penalty_code), v);
2014# define update_tex_local_tolerance(v)         tex_eq_word_define(internal_integer_location(local_tolerance_code), v);
2015# define update_tex_local_pre_tolerance(v)     tex_eq_word_define(internal_integer_location(local_pre_tolerance_code), v);
2016
2017# define box_limit_mode_hlist ((box_limit_mode_par & box_limit_hlist) == box_limit_hlist)
2018# define box_limit_mode_vlist ((box_limit_mode_par & box_limit_vlist) == box_limit_vlist)
2019# define box_limit_mode_line  ((box_limit_mode_par & box_limit_line) == box_limit_line)
2020
2021/*tex For the moment here; a preparation for a dedicated insert structure. */
2022
2023# define insert_content(A)    box_register(A)
2024# define insert_multiplier(A) count_register(A)
2025# define insert_maxheight(A)  dimension_register(A)
2026# define insert_distance(A)   skip_register(A)
2027
2028typedef enum cs_errors {
2029    cs_no_error,
2030    cs_null_error,
2031    cs_below_base_error,
2032    cs_undefined_error, 
2033    cs_out_of_range_error,
2034} cs_errors;
2035
2036extern int tex_cs_state(halfword p) ;
2037
2038# endif
2039