]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bc/include/program.h
MFV: zstd 1.5.2
[FreeBSD/FreeBSD.git] / contrib / bc / include / program.h
1 /*
2  * *****************************************************************************
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  *
6  * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * * Redistributions of source code must retain the above copyright notice, this
12  *   list of conditions and the following disclaimer.
13  *
14  * * Redistributions in binary form must reproduce the above copyright notice,
15  *   this list of conditions and the following disclaimer in the documentation
16  *   and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * *****************************************************************************
31  *
32  * Definitions for bc programs.
33  *
34  */
35
36 #ifndef BC_PROGRAM_H
37 #define BC_PROGRAM_H
38
39 #include <assert.h>
40 #include <stddef.h>
41
42 #include <status.h>
43 #include <parse.h>
44 #include <lang.h>
45 #include <num.h>
46 #include <rand.h>
47
48 /// The index of ibase in the globals array.
49 #define BC_PROG_GLOBALS_IBASE (0)
50
51 /// The index of obase in the globals array.
52 #define BC_PROG_GLOBALS_OBASE (1)
53
54 /// The index of scale in the globals array.
55 #define BC_PROG_GLOBALS_SCALE (2)
56
57 #if BC_ENABLE_EXTRA_MATH
58
59 /// The index of the rand max in the maxes array.
60 #define BC_PROG_MAX_RAND (3)
61
62 #endif // BC_ENABLE_EXTRA_MATH
63
64 /// The length of the globals array.
65 #define BC_PROG_GLOBALS_LEN (3 + BC_ENABLE_EXTRA_MATH)
66
67 typedef struct BcProgram
68 {
69         /// The array of globals values.
70         BcBigDig globals[BC_PROG_GLOBALS_LEN];
71
72         /// The array of globals stacks.
73         BcVec globals_v[BC_PROG_GLOBALS_LEN];
74
75 #if BC_ENABLE_EXTRA_MATH
76
77         /// The pseudo-random number generator.
78         BcRNG rng;
79
80 #endif // BC_ENABLE_EXTRA_MATH
81
82         /// The results stack.
83         BcVec results;
84
85         /// The execution stack.
86         BcVec stack;
87
88         /// A pointer to the current function's constants.
89         BcVec* consts;
90
91         /// A pointer to the current function's strings.
92         BcVec* strs;
93
94         /// The array of functions.
95         BcVec fns;
96
97         /// The map of functions to go with fns.
98         BcVec fn_map;
99
100         /// The array of variables.
101         BcVec vars;
102
103         /// The map of variables to go with vars.
104         BcVec var_map;
105
106         /// The array of arrays.
107         BcVec arrs;
108
109         /// The map of arrays to go with arrs.
110         BcVec arr_map;
111
112 #if DC_ENABLED
113
114         /// A vector of tail calls. These are just integers, which are the number of
115         /// tail calls that have been executed for each function (string) on the
116         /// stack for dc. This is to prevent dc from constantly growing memory use
117         /// because of pushing more and more string executions on the stack.
118         BcVec tail_calls;
119
120 #endif // DC_ENABLED
121
122         /// A BcNum that has the proper base for asciify.
123         BcNum strmb;
124
125 #if BC_ENABLED
126
127         /// The last printed value for bc.
128         BcNum last;
129
130 #endif // BC_ENABLED
131
132         // The BcDig array for strmb. This uses BC_NUM_LONG_LOG10 because it is used
133         // in bc_num_ulong2num(), which attempts to realloc, unless it is big
134         // enough. This is big enough.
135         BcDig strmb_num[BC_NUM_BIGDIG_LOG10];
136
137 } BcProgram;
138
139 /**
140  * Returns true if the stack @a s has at least @a n items, false otherwise.
141  * @param s  The stack to check.
142  * @param n  The number of items the stack must have.
143  * @return   True if @a s has at least @a n items, false otherwise.
144  */
145 #define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) (n)))
146
147 /**
148  * Get a pointer to the top value in a global value stack.
149  * @param v  The global value stack.
150  * @return   A pointer to the top value in @a v.
151  */
152 #define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v))
153
154 /**
155  * Get the top value in a global value stack.
156  * @param v  The global value stack.
157  * @return   The top value in @a v.
158  */
159 #define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v)))
160
161 /**
162  * Returns the current value of ibase.
163  * @param p  The program.
164  * @return   The current ibase.
165  */
166 #define BC_PROG_IBASE(p) ((p)->globals[BC_PROG_GLOBALS_IBASE])
167
168 /**
169  * Returns the current value of obase.
170  * @param p  The program.
171  * @return   The current obase.
172  */
173 #define BC_PROG_OBASE(p) ((p)->globals[BC_PROG_GLOBALS_OBASE])
174
175 /**
176  * Returns the current value of scale.
177  * @param p  The program.
178  * @return   The current scale.
179  */
180 #define BC_PROG_SCALE(p) ((p)->globals[BC_PROG_GLOBALS_SCALE])
181
182 /// The index for the main function in the functions array.//
183 #define BC_PROG_MAIN (0)
184
185 /// The index for the read function in the functions array.
186 #define BC_PROG_READ (1)
187
188 /**
189  * Retires (completes the execution of) an instruction. Some instructions
190  * require special retirement, but most can use this. This basically pops the
191  * operands while preserving the result (which we assumed was pushed before the
192  * actual operation).
193  * @param p     The program.
194  * @param nres  The number of results returned by the instruction.
195  * @param nops  The number of operands used by the instruction.
196  */
197 #define bc_program_retire(p, nres, nops) \
198         (bc_vec_npopAt(&(p)->results, (nops), (p)->results.len - (nres + nops)))
199
200 #if DC_ENABLED
201
202 /// A constant that tells how many functions are required in dc.
203 #define BC_PROG_REQ_FUNCS (2)
204
205 #if !BC_ENABLED
206
207 /// This define disappears the parameter last because for dc only, last is
208 /// always true.
209 #define bc_program_copyToVar(p, name, t, last) bc_program_copyToVar(p, name, t)
210
211 #endif // !BC_ENABLED
212
213 #else // DC_ENABLED
214
215 /// This define disappears pop and copy because for bc, 'pop' and 'copy' are
216 /// always false.
217 #define bc_program_pushVar(p, code, bgn, pop, copy) \
218         bc_program_pushVar(p, code, bgn)
219
220 // In debug mode, we want bc to check the stack, but otherwise, we don't because
221 // the bc language implicitly mandates that the stack should always have enough
222 // items.
223 #ifdef NDEBUG
224 #define BC_PROG_NO_STACK_CHECK
225 #endif // NDEBUG
226
227 #endif // DC_ENABLED
228
229 /**
230  * Returns true if the BcNum @a n is acting as a string.
231  * @param n  The BcNum to test.
232  * @return   True if @a n is acting as a string, false otherwise.
233  */
234 #define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap)
235
236 #if BC_ENABLED
237
238 /**
239  * Returns true if the result @a r and @a n is a number.
240  * @param r  The result.
241  * @param n  The number corresponding to the result.
242  * @return   True if the result holds a number, false otherwise.
243  */
244 #define BC_PROG_NUM(r, n) \
245         ((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
246
247 #else // BC_ENABLED
248
249 /**
250  * Returns true if the result @a r and @a n is a number.
251  * @param r  The result.
252  * @param n  The number corresponding to the result.
253  * @return   True if the result holds a number, false otherwise.
254  */
255 #define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
256
257 #endif // BC_ENABLED
258
259 /**
260  * This is a function type for unary operations. Currently, these include
261  * boolean not, negation, and truncation with extra math.
262  * @param r  The BcResult to store the result into.
263  * @param n  The parameter to the unary operation.
264  */
265 typedef void (*BcProgramUnary)(BcResult* r, BcNum* n);
266
267 /**
268  * Initializes the BcProgram.
269  * @param p  The program to initialize.
270  */
271 void
272 bc_program_init(BcProgram* p);
273
274 #ifndef NDEBUG
275
276 /**
277  * Frees a BcProgram. This is only used in debug builds because a BcProgram is
278  * only freed on program exit, and we don't care about freeing resources on
279  * exit.
280  * @param p  The program to initialize.
281  */
282 void
283 bc_program_free(BcProgram* p);
284
285 #endif // NDEBUG
286
287 #if BC_DEBUG_CODE
288 #if BC_ENABLED && DC_ENABLED
289
290 /**
291  * Prints the bytecode in a function. This is a debug-only function.
292  * @param p  The program.
293  */
294 void
295 bc_program_code(const BcProgram* p);
296
297 /**
298  * Prints an instruction. This is a debug-only function.
299  * @param p  The program.
300  * @param code  The bytecode array.
301  * @param bgn   A pointer to the current index. It is also updated to the next
302  *              index.
303  */
304 void
305 bc_program_printInst(const BcProgram* p, const char* code,
306                      size_t* restrict bgn);
307
308 /**
309  * Prints the stack. This is a debug-only function.
310  * @param p  The program.
311  */
312 void
313 bc_program_printStackDebug(BcProgram* p);
314
315 #endif // BC_ENABLED && DC_ENABLED
316 #endif // BC_DEBUG_CODE
317
318 /**
319  * Returns the index of the variable or array in their respective arrays.
320  * @param p    The program.
321  * @param id   The BcId of the variable or array.
322  * @param var  True if the search should be for a variable, false for an array.
323  * @return     The index of the variable or array in the correct array.
324  */
325 size_t
326 bc_program_search(BcProgram* p, const char* id, bool var);
327
328 /**
329  * Adds a string to a function and returns the string's index in the function.
330  * @param p     The program.
331  * @param str   The string to add.
332  * @param fidx  The index of the function to add to.
333  */
334 size_t
335 bc_program_addString(BcProgram* p, const char* str, size_t fidx);
336
337 /**
338  * Inserts a function into the program and returns the index of the function in
339  * the fns array.
340  * @param p     The program.
341  * @param name  The name of the function.
342  * @return      The index of the function after insertion.
343  */
344 size_t
345 bc_program_insertFunc(BcProgram* p, const char* name);
346
347 /**
348  * Resets a program, usually because of resetting after an error.
349  * @param p  The program to reset.
350  */
351 void
352 bc_program_reset(BcProgram* p);
353
354 /**
355  * Executes bc or dc code in the BcProgram.
356  * @param p  The program.
357  */
358 void
359 bc_program_exec(BcProgram* p);
360
361 /**
362  * Negates a copy of a BcNum. This is a BcProgramUnary function.
363  * @param r  The BcResult to store the result into.
364  * @param n  The parameter to the unary operation.
365  */
366 void
367 bc_program_negate(BcResult* r, BcNum* n);
368
369 /**
370  * Returns a boolean not of a BcNum. This is a BcProgramUnary function.
371  * @param r  The BcResult to store the result into.
372  * @param n  The parameter to the unary operation.
373  */
374 void
375 bc_program_not(BcResult* r, BcNum* n);
376
377 #if BC_ENABLE_EXTRA_MATH
378
379 /**
380  * Truncates a copy of a BcNum. This is a BcProgramUnary function.
381  * @param r  The BcResult to store the result into.
382  * @param n  The parameter to the unary operation.
383  */
384 void
385 bc_program_trunc(BcResult* r, BcNum* n);
386
387 /**
388  * Assigns a value to the seed builtin variable.
389  * @param p    The program.
390  * @param val  The value to assign to the seed.
391  */
392 void
393 bc_program_assignSeed(BcProgram* p, BcNum* val);
394
395 #endif // BC_ENABLE_EXTRA_MATH
396
397 /**
398  * Assigns a value to a builtin value that is not seed.
399  * @param p      The program.
400  * @param scale  True if the builtin is scale.
401  * @param obase  True if the builtin is obase. This cannot be true at the same
402  *               time @a scale is.
403  * @param val    The value to assign to the builtin.
404  */
405 void
406 bc_program_assignBuiltin(BcProgram* p, bool scale, bool obase, BcBigDig val);
407
408 /// A reference to an array of binary operator functions.
409 extern const BcNumBinaryOp bc_program_ops[];
410
411 /// A reference to an array of binary operator allocation request functions.
412 extern const BcNumBinaryOpReq bc_program_opReqs[];
413
414 /// A reference to an array of unary operator functions.
415 extern const BcProgramUnary bc_program_unarys[];
416
417 /// A reference to a filename for command-line expressions.
418 extern const char bc_program_exprs_name[];
419
420 /// A reference to a filename for stdin.
421 extern const char bc_program_stdin_name[];
422
423 /// A reference to the ready message printed on SIGINT.
424 extern const char bc_program_ready_msg[];
425
426 /// A reference to the length of the ready message.
427 extern const size_t bc_program_ready_msg_len;
428
429 /// A reference to an array of escape characters for the print statement.
430 extern const char bc_program_esc_chars[];
431
432 /// A reference to an array of the characters corresponding to the escape
433 /// characters in bc_program_esc_chars.
434 extern const char bc_program_esc_seqs[];
435
436 #if BC_HAS_COMPUTED_GOTO
437
438 #if BC_DEBUG_CODE
439
440 // clang-format off
441 #define BC_PROG_JUMP(inst, code, ip)                                 \
442         do                                                               \
443         {                                                                \
444                 inst = (uchar) (code)[(ip)->idx++];                          \
445                 bc_file_printf(&vm.ferr, "inst: %s\n", bc_inst_names[inst]); \
446                 bc_file_flush(&vm.ferr, bc_flush_none);                      \
447                 goto *bc_program_inst_lbls[inst];                            \
448         }                                                                \
449         while (0)
450 // clang-format on
451
452 #else // BC_DEBUG_CODE
453
454 // clang-format off
455 #define BC_PROG_JUMP(inst, code, ip)        \
456         do                                      \
457         {                                       \
458                 inst = (uchar) (code)[(ip)->idx++]; \
459                 goto *bc_program_inst_lbls[inst];   \
460         }                                       \
461         while (0)
462 // clang-format on
463
464 #endif // BC_DEBUG_CODE
465
466 #define BC_PROG_DIRECT_JUMP(l) goto lbl_##l;
467 #define BC_PROG_LBL(l) lbl_##l
468 #define BC_PROG_FALLTHROUGH
469
470 #if BC_C11
471
472 #define BC_PROG_LBLS_SIZE (sizeof(bc_program_inst_lbls) / sizeof(void*))
473 #define BC_PROG_LBLS_ASSERT                                  \
474         _Static_assert(BC_PROG_LBLS_SIZE == BC_INST_INVALID + 1, \
475                        "bc_program_inst_lbls[] mismatches the instructions")
476
477 #else // BC_C11
478
479 #define BC_PROG_LBLS_ASSERT
480
481 #endif // BC_C11
482
483 #if BC_ENABLED
484
485 #if DC_ENABLED
486
487 #if BC_ENABLE_EXTRA_MATH
488
489 #define BC_PROG_LBLS                                    \
490         static const void* const bc_program_inst_lbls[] = { \
491                 &&lbl_BC_INST_INC,                              \
492                 &&lbl_BC_INST_DEC,                              \
493                 &&lbl_BC_INST_NEG,                              \
494                 &&lbl_BC_INST_BOOL_NOT,                         \
495                 &&lbl_BC_INST_TRUNC,                            \
496                 &&lbl_BC_INST_POWER,                            \
497                 &&lbl_BC_INST_MULTIPLY,                         \
498                 &&lbl_BC_INST_DIVIDE,                           \
499                 &&lbl_BC_INST_MODULUS,                          \
500                 &&lbl_BC_INST_PLUS,                             \
501                 &&lbl_BC_INST_MINUS,                            \
502                 &&lbl_BC_INST_PLACES,                           \
503                 &&lbl_BC_INST_LSHIFT,                           \
504                 &&lbl_BC_INST_RSHIFT,                           \
505                 &&lbl_BC_INST_REL_EQ,                           \
506                 &&lbl_BC_INST_REL_LE,                           \
507                 &&lbl_BC_INST_REL_GE,                           \
508                 &&lbl_BC_INST_REL_NE,                           \
509                 &&lbl_BC_INST_REL_LT,                           \
510                 &&lbl_BC_INST_REL_GT,                           \
511                 &&lbl_BC_INST_BOOL_OR,                          \
512                 &&lbl_BC_INST_BOOL_AND,                         \
513                 &&lbl_BC_INST_ASSIGN_POWER,                     \
514                 &&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
515                 &&lbl_BC_INST_ASSIGN_DIVIDE,                    \
516                 &&lbl_BC_INST_ASSIGN_MODULUS,                   \
517                 &&lbl_BC_INST_ASSIGN_PLUS,                      \
518                 &&lbl_BC_INST_ASSIGN_MINUS,                     \
519                 &&lbl_BC_INST_ASSIGN_PLACES,                    \
520                 &&lbl_BC_INST_ASSIGN_LSHIFT,                    \
521                 &&lbl_BC_INST_ASSIGN_RSHIFT,                    \
522                 &&lbl_BC_INST_ASSIGN,                           \
523                 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
524                 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
525                 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
526                 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
527                 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
528                 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
529                 &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL,             \
530                 &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL,             \
531                 &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL,             \
532                 &&lbl_BC_INST_ASSIGN_NO_VAL,                    \
533                 &&lbl_BC_INST_NUM,                              \
534                 &&lbl_BC_INST_VAR,                              \
535                 &&lbl_BC_INST_ARRAY_ELEM,                       \
536                 &&lbl_BC_INST_ARRAY,                            \
537                 &&lbl_BC_INST_ZERO,                             \
538                 &&lbl_BC_INST_ONE,                              \
539                 &&lbl_BC_INST_LAST,                             \
540                 &&lbl_BC_INST_IBASE,                            \
541                 &&lbl_BC_INST_OBASE,                            \
542                 &&lbl_BC_INST_SCALE,                            \
543                 &&lbl_BC_INST_SEED,                             \
544                 &&lbl_BC_INST_LENGTH,                           \
545                 &&lbl_BC_INST_SCALE_FUNC,                       \
546                 &&lbl_BC_INST_SQRT,                             \
547                 &&lbl_BC_INST_ABS,                              \
548                 &&lbl_BC_INST_IRAND,                            \
549                 &&lbl_BC_INST_ASCIIFY,                          \
550                 &&lbl_BC_INST_READ,                             \
551                 &&lbl_BC_INST_RAND,                             \
552                 &&lbl_BC_INST_MAXIBASE,                         \
553                 &&lbl_BC_INST_MAXOBASE,                         \
554                 &&lbl_BC_INST_MAXSCALE,                         \
555                 &&lbl_BC_INST_MAXRAND,                          \
556                 &&lbl_BC_INST_LINE_LENGTH,                      \
557                 &&lbl_BC_INST_GLOBAL_STACKS,                    \
558                 &&lbl_BC_INST_LEADING_ZERO,                     \
559                 &&lbl_BC_INST_PRINT,                            \
560                 &&lbl_BC_INST_PRINT_POP,                        \
561                 &&lbl_BC_INST_STR,                              \
562                 &&lbl_BC_INST_PRINT_STR,                        \
563                 &&lbl_BC_INST_JUMP,                             \
564                 &&lbl_BC_INST_JUMP_ZERO,                        \
565                 &&lbl_BC_INST_CALL,                             \
566                 &&lbl_BC_INST_RET,                              \
567                 &&lbl_BC_INST_RET0,                             \
568                 &&lbl_BC_INST_RET_VOID,                         \
569                 &&lbl_BC_INST_HALT,                             \
570                 &&lbl_BC_INST_POP,                              \
571                 &&lbl_BC_INST_SWAP,                             \
572                 &&lbl_BC_INST_MODEXP,                           \
573                 &&lbl_BC_INST_DIVMOD,                           \
574                 &&lbl_BC_INST_PRINT_STREAM,                     \
575                 &&lbl_BC_INST_POP_EXEC,                         \
576                 &&lbl_BC_INST_EXECUTE,                          \
577                 &&lbl_BC_INST_EXEC_COND,                        \
578                 &&lbl_BC_INST_PRINT_STACK,                      \
579                 &&lbl_BC_INST_CLEAR_STACK,                      \
580                 &&lbl_BC_INST_REG_STACK_LEN,                    \
581                 &&lbl_BC_INST_STACK_LEN,                        \
582                 &&lbl_BC_INST_DUPLICATE,                        \
583                 &&lbl_BC_INST_LOAD,                             \
584                 &&lbl_BC_INST_PUSH_VAR,                         \
585                 &&lbl_BC_INST_PUSH_TO_VAR,                      \
586                 &&lbl_BC_INST_QUIT,                             \
587                 &&lbl_BC_INST_NQUIT,                            \
588                 &&lbl_BC_INST_EXEC_STACK_LEN,                   \
589                 &&lbl_BC_INST_INVALID,                          \
590         }
591
592 #else // BC_ENABLE_EXTRA_MATH
593
594 #define BC_PROG_LBLS                                    \
595         static const void* const bc_program_inst_lbls[] = { \
596                 &&lbl_BC_INST_INC,                              \
597                 &&lbl_BC_INST_DEC,                              \
598                 &&lbl_BC_INST_NEG,                              \
599                 &&lbl_BC_INST_BOOL_NOT,                         \
600                 &&lbl_BC_INST_POWER,                            \
601                 &&lbl_BC_INST_MULTIPLY,                         \
602                 &&lbl_BC_INST_DIVIDE,                           \
603                 &&lbl_BC_INST_MODULUS,                          \
604                 &&lbl_BC_INST_PLUS,                             \
605                 &&lbl_BC_INST_MINUS,                            \
606                 &&lbl_BC_INST_REL_EQ,                           \
607                 &&lbl_BC_INST_REL_LE,                           \
608                 &&lbl_BC_INST_REL_GE,                           \
609                 &&lbl_BC_INST_REL_NE,                           \
610                 &&lbl_BC_INST_REL_LT,                           \
611                 &&lbl_BC_INST_REL_GT,                           \
612                 &&lbl_BC_INST_BOOL_OR,                          \
613                 &&lbl_BC_INST_BOOL_AND,                         \
614                 &&lbl_BC_INST_ASSIGN_POWER,                     \
615                 &&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
616                 &&lbl_BC_INST_ASSIGN_DIVIDE,                    \
617                 &&lbl_BC_INST_ASSIGN_MODULUS,                   \
618                 &&lbl_BC_INST_ASSIGN_PLUS,                      \
619                 &&lbl_BC_INST_ASSIGN_MINUS,                     \
620                 &&lbl_BC_INST_ASSIGN,                           \
621                 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
622                 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
623                 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
624                 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
625                 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
626                 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
627                 &&lbl_BC_INST_ASSIGN_NO_VAL,                    \
628                 &&lbl_BC_INST_NUM,                              \
629                 &&lbl_BC_INST_VAR,                              \
630                 &&lbl_BC_INST_ARRAY_ELEM,                       \
631                 &&lbl_BC_INST_ARRAY,                            \
632                 &&lbl_BC_INST_ZERO,                             \
633                 &&lbl_BC_INST_ONE,                              \
634                 &&lbl_BC_INST_LAST,                             \
635                 &&lbl_BC_INST_IBASE,                            \
636                 &&lbl_BC_INST_OBASE,                            \
637                 &&lbl_BC_INST_SCALE,                            \
638                 &&lbl_BC_INST_LENGTH,                           \
639                 &&lbl_BC_INST_SCALE_FUNC,                       \
640                 &&lbl_BC_INST_SQRT,                             \
641                 &&lbl_BC_INST_ABS,                              \
642                 &&lbl_BC_INST_ASCIIFY,                          \
643                 &&lbl_BC_INST_READ,                             \
644                 &&lbl_BC_INST_MAXIBASE,                         \
645                 &&lbl_BC_INST_MAXOBASE,                         \
646                 &&lbl_BC_INST_MAXSCALE,                         \
647                 &&lbl_BC_INST_LINE_LENGTH,                      \
648                 &&lbl_BC_INST_GLOBAL_STACKS,                    \
649                 &&lbl_BC_INST_LEADING_ZERO,                     \
650                 &&lbl_BC_INST_PRINT,                            \
651                 &&lbl_BC_INST_PRINT_POP,                        \
652                 &&lbl_BC_INST_STR,                              \
653                 &&lbl_BC_INST_PRINT_STR,                        \
654                 &&lbl_BC_INST_JUMP,                             \
655                 &&lbl_BC_INST_JUMP_ZERO,                        \
656                 &&lbl_BC_INST_CALL,                             \
657                 &&lbl_BC_INST_RET,                              \
658                 &&lbl_BC_INST_RET0,                             \
659                 &&lbl_BC_INST_RET_VOID,                         \
660                 &&lbl_BC_INST_HALT,                             \
661                 &&lbl_BC_INST_POP,                              \
662                 &&lbl_BC_INST_SWAP,                             \
663                 &&lbl_BC_INST_MODEXP,                           \
664                 &&lbl_BC_INST_DIVMOD,                           \
665                 &&lbl_BC_INST_PRINT_STREAM,                     \
666                 &&lbl_BC_INST_POP_EXEC,                         \
667                 &&lbl_BC_INST_EXECUTE,                          \
668                 &&lbl_BC_INST_EXEC_COND,                        \
669                 &&lbl_BC_INST_PRINT_STACK,                      \
670                 &&lbl_BC_INST_CLEAR_STACK,                      \
671                 &&lbl_BC_INST_REG_STACK_LEN,                    \
672                 &&lbl_BC_INST_STACK_LEN,                        \
673                 &&lbl_BC_INST_DUPLICATE,                        \
674                 &&lbl_BC_INST_LOAD,                             \
675                 &&lbl_BC_INST_PUSH_VAR,                         \
676                 &&lbl_BC_INST_PUSH_TO_VAR,                      \
677                 &&lbl_BC_INST_QUIT,                             \
678                 &&lbl_BC_INST_NQUIT,                            \
679                 &&lbl_BC_INST_EXEC_STACK_LEN,                   \
680                 &&lbl_BC_INST_INVALID,                          \
681         }
682
683 #endif // BC_ENABLE_EXTRA_MATH
684
685 #else // DC_ENABLED
686
687 #if BC_ENABLE_EXTRA_MATH
688
689 #define BC_PROG_LBLS                                    \
690         static const void* const bc_program_inst_lbls[] = { \
691                 &&lbl_BC_INST_INC,                              \
692                 &&lbl_BC_INST_DEC,                              \
693                 &&lbl_BC_INST_NEG,                              \
694                 &&lbl_BC_INST_BOOL_NOT,                         \
695                 &&lbl_BC_INST_TRUNC,                            \
696                 &&lbl_BC_INST_POWER,                            \
697                 &&lbl_BC_INST_MULTIPLY,                         \
698                 &&lbl_BC_INST_DIVIDE,                           \
699                 &&lbl_BC_INST_MODULUS,                          \
700                 &&lbl_BC_INST_PLUS,                             \
701                 &&lbl_BC_INST_MINUS,                            \
702                 &&lbl_BC_INST_PLACES,                           \
703                 &&lbl_BC_INST_LSHIFT,                           \
704                 &&lbl_BC_INST_RSHIFT,                           \
705                 &&lbl_BC_INST_REL_EQ,                           \
706                 &&lbl_BC_INST_REL_LE,                           \
707                 &&lbl_BC_INST_REL_GE,                           \
708                 &&lbl_BC_INST_REL_NE,                           \
709                 &&lbl_BC_INST_REL_LT,                           \
710                 &&lbl_BC_INST_REL_GT,                           \
711                 &&lbl_BC_INST_BOOL_OR,                          \
712                 &&lbl_BC_INST_BOOL_AND,                         \
713                 &&lbl_BC_INST_ASSIGN_POWER,                     \
714                 &&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
715                 &&lbl_BC_INST_ASSIGN_DIVIDE,                    \
716                 &&lbl_BC_INST_ASSIGN_MODULUS,                   \
717                 &&lbl_BC_INST_ASSIGN_PLUS,                      \
718                 &&lbl_BC_INST_ASSIGN_MINUS,                     \
719                 &&lbl_BC_INST_ASSIGN_PLACES,                    \
720                 &&lbl_BC_INST_ASSIGN_LSHIFT,                    \
721                 &&lbl_BC_INST_ASSIGN_RSHIFT,                    \
722                 &&lbl_BC_INST_ASSIGN,                           \
723                 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
724                 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
725                 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
726                 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
727                 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
728                 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
729                 &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL,             \
730                 &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL,             \
731                 &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL,             \
732                 &&lbl_BC_INST_ASSIGN_NO_VAL,                    \
733                 &&lbl_BC_INST_NUM,                              \
734                 &&lbl_BC_INST_VAR,                              \
735                 &&lbl_BC_INST_ARRAY_ELEM,                       \
736                 &&lbl_BC_INST_ARRAY,                            \
737                 &&lbl_BC_INST_ZERO,                             \
738                 &&lbl_BC_INST_ONE,                              \
739                 &&lbl_BC_INST_LAST,                             \
740                 &&lbl_BC_INST_IBASE,                            \
741                 &&lbl_BC_INST_OBASE,                            \
742                 &&lbl_BC_INST_SCALE,                            \
743                 &&lbl_BC_INST_SEED,                             \
744                 &&lbl_BC_INST_LENGTH,                           \
745                 &&lbl_BC_INST_SCALE_FUNC,                       \
746                 &&lbl_BC_INST_SQRT,                             \
747                 &&lbl_BC_INST_ABS,                              \
748                 &&lbl_BC_INST_IRAND,                            \
749                 &&lbl_BC_INST_ASCIIFY,                          \
750                 &&lbl_BC_INST_READ,                             \
751                 &&lbl_BC_INST_RAND,                             \
752                 &&lbl_BC_INST_MAXIBASE,                         \
753                 &&lbl_BC_INST_MAXOBASE,                         \
754                 &&lbl_BC_INST_MAXSCALE,                         \
755                 &&lbl_BC_INST_MAXRAND,                          \
756                 &&lbl_BC_INST_LINE_LENGTH,                      \
757                 &&lbl_BC_INST_GLOBAL_STACKS,                    \
758                 &&lbl_BC_INST_LEADING_ZERO,                     \
759                 &&lbl_BC_INST_PRINT,                            \
760                 &&lbl_BC_INST_PRINT_POP,                        \
761                 &&lbl_BC_INST_STR,                              \
762                 &&lbl_BC_INST_PRINT_STR,                        \
763                 &&lbl_BC_INST_JUMP,                             \
764                 &&lbl_BC_INST_JUMP_ZERO,                        \
765                 &&lbl_BC_INST_CALL,                             \
766                 &&lbl_BC_INST_RET,                              \
767                 &&lbl_BC_INST_RET0,                             \
768                 &&lbl_BC_INST_RET_VOID,                         \
769                 &&lbl_BC_INST_HALT,                             \
770                 &&lbl_BC_INST_POP,                              \
771                 &&lbl_BC_INST_SWAP,                             \
772                 &&lbl_BC_INST_MODEXP,                           \
773                 &&lbl_BC_INST_DIVMOD,                           \
774                 &&lbl_BC_INST_PRINT_STREAM,                     \
775                 &&lbl_BC_INST_INVALID,                          \
776         }
777
778 #else // BC_ENABLE_EXTRA_MATH
779
780 #define BC_PROG_LBLS                                    \
781         static const void* const bc_program_inst_lbls[] = { \
782                 &&lbl_BC_INST_INC,                              \
783                 &&lbl_BC_INST_DEC,                              \
784                 &&lbl_BC_INST_NEG,                              \
785                 &&lbl_BC_INST_BOOL_NOT,                         \
786                 &&lbl_BC_INST_POWER,                            \
787                 &&lbl_BC_INST_MULTIPLY,                         \
788                 &&lbl_BC_INST_DIVIDE,                           \
789                 &&lbl_BC_INST_MODULUS,                          \
790                 &&lbl_BC_INST_PLUS,                             \
791                 &&lbl_BC_INST_MINUS,                            \
792                 &&lbl_BC_INST_REL_EQ,                           \
793                 &&lbl_BC_INST_REL_LE,                           \
794                 &&lbl_BC_INST_REL_GE,                           \
795                 &&lbl_BC_INST_REL_NE,                           \
796                 &&lbl_BC_INST_REL_LT,                           \
797                 &&lbl_BC_INST_REL_GT,                           \
798                 &&lbl_BC_INST_BOOL_OR,                          \
799                 &&lbl_BC_INST_BOOL_AND,                         \
800                 &&lbl_BC_INST_ASSIGN_POWER,                     \
801                 &&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
802                 &&lbl_BC_INST_ASSIGN_DIVIDE,                    \
803                 &&lbl_BC_INST_ASSIGN_MODULUS,                   \
804                 &&lbl_BC_INST_ASSIGN_PLUS,                      \
805                 &&lbl_BC_INST_ASSIGN_MINUS,                     \
806                 &&lbl_BC_INST_ASSIGN,                           \
807                 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
808                 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
809                 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
810                 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
811                 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
812                 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
813                 &&lbl_BC_INST_ASSIGN_NO_VAL,                    \
814                 &&lbl_BC_INST_NUM,                              \
815                 &&lbl_BC_INST_VAR,                              \
816                 &&lbl_BC_INST_ARRAY_ELEM,                       \
817                 &&lbl_BC_INST_ARRAY,                            \
818                 &&lbl_BC_INST_ZERO,                             \
819                 &&lbl_BC_INST_ONE,                              \
820                 &&lbl_BC_INST_LAST,                             \
821                 &&lbl_BC_INST_IBASE,                            \
822                 &&lbl_BC_INST_OBASE,                            \
823                 &&lbl_BC_INST_SCALE,                            \
824                 &&lbl_BC_INST_LENGTH,                           \
825                 &&lbl_BC_INST_SCALE_FUNC,                       \
826                 &&lbl_BC_INST_SQRT,                             \
827                 &&lbl_BC_INST_ABS,                              \
828                 &&lbl_BC_INST_ASCIIFY,                          \
829                 &&lbl_BC_INST_READ,                             \
830                 &&lbl_BC_INST_MAXIBASE,                         \
831                 &&lbl_BC_INST_MAXOBASE,                         \
832                 &&lbl_BC_INST_MAXSCALE,                         \
833                 &&lbl_BC_INST_LINE_LENGTH,                      \
834                 &&lbl_BC_INST_GLOBAL_STACKS,                    \
835                 &&lbl_BC_INST_LEADING_ZERO,                     \
836                 &&lbl_BC_INST_PRINT,                            \
837                 &&lbl_BC_INST_PRINT_POP,                        \
838                 &&lbl_BC_INST_STR,                              \
839                 &&lbl_BC_INST_PRINT_STR,                        \
840                 &&lbl_BC_INST_JUMP,                             \
841                 &&lbl_BC_INST_JUMP_ZERO,                        \
842                 &&lbl_BC_INST_CALL,                             \
843                 &&lbl_BC_INST_RET,                              \
844                 &&lbl_BC_INST_RET0,                             \
845                 &&lbl_BC_INST_RET_VOID,                         \
846                 &&lbl_BC_INST_HALT,                             \
847                 &&lbl_BC_INST_POP,                              \
848                 &&lbl_BC_INST_SWAP,                             \
849                 &&lbl_BC_INST_MODEXP,                           \
850                 &&lbl_BC_INST_DIVMOD,                           \
851                 &&lbl_BC_INST_PRINT_STREAM,                     \
852                 &&lbl_BC_INST_INVALID,                          \
853         }
854
855 #endif // BC_ENABLE_EXTRA_MATH
856
857 #endif // DC_ENABLED
858
859 #else // BC_ENABLED
860
861 #if BC_ENABLE_EXTRA_MATH
862
863 #define BC_PROG_LBLS                                    \
864         static const void* const bc_program_inst_lbls[] = { \
865                 &&lbl_BC_INST_NEG,                              \
866                 &&lbl_BC_INST_BOOL_NOT,                         \
867                 &&lbl_BC_INST_TRUNC,                            \
868                 &&lbl_BC_INST_POWER,                            \
869                 &&lbl_BC_INST_MULTIPLY,                         \
870                 &&lbl_BC_INST_DIVIDE,                           \
871                 &&lbl_BC_INST_MODULUS,                          \
872                 &&lbl_BC_INST_PLUS,                             \
873                 &&lbl_BC_INST_MINUS,                            \
874                 &&lbl_BC_INST_PLACES,                           \
875                 &&lbl_BC_INST_LSHIFT,                           \
876                 &&lbl_BC_INST_RSHIFT,                           \
877                 &&lbl_BC_INST_REL_EQ,                           \
878                 &&lbl_BC_INST_REL_LE,                           \
879                 &&lbl_BC_INST_REL_GE,                           \
880                 &&lbl_BC_INST_REL_NE,                           \
881                 &&lbl_BC_INST_REL_LT,                           \
882                 &&lbl_BC_INST_REL_GT,                           \
883                 &&lbl_BC_INST_BOOL_OR,                          \
884                 &&lbl_BC_INST_BOOL_AND,                         \
885                 &&lbl_BC_INST_ASSIGN_NO_VAL,                    \
886                 &&lbl_BC_INST_NUM,                              \
887                 &&lbl_BC_INST_VAR,                              \
888                 &&lbl_BC_INST_ARRAY_ELEM,                       \
889                 &&lbl_BC_INST_ARRAY,                            \
890                 &&lbl_BC_INST_ZERO,                             \
891                 &&lbl_BC_INST_ONE,                              \
892                 &&lbl_BC_INST_IBASE,                            \
893                 &&lbl_BC_INST_OBASE,                            \
894                 &&lbl_BC_INST_SCALE,                            \
895                 &&lbl_BC_INST_SEED,                             \
896                 &&lbl_BC_INST_LENGTH,                           \
897                 &&lbl_BC_INST_SCALE_FUNC,                       \
898                 &&lbl_BC_INST_SQRT,                             \
899                 &&lbl_BC_INST_ABS,                              \
900                 &&lbl_BC_INST_IRAND,                            \
901                 &&lbl_BC_INST_ASCIIFY,                          \
902                 &&lbl_BC_INST_READ,                             \
903                 &&lbl_BC_INST_RAND,                             \
904                 &&lbl_BC_INST_MAXIBASE,                         \
905                 &&lbl_BC_INST_MAXOBASE,                         \
906                 &&lbl_BC_INST_MAXSCALE,                         \
907                 &&lbl_BC_INST_MAXRAND,                          \
908                 &&lbl_BC_INST_LINE_LENGTH,                      \
909                 &&lbl_BC_INST_LEADING_ZERO,                     \
910                 &&lbl_BC_INST_PRINT,                            \
911                 &&lbl_BC_INST_PRINT_POP,                        \
912                 &&lbl_BC_INST_STR,                              \
913                 &&lbl_BC_INST_POP,                              \
914                 &&lbl_BC_INST_SWAP,                             \
915                 &&lbl_BC_INST_MODEXP,                           \
916                 &&lbl_BC_INST_DIVMOD,                           \
917                 &&lbl_BC_INST_PRINT_STREAM,                     \
918                 &&lbl_BC_INST_POP_EXEC,                         \
919                 &&lbl_BC_INST_EXECUTE,                          \
920                 &&lbl_BC_INST_EXEC_COND,                        \
921                 &&lbl_BC_INST_PRINT_STACK,                      \
922                 &&lbl_BC_INST_CLEAR_STACK,                      \
923                 &&lbl_BC_INST_REG_STACK_LEN,                    \
924                 &&lbl_BC_INST_STACK_LEN,                        \
925                 &&lbl_BC_INST_DUPLICATE,                        \
926                 &&lbl_BC_INST_LOAD,                             \
927                 &&lbl_BC_INST_PUSH_VAR,                         \
928                 &&lbl_BC_INST_PUSH_TO_VAR,                      \
929                 &&lbl_BC_INST_QUIT,                             \
930                 &&lbl_BC_INST_NQUIT,                            \
931                 &&lbl_BC_INST_EXEC_STACK_LEN,                   \
932                 &&lbl_BC_INST_INVALID,                          \
933         }
934
935 #else // BC_ENABLE_EXTRA_MATH
936
937 #define BC_PROG_LBLS                                    \
938         static const void* const bc_program_inst_lbls[] = { \
939                 &&lbl_BC_INST_NEG,                              \
940                 &&lbl_BC_INST_BOOL_NOT,                         \
941                 &&lbl_BC_INST_POWER,                            \
942                 &&lbl_BC_INST_MULTIPLY,                         \
943                 &&lbl_BC_INST_DIVIDE,                           \
944                 &&lbl_BC_INST_MODULUS,                          \
945                 &&lbl_BC_INST_PLUS,                             \
946                 &&lbl_BC_INST_MINUS,                            \
947                 &&lbl_BC_INST_REL_EQ,                           \
948                 &&lbl_BC_INST_REL_LE,                           \
949                 &&lbl_BC_INST_REL_GE,                           \
950                 &&lbl_BC_INST_REL_NE,                           \
951                 &&lbl_BC_INST_REL_LT,                           \
952                 &&lbl_BC_INST_REL_GT,                           \
953                 &&lbl_BC_INST_BOOL_OR,                          \
954                 &&lbl_BC_INST_BOOL_AND,                         \
955                 &&lbl_BC_INST_ASSIGN_NO_VAL,                    \
956                 &&lbl_BC_INST_NUM,                              \
957                 &&lbl_BC_INST_VAR,                              \
958                 &&lbl_BC_INST_ARRAY_ELEM,                       \
959                 &&lbl_BC_INST_ARRAY,                            \
960                 &&lbl_BC_INST_ZERO,                             \
961                 &&lbl_BC_INST_ONE,                              \
962                 &&lbl_BC_INST_IBASE,                            \
963                 &&lbl_BC_INST_OBASE,                            \
964                 &&lbl_BC_INST_SCALE,                            \
965                 &&lbl_BC_INST_LENGTH,                           \
966                 &&lbl_BC_INST_SCALE_FUNC,                       \
967                 &&lbl_BC_INST_SQRT,                             \
968                 &&lbl_BC_INST_ABS,                              \
969                 &&lbl_BC_INST_ASCIIFY,                          \
970                 &&lbl_BC_INST_READ,                             \
971                 &&lbl_BC_INST_MAXIBASE,                         \
972                 &&lbl_BC_INST_MAXOBASE,                         \
973                 &&lbl_BC_INST_MAXSCALE,                         \
974                 &&lbl_BC_INST_LINE_LENGTH,                      \
975                 &&lbl_BC_INST_LEADING_ZERO,                     \
976                 &&lbl_BC_INST_PRINT,                            \
977                 &&lbl_BC_INST_PRINT_POP,                        \
978                 &&lbl_BC_INST_STR,                              \
979                 &&lbl_BC_INST_POP,                              \
980                 &&lbl_BC_INST_SWAP,                             \
981                 &&lbl_BC_INST_MODEXP,                           \
982                 &&lbl_BC_INST_DIVMOD,                           \
983                 &&lbl_BC_INST_PRINT_STREAM,                     \
984                 &&lbl_BC_INST_POP_EXEC,                         \
985                 &&lbl_BC_INST_EXECUTE,                          \
986                 &&lbl_BC_INST_EXEC_COND,                        \
987                 &&lbl_BC_INST_PRINT_STACK,                      \
988                 &&lbl_BC_INST_CLEAR_STACK,                      \
989                 &&lbl_BC_INST_REG_STACK_LEN,                    \
990                 &&lbl_BC_INST_STACK_LEN,                        \
991                 &&lbl_BC_INST_DUPLICATE,                        \
992                 &&lbl_BC_INST_LOAD,                             \
993                 &&lbl_BC_INST_PUSH_VAR,                         \
994                 &&lbl_BC_INST_PUSH_TO_VAR,                      \
995                 &&lbl_BC_INST_QUIT,                             \
996                 &&lbl_BC_INST_NQUIT,                            \
997                 &&lbl_BC_INST_EXEC_STACK_LEN,                   \
998                 &&lbl_BC_INST_INVALID,                          \
999         }
1000
1001 #endif // BC_ENABLE_EXTRA_MATH
1002
1003 #endif // BC_ENABLED
1004
1005 #else // BC_HAS_COMPUTED_GOTO
1006
1007 #define BC_PROG_JUMP(inst, code, ip) break
1008 #define BC_PROG_DIRECT_JUMP(l)
1009 #define BC_PROG_LBL(l) case l
1010 #define BC_PROG_FALLTHROUGH BC_FALLTHROUGH
1011
1012 #define BC_PROG_LBLS
1013
1014 #endif // BC_HAS_COMPUTED_GOTO
1015
1016 #endif // BC_PROGRAM_H