texconditional.h /size: 6820 b    last modification: 2025-02-21 11:03
1/*
2    See license.txt in the root of this project.
3*/
4
5# ifndef LMT_CONDITIONAL_H
6# define LMT_CONDITIONAL_H
7
8/*tex
9
10    The next list should be in sync with |if_branch_mapping| at the top of the |c| file with the
11    same name. The next ones also go on the condition stack so we need to retain this order and
12    organization.
13
14    There is a catch here: the codes of the |if_test_cmd|, |fi_or_else_cmd| and |or_else_cmd| are
15    all in this enumeration. This has to do with the history of not always checking for the cmd
16    code in the fast skipping branches. We could change that but not now.
17
18    Well, in the end I combined |if_test_cmd|, |fi_or_else_cmd| and |or_else_cmd| because they use
19    the same chr range anyway and it also simplifies some of the testing (especially after some
20    more robust cmd/chr checking was added, and after that the |fi_or_else_cmd| and |or_else_cmd|
21    were combined. The main motivation is that we can have a more consistent \LUA\ token interface
22    end. It is debatable as we divert from the original, but we already did that by introducing
23    more conditionals, |\orelse| and the generic |\ifconditional| that also demandeed all kind of
24    adaptations. Sorry. The comments are mostly the same, including references to the older cmd
25    codes (pre 2.07 there used to be some switch/case statements in places but these were flattened).
26
27    Btw, the |\unless| prefix is kept out of this because it relates to expansion and prefixes are
28    separate anyway. It would make the code less pretty.
29
30    One reason for a split in cmd codes is performance but we didn't loose on the change.
31
32*/
33
34typedef enum if_test_codes {
35    /*tex These are private chr codes: */
36
37    no_if_code,             /*tex We're not in a condition. */
38    if_code,                /*tex We have a condition. */
39
40    /*tex These are public chr codes: */
41
42    fi_code,                /*tex |\fi| */
43    else_code,              /*tex |\else| */
44    or_code,                /*tex |\or| */
45    or_else_code,           /*tex |\orelse| */
46    or_unless_code,         /*tex |\orunless| */
47
48    /*tex 
49        Here come the \if... codes. Some are just there to minimize tracing and are not faster, 
50        like |\ifzerodim| (we can use |\ifcase| instead but not with |\unless|). 
51
52        For historic reasons we see a mixture if |int| and |num| here but I see no reason the 
53        change that now.  
54    */
55
56    if_char_code,            /*tex |\if| */
57    if_cat_code,             /*tex |\ifcat| */
58    if_int_code,             /*tex |\ifnum| */
59    if_abs_int_code,         /*tex |\ifabsnum| */ 
60    if_zero_int_code,        /*tex |\ifzeronum|*/
61    if_interval_int_code,
62    if_posit_code,    
63    if_abs_posit_code,
64    if_zero_posit_code,
65    if_interval_posit_code,
66    if_dim_code,             /*tex |\ifdim| */
67    if_abs_dim_code,         /*tex |\ifabsdim| */
68    if_zero_dim_code,        /*tex |\ifzerodim| */
69    if_interval_dim_code,
70    if_odd_code,             /*tex |\ifodd| */
71    if_vmode_code,           /*tex |\ifvmode| */
72    if_hmode_code,           /*tex |\ifhmode| */
73    if_mmode_code,           /*tex |\ifmmode| */
74    if_inner_code,           /*tex |\ifinner| */
75    if_void_code,            /*tex |\ifvoid| */
76    if_hbox_code,            /*tex |\ifhbox| */
77    if_vbox_code,            /*tex |\ifvbox| */
78    if_tok_code,             /*tex |\iftok| */
79    if_cstok_code,           /*tex |\ifcstok| */
80    if_x_code,               /*tex |\ifx| */
81    if_true_code,            /*tex |\iftrue| */
82    if_false_code,           /*tex |\iffalse| */
83    if_chk_int_code,         /*tex |\ifchknum| */
84    if_chk_integer_code,     /*tex |\ifchknumber| */
85    if_chk_intexpr_code,     /*tex |\ifnumexpr| */
86    if_val_int_code,         /*tex |\ifnumval| */
87    if_cmp_int_code,         /*tex |\ifcmpnum| */
88    if_chk_dim_code,         /*tex |\ifchkdim| */
89    if_chk_dimension_code,   /*tex |\ifchkdimension| */
90    if_chk_dimexpr_code,     /*tex |\ifdimexpr| */
91    if_val_dim_code,         /*tex |\ifdimval| */
92    if_cmp_dim_code,         /*tex |\ifcmpdim| */
93    if_case_code,            /*tex |\ifcase| */
94    if_defined_code,         /*tex |\ifdefined| */
95    if_csname_code,          /*tex |\ifcsname| */
96    if_in_csname_code,       /*tex |\ifincsname| */
97    if_font_char_code,       /*tex |\iffontchar| */
98    if_condition_code,       /*tex |\ifcondition| */
99    if_flags_code,           /*tex |\ifflags| */
100    if_empty_code,           /*tex |\ifempty| */
101    if_relax_code,           /*tex |\ifrelax| */
102    if_boolean_code,         /*tex |\ifboolean| */
103    if_numexpression_code,   /*tex |\ifnumexpression| */
104    if_dimexpression_code,   /*tex |\ifdimexpression| */
105    if_last_named_cs_code,   /*tex |\iflastnamedcs| */
106    if_math_parameter_code,  /*tex |\ifmathparameter| */
107    if_math_style_code,      /*tex |\ifmathstyle| */
108    if_arguments_code,       /*tex |\ifarguments| */
109    if_parameters_code,      /*tex |\ifparameters| */
110    if_parameter_code,       /*tex |\ifparameter| */
111    if_has_tok_code,         /*tex |\ifhastok| */
112    if_has_toks_code,        /*tex |\ifhastoks| */
113    if_has_xtoks_code,       /*tex |\ifhasxtoks| */
114    if_has_char_code,        /*tex |\ifhaschar| */
115    if_insert_code,          /*tex |\ifinsert| */
116    if_in_alignment_code,    /*tex |\ifinalignment| */
117    if_cramped_code,         /*tex |\ifcrampedmathstyle| */
118    if_list_code,            /*tex |\iflist| */
119 // if_bitwise_and_code,     /*tex |\ifbitwiseand| */
120} if_test_codes;
121
122# define first_if_test_code fi_code
123# define last_if_test_code  if_list_code
124//define last_if_test_code  if_bitwise_and_code
125
126# define first_real_if_test_code if_char_code
127# define last_real_if_test_code  if_list_code
128//define last_real_if_test_code  if_bitwise_and_code
129
130typedef struct condition_state_info {
131    halfword    cond_ptr;      /*tex top of the condition stack */
132    quarterword cur_if;        /*tex type of conditional being worked on */
133    quarterword if_limit;      /*tex upper bound on |fi_or_else| codes */
134    singleword  cur_unless;
135    singleword  if_unless;
136    singleword  if_step;
137    singleword  unused;
138    halfword    if_line;       /*tex line where that conditional began */
139    halfword    if_nesting;
140    halfword    skip_line;     /*tex skipping began here */
141    halfword    chk_integer;
142    scaled      chk_dimension;
143} condition_state_info ;
144
145extern condition_state_info lmt_condition_state;
146
147extern void tex_conditional_if         (halfword code, int unless);
148extern void tex_conditional_fi_or_else (void);
149extern void tex_conditional_unless     (void);
150extern void tex_show_ifs               (void);
151extern void tex_conditional_catch_up   (void);
152/*     void tex_quit_fi                (void); */
153/*     void tex_conditional_after_fi   (void); */
154
155# endif
156