]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bc/include/program.h
usr.bin/gh-bc, contrib/bc: update to version 5.0.0
[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) \
210         bc_program_copyToVar(p, name, t)
211
212 #endif // !BC_ENABLED
213
214 #else // DC_ENABLED
215
216 /// This define disappears pop and copy because for bc, 'pop' and 'copy' are
217 /// always false.
218 #define bc_program_pushVar(p, code, bgn, pop, copy) \
219         bc_program_pushVar(p, code, bgn)
220
221 // In debug mode, we want bc to check the stack, but otherwise, we don't because
222 // the bc language implicitly mandates that the stack should always have enough
223 // items.
224 #ifdef NDEBUG
225 #define BC_PROG_NO_STACK_CHECK
226 #endif // NDEBUG
227
228 #endif // DC_ENABLED
229
230 /**
231  * Returns true if the BcNum @a n is acting as a string.
232  * @param n  The BcNum to test.
233  * @return   True if @a n is acting as a string, false otherwise.
234  */
235 #define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap)
236
237 #if BC_ENABLED
238
239 /**
240  * Returns true if the result @a r and @a n is a number.
241  * @param r  The result.
242  * @param n  The number corresponding to the result.
243  * @return   True if the result holds a number, false otherwise.
244  */
245 #define BC_PROG_NUM(r, n) \
246         ((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
247
248 #else // BC_ENABLED
249
250 /**
251  * Returns true if the result @a r and @a n is a number.
252  * @param r  The result.
253  * @param n  The number corresponding to the result.
254  * @return   True if the result holds a number, false otherwise.
255  */
256 #define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
257
258 #endif // BC_ENABLED
259
260 /**
261  * This is a function type for unary operations. Currently, these include
262  * boolean not, negation, and truncation with extra math.
263  * @param r  The BcResult to store the result into.
264  * @param n  The parameter to the unary operation.
265  */
266 typedef void (*BcProgramUnary)(BcResult *r, BcNum *n);
267
268 /**
269  * Initializes the BcProgram.
270  * @param p  The program to initialize.
271  */
272 void 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 bc_program_free(BcProgram *p);
283
284 #endif // NDEBUG
285
286 #if BC_DEBUG_CODE
287 #if BC_ENABLED && DC_ENABLED
288
289 /**
290  * Prints the bytecode in a function. This is a debug-only function.
291  * @param p  The program.
292  */
293 void bc_program_code(const BcProgram *p);
294
295 /**
296  * Prints an instruction. This is a debug-only function.
297  * @param p  The program.
298  * @param code  The bytecode array.
299  * @param bgn   A pointer to the current index. It is also updated to the next
300  *              index.
301  */
302 void bc_program_printInst(const BcProgram *p, const char *code,
303                           size_t *restrict bgn);
304
305 /**
306  * Prints the stack. This is a debug-only function.
307  * @param p  The program.
308  */
309 void bc_program_printStackDebug(BcProgram* p);
310
311 #endif // BC_ENABLED && DC_ENABLED
312 #endif // BC_DEBUG_CODE
313
314 /**
315  * Returns the index of the variable or array in their respective arrays.
316  * @param p    The program.
317  * @param id   The BcId of the variable or array.
318  * @param var  True if the search should be for a variable, false for an array.
319  * @return     The index of the variable or array in the correct array.
320  */
321 size_t bc_program_search(BcProgram *p, const char* id, bool var);
322
323 /**
324  * Adds a string to a function and returns the string's index in the function.
325  * @param p     The program.
326  * @param str   The string to add.
327  * @param fidx  The index of the function to add to.
328  */
329 size_t bc_program_addString(BcProgram *p, const char *str, size_t fidx);
330
331 /**
332  * Inserts a function into the program and returns the index of the function in
333  * the fns array.
334  * @param p     The program.
335  * @param name  The name of the function.
336  * @return      The index of the function after insertion.
337  */
338 size_t bc_program_insertFunc(BcProgram *p, const char *name);
339
340 /**
341  * Resets a program, usually because of resetting after an error.
342  * @param p  The program to reset.
343  */
344 void bc_program_reset(BcProgram *p);
345
346 /**
347  * Executes bc or dc code in the BcProgram.
348  * @param p  The program.
349  */
350 void bc_program_exec(BcProgram *p);
351
352 /**
353  * Negates a copy of a BcNum. This is a BcProgramUnary function.
354  * @param r  The BcResult to store the result into.
355  * @param n  The parameter to the unary operation.
356  */
357 void bc_program_negate(BcResult *r, BcNum *n);
358
359 /**
360  * Returns a boolean not of a BcNum. This is a BcProgramUnary function.
361  * @param r  The BcResult to store the result into.
362  * @param n  The parameter to the unary operation.
363  */
364 void bc_program_not(BcResult *r, BcNum *n);
365
366 #if BC_ENABLE_EXTRA_MATH
367
368 /**
369  * Truncates a copy of a BcNum. This is a BcProgramUnary function.
370  * @param r  The BcResult to store the result into.
371  * @param n  The parameter to the unary operation.
372  */
373 void bc_program_trunc(BcResult *r, BcNum *n);
374
375 #endif // BC_ENABLE_EXTRA_MATH
376
377 /// A reference to an array of binary operator functions.
378 extern const BcNumBinaryOp bc_program_ops[];
379
380 /// A reference to an array of binary operator allocation request functions.
381 extern const BcNumBinaryOpReq bc_program_opReqs[];
382
383 /// A reference to an array of unary operator functions.
384 extern const BcProgramUnary bc_program_unarys[];
385
386 /// A reference to a filename for command-line expressions.
387 extern const char bc_program_exprs_name[];
388
389 /// A reference to a filename for stdin.
390 extern const char bc_program_stdin_name[];
391
392 /// A reference to the ready message printed on SIGINT.
393 extern const char bc_program_ready_msg[];
394
395 /// A reference to the length of the ready message.
396 extern const size_t bc_program_ready_msg_len;
397
398 /// A reference to an array of escape characters for the print statement.
399 extern const char bc_program_esc_chars[];
400
401 /// A reference to an array of the characters corresponding to the escape
402 /// characters in bc_program_esc_chars.
403 extern const char bc_program_esc_seqs[];
404
405 #if BC_HAS_COMPUTED_GOTO
406
407 #if BC_DEBUG_CODE
408
409 #define BC_PROG_JUMP(inst, code, ip)                                 \
410         do {                                                             \
411                 inst = (uchar) (code)[(ip)->idx++];                          \
412                 bc_file_printf(&vm.ferr, "inst: %s\n", bc_inst_names[inst]); \
413                 bc_file_flush(&vm.ferr, bc_flush_none);                      \
414                 goto *bc_program_inst_lbls[inst];                            \
415         } while (0)
416
417 #else // BC_DEBUG_CODE
418
419 #define BC_PROG_JUMP(inst, code, ip)        \
420         do {                                    \
421                 inst = (uchar) (code)[(ip)->idx++]; \
422                 goto *bc_program_inst_lbls[inst];   \
423         } while (0)
424
425 #endif // BC_DEBUG_CODE
426
427 #define BC_PROG_DIRECT_JUMP(l) goto lbl_ ## l;
428 #define BC_PROG_LBL(l) lbl_ ## l
429 #define BC_PROG_FALLTHROUGH
430
431 #if BC_C11
432
433 #define BC_PROG_LBLS_SIZE (sizeof(bc_program_inst_lbls) / sizeof(void*))
434 #define BC_PROG_LBLS_ASSERT \
435         static_assert(BC_PROG_LBLS_SIZE == BC_INST_INVALID + 1,\
436                       "bc_program_inst_lbls[] mismatches the instructions")
437
438 #else // BC_C11
439
440 #define BC_PROG_LBLS_ASSERT
441
442 #endif // BC_C11
443
444 #if BC_ENABLED
445
446 #if DC_ENABLED
447
448 #if BC_ENABLE_EXTRA_MATH
449
450 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
451         &&lbl_BC_INST_INC,                                                   \
452         &&lbl_BC_INST_DEC,                                                   \
453         &&lbl_BC_INST_NEG,                                                   \
454         &&lbl_BC_INST_BOOL_NOT,                                              \
455         &&lbl_BC_INST_TRUNC,                                                 \
456         &&lbl_BC_INST_POWER,                                                 \
457         &&lbl_BC_INST_MULTIPLY,                                              \
458         &&lbl_BC_INST_DIVIDE,                                                \
459         &&lbl_BC_INST_MODULUS,                                               \
460         &&lbl_BC_INST_PLUS,                                                  \
461         &&lbl_BC_INST_MINUS,                                                 \
462         &&lbl_BC_INST_PLACES,                                                \
463         &&lbl_BC_INST_LSHIFT,                                                \
464         &&lbl_BC_INST_RSHIFT,                                                \
465         &&lbl_BC_INST_REL_EQ,                                                \
466         &&lbl_BC_INST_REL_LE,                                                \
467         &&lbl_BC_INST_REL_GE,                                                \
468         &&lbl_BC_INST_REL_NE,                                                \
469         &&lbl_BC_INST_REL_LT,                                                \
470         &&lbl_BC_INST_REL_GT,                                                \
471         &&lbl_BC_INST_BOOL_OR,                                               \
472         &&lbl_BC_INST_BOOL_AND,                                              \
473         &&lbl_BC_INST_ASSIGN_POWER,                                          \
474         &&lbl_BC_INST_ASSIGN_MULTIPLY,                                       \
475         &&lbl_BC_INST_ASSIGN_DIVIDE,                                         \
476         &&lbl_BC_INST_ASSIGN_MODULUS,                                        \
477         &&lbl_BC_INST_ASSIGN_PLUS,                                           \
478         &&lbl_BC_INST_ASSIGN_MINUS,                                          \
479         &&lbl_BC_INST_ASSIGN_PLACES,                                         \
480         &&lbl_BC_INST_ASSIGN_LSHIFT,                                         \
481         &&lbl_BC_INST_ASSIGN_RSHIFT,                                         \
482         &&lbl_BC_INST_ASSIGN,                                                \
483         &&lbl_BC_INST_ASSIGN_POWER_NO_VAL,                                   \
484         &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,                                \
485         &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,                                  \
486         &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,                                 \
487         &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,                                    \
488         &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,                                   \
489         &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL,                                  \
490         &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL,                                  \
491         &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL,                                  \
492         &&lbl_BC_INST_ASSIGN_NO_VAL,                                         \
493         &&lbl_BC_INST_NUM,                                                   \
494         &&lbl_BC_INST_VAR,                                                   \
495         &&lbl_BC_INST_ARRAY_ELEM,                                            \
496         &&lbl_BC_INST_ARRAY,                                                 \
497         &&lbl_BC_INST_ZERO,                                                  \
498         &&lbl_BC_INST_ONE,                                                   \
499         &&lbl_BC_INST_LAST,                                                  \
500         &&lbl_BC_INST_IBASE,                                                 \
501         &&lbl_BC_INST_OBASE,                                                 \
502         &&lbl_BC_INST_SCALE,                                                 \
503         &&lbl_BC_INST_SEED,                                                  \
504         &&lbl_BC_INST_LENGTH,                                                \
505         &&lbl_BC_INST_SCALE_FUNC,                                            \
506         &&lbl_BC_INST_SQRT,                                                  \
507         &&lbl_BC_INST_ABS,                                                   \
508         &&lbl_BC_INST_IRAND,                                                 \
509         &&lbl_BC_INST_ASCIIFY,                                               \
510         &&lbl_BC_INST_READ,                                                  \
511         &&lbl_BC_INST_RAND,                                                  \
512         &&lbl_BC_INST_MAXIBASE,                                              \
513         &&lbl_BC_INST_MAXOBASE,                                              \
514         &&lbl_BC_INST_MAXSCALE,                                              \
515         &&lbl_BC_INST_MAXRAND,                                               \
516         &&lbl_BC_INST_LINE_LENGTH,                                           \
517         &&lbl_BC_INST_GLOBAL_STACKS,                                         \
518         &&lbl_BC_INST_LEADING_ZERO,                                          \
519         &&lbl_BC_INST_PRINT,                                                 \
520         &&lbl_BC_INST_PRINT_POP,                                             \
521         &&lbl_BC_INST_STR,                                                   \
522         &&lbl_BC_INST_PRINT_STR,                                             \
523         &&lbl_BC_INST_JUMP,                                                  \
524         &&lbl_BC_INST_JUMP_ZERO,                                             \
525         &&lbl_BC_INST_CALL,                                                  \
526         &&lbl_BC_INST_RET,                                                   \
527         &&lbl_BC_INST_RET0,                                                  \
528         &&lbl_BC_INST_RET_VOID,                                              \
529         &&lbl_BC_INST_HALT,                                                  \
530         &&lbl_BC_INST_POP,                                                   \
531         &&lbl_BC_INST_SWAP,                                                  \
532         &&lbl_BC_INST_MODEXP,                                                \
533         &&lbl_BC_INST_DIVMOD,                                                \
534         &&lbl_BC_INST_PRINT_STREAM,                                          \
535         &&lbl_BC_INST_POP_EXEC,                                              \
536         &&lbl_BC_INST_EXECUTE,                                               \
537         &&lbl_BC_INST_EXEC_COND,                                             \
538         &&lbl_BC_INST_PRINT_STACK,                                           \
539         &&lbl_BC_INST_CLEAR_STACK,                                           \
540         &&lbl_BC_INST_REG_STACK_LEN,                                         \
541         &&lbl_BC_INST_STACK_LEN,                                             \
542         &&lbl_BC_INST_DUPLICATE,                                             \
543         &&lbl_BC_INST_LOAD,                                                  \
544         &&lbl_BC_INST_PUSH_VAR,                                              \
545         &&lbl_BC_INST_PUSH_TO_VAR,                                           \
546         &&lbl_BC_INST_QUIT,                                                  \
547         &&lbl_BC_INST_NQUIT,                                                 \
548         &&lbl_BC_INST_EXEC_STACK_LEN,                                        \
549         &&lbl_BC_INST_INVALID,                                               \
550 }
551
552 #else // BC_ENABLE_EXTRA_MATH
553
554 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
555         &&lbl_BC_INST_INC,                                                   \
556         &&lbl_BC_INST_DEC,                                                   \
557         &&lbl_BC_INST_NEG,                                                   \
558         &&lbl_BC_INST_BOOL_NOT,                                              \
559         &&lbl_BC_INST_POWER,                                                 \
560         &&lbl_BC_INST_MULTIPLY,                                              \
561         &&lbl_BC_INST_DIVIDE,                                                \
562         &&lbl_BC_INST_MODULUS,                                               \
563         &&lbl_BC_INST_PLUS,                                                  \
564         &&lbl_BC_INST_MINUS,                                                 \
565         &&lbl_BC_INST_REL_EQ,                                                \
566         &&lbl_BC_INST_REL_LE,                                                \
567         &&lbl_BC_INST_REL_GE,                                                \
568         &&lbl_BC_INST_REL_NE,                                                \
569         &&lbl_BC_INST_REL_LT,                                                \
570         &&lbl_BC_INST_REL_GT,                                                \
571         &&lbl_BC_INST_BOOL_OR,                                               \
572         &&lbl_BC_INST_BOOL_AND,                                              \
573         &&lbl_BC_INST_ASSIGN_POWER,                                          \
574         &&lbl_BC_INST_ASSIGN_MULTIPLY,                                       \
575         &&lbl_BC_INST_ASSIGN_DIVIDE,                                         \
576         &&lbl_BC_INST_ASSIGN_MODULUS,                                        \
577         &&lbl_BC_INST_ASSIGN_PLUS,                                           \
578         &&lbl_BC_INST_ASSIGN_MINUS,                                          \
579         &&lbl_BC_INST_ASSIGN,                                                \
580         &&lbl_BC_INST_ASSIGN_POWER_NO_VAL,                                   \
581         &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,                                \
582         &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,                                  \
583         &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,                                 \
584         &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,                                    \
585         &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,                                   \
586         &&lbl_BC_INST_ASSIGN_NO_VAL,                                         \
587         &&lbl_BC_INST_NUM,                                                   \
588         &&lbl_BC_INST_VAR,                                                   \
589         &&lbl_BC_INST_ARRAY_ELEM,                                            \
590         &&lbl_BC_INST_ARRAY,                                                 \
591         &&lbl_BC_INST_ZERO,                                                  \
592         &&lbl_BC_INST_ONE,                                                   \
593         &&lbl_BC_INST_LAST,                                                  \
594         &&lbl_BC_INST_IBASE,                                                 \
595         &&lbl_BC_INST_OBASE,                                                 \
596         &&lbl_BC_INST_SCALE,                                                 \
597         &&lbl_BC_INST_LENGTH,                                                \
598         &&lbl_BC_INST_SCALE_FUNC,                                            \
599         &&lbl_BC_INST_SQRT,                                                  \
600         &&lbl_BC_INST_ABS,                                                   \
601         &&lbl_BC_INST_ASCIIFY,                                               \
602         &&lbl_BC_INST_READ,                                                  \
603         &&lbl_BC_INST_MAXIBASE,                                              \
604         &&lbl_BC_INST_MAXOBASE,                                              \
605         &&lbl_BC_INST_MAXSCALE,                                              \
606         &&lbl_BC_INST_LINE_LENGTH,                                           \
607         &&lbl_BC_INST_GLOBAL_STACKS,                                         \
608         &&lbl_BC_INST_LEADING_ZERO,                                          \
609         &&lbl_BC_INST_PRINT,                                                 \
610         &&lbl_BC_INST_PRINT_POP,                                             \
611         &&lbl_BC_INST_STR,                                                   \
612         &&lbl_BC_INST_PRINT_STR,                                             \
613         &&lbl_BC_INST_JUMP,                                                  \
614         &&lbl_BC_INST_JUMP_ZERO,                                             \
615         &&lbl_BC_INST_CALL,                                                  \
616         &&lbl_BC_INST_RET,                                                   \
617         &&lbl_BC_INST_RET0,                                                  \
618         &&lbl_BC_INST_RET_VOID,                                              \
619         &&lbl_BC_INST_HALT,                                                  \
620         &&lbl_BC_INST_POP,                                                   \
621         &&lbl_BC_INST_SWAP,                                                  \
622         &&lbl_BC_INST_MODEXP,                                                \
623         &&lbl_BC_INST_DIVMOD,                                                \
624         &&lbl_BC_INST_PRINT_STREAM,                                          \
625         &&lbl_BC_INST_POP_EXEC,                                              \
626         &&lbl_BC_INST_EXECUTE,                                               \
627         &&lbl_BC_INST_EXEC_COND,                                             \
628         &&lbl_BC_INST_PRINT_STACK,                                           \
629         &&lbl_BC_INST_CLEAR_STACK,                                           \
630         &&lbl_BC_INST_REG_STACK_LEN,                                         \
631         &&lbl_BC_INST_STACK_LEN,                                             \
632         &&lbl_BC_INST_DUPLICATE,                                             \
633         &&lbl_BC_INST_LOAD,                                                  \
634         &&lbl_BC_INST_PUSH_VAR,                                              \
635         &&lbl_BC_INST_PUSH_TO_VAR,                                           \
636         &&lbl_BC_INST_QUIT,                                                  \
637         &&lbl_BC_INST_NQUIT,                                                 \
638         &&lbl_BC_INST_EXEC_STACK_LEN,                                        \
639         &&lbl_BC_INST_INVALID,                                               \
640 }
641
642 #endif // BC_ENABLE_EXTRA_MATH
643
644 #else // DC_ENABLED
645
646 #if BC_ENABLE_EXTRA_MATH
647
648 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
649         &&lbl_BC_INST_INC,                                                   \
650         &&lbl_BC_INST_DEC,                                                   \
651         &&lbl_BC_INST_NEG,                                                   \
652         &&lbl_BC_INST_BOOL_NOT,                                              \
653         &&lbl_BC_INST_TRUNC,                                                 \
654         &&lbl_BC_INST_POWER,                                                 \
655         &&lbl_BC_INST_MULTIPLY,                                              \
656         &&lbl_BC_INST_DIVIDE,                                                \
657         &&lbl_BC_INST_MODULUS,                                               \
658         &&lbl_BC_INST_PLUS,                                                  \
659         &&lbl_BC_INST_MINUS,                                                 \
660         &&lbl_BC_INST_PLACES,                                                \
661         &&lbl_BC_INST_LSHIFT,                                                \
662         &&lbl_BC_INST_RSHIFT,                                                \
663         &&lbl_BC_INST_REL_EQ,                                                \
664         &&lbl_BC_INST_REL_LE,                                                \
665         &&lbl_BC_INST_REL_GE,                                                \
666         &&lbl_BC_INST_REL_NE,                                                \
667         &&lbl_BC_INST_REL_LT,                                                \
668         &&lbl_BC_INST_REL_GT,                                                \
669         &&lbl_BC_INST_BOOL_OR,                                               \
670         &&lbl_BC_INST_BOOL_AND,                                              \
671         &&lbl_BC_INST_ASSIGN_POWER,                                          \
672         &&lbl_BC_INST_ASSIGN_MULTIPLY,                                       \
673         &&lbl_BC_INST_ASSIGN_DIVIDE,                                         \
674         &&lbl_BC_INST_ASSIGN_MODULUS,                                        \
675         &&lbl_BC_INST_ASSIGN_PLUS,                                           \
676         &&lbl_BC_INST_ASSIGN_MINUS,                                          \
677         &&lbl_BC_INST_ASSIGN_PLACES,                                         \
678         &&lbl_BC_INST_ASSIGN_LSHIFT,                                         \
679         &&lbl_BC_INST_ASSIGN_RSHIFT,                                         \
680         &&lbl_BC_INST_ASSIGN,                                                \
681         &&lbl_BC_INST_ASSIGN_POWER_NO_VAL,                                   \
682         &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,                                \
683         &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,                                  \
684         &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,                                 \
685         &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,                                    \
686         &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,                                   \
687         &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL,                                  \
688         &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL,                                  \
689         &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL,                                  \
690         &&lbl_BC_INST_ASSIGN_NO_VAL,                                         \
691         &&lbl_BC_INST_NUM,                                                   \
692         &&lbl_BC_INST_VAR,                                                   \
693         &&lbl_BC_INST_ARRAY_ELEM,                                            \
694         &&lbl_BC_INST_ARRAY,                                                 \
695         &&lbl_BC_INST_ZERO,                                                  \
696         &&lbl_BC_INST_ONE,                                                   \
697         &&lbl_BC_INST_LAST,                                                  \
698         &&lbl_BC_INST_IBASE,                                                 \
699         &&lbl_BC_INST_OBASE,                                                 \
700         &&lbl_BC_INST_SCALE,                                                 \
701         &&lbl_BC_INST_SEED,                                                  \
702         &&lbl_BC_INST_LENGTH,                                                \
703         &&lbl_BC_INST_SCALE_FUNC,                                            \
704         &&lbl_BC_INST_SQRT,                                                  \
705         &&lbl_BC_INST_ABS,                                                   \
706         &&lbl_BC_INST_IRAND,                                                 \
707         &&lbl_BC_INST_ASCIIFY,                                               \
708         &&lbl_BC_INST_READ,                                                  \
709         &&lbl_BC_INST_RAND,                                                  \
710         &&lbl_BC_INST_MAXIBASE,                                              \
711         &&lbl_BC_INST_MAXOBASE,                                              \
712         &&lbl_BC_INST_MAXSCALE,                                              \
713         &&lbl_BC_INST_MAXRAND,                                               \
714         &&lbl_BC_INST_LINE_LENGTH,                                           \
715         &&lbl_BC_INST_GLOBAL_STACKS,                                         \
716         &&lbl_BC_INST_LEADING_ZERO,                                          \
717         &&lbl_BC_INST_PRINT,                                                 \
718         &&lbl_BC_INST_PRINT_POP,                                             \
719         &&lbl_BC_INST_STR,                                                   \
720         &&lbl_BC_INST_PRINT_STR,                                             \
721         &&lbl_BC_INST_JUMP,                                                  \
722         &&lbl_BC_INST_JUMP_ZERO,                                             \
723         &&lbl_BC_INST_CALL,                                                  \
724         &&lbl_BC_INST_RET,                                                   \
725         &&lbl_BC_INST_RET0,                                                  \
726         &&lbl_BC_INST_RET_VOID,                                              \
727         &&lbl_BC_INST_HALT,                                                  \
728         &&lbl_BC_INST_POP,                                                   \
729         &&lbl_BC_INST_SWAP,                                                  \
730         &&lbl_BC_INST_MODEXP,                                                \
731         &&lbl_BC_INST_DIVMOD,                                                \
732         &&lbl_BC_INST_PRINT_STREAM,                                          \
733         &&lbl_BC_INST_INVALID,                                               \
734 }
735
736 #else // BC_ENABLE_EXTRA_MATH
737
738 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
739         &&lbl_BC_INST_INC,                                                   \
740         &&lbl_BC_INST_DEC,                                                   \
741         &&lbl_BC_INST_NEG,                                                   \
742         &&lbl_BC_INST_BOOL_NOT,                                              \
743         &&lbl_BC_INST_POWER,                                                 \
744         &&lbl_BC_INST_MULTIPLY,                                              \
745         &&lbl_BC_INST_DIVIDE,                                                \
746         &&lbl_BC_INST_MODULUS,                                               \
747         &&lbl_BC_INST_PLUS,                                                  \
748         &&lbl_BC_INST_MINUS,                                                 \
749         &&lbl_BC_INST_REL_EQ,                                                \
750         &&lbl_BC_INST_REL_LE,                                                \
751         &&lbl_BC_INST_REL_GE,                                                \
752         &&lbl_BC_INST_REL_NE,                                                \
753         &&lbl_BC_INST_REL_LT,                                                \
754         &&lbl_BC_INST_REL_GT,                                                \
755         &&lbl_BC_INST_BOOL_OR,                                               \
756         &&lbl_BC_INST_BOOL_AND,                                              \
757         &&lbl_BC_INST_ASSIGN_POWER,                                          \
758         &&lbl_BC_INST_ASSIGN_MULTIPLY,                                       \
759         &&lbl_BC_INST_ASSIGN_DIVIDE,                                         \
760         &&lbl_BC_INST_ASSIGN_MODULUS,                                        \
761         &&lbl_BC_INST_ASSIGN_PLUS,                                           \
762         &&lbl_BC_INST_ASSIGN_MINUS,                                          \
763         &&lbl_BC_INST_ASSIGN,                                                \
764         &&lbl_BC_INST_ASSIGN_POWER_NO_VAL,                                   \
765         &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,                                \
766         &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,                                  \
767         &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,                                 \
768         &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,                                    \
769         &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,                                   \
770         &&lbl_BC_INST_ASSIGN_NO_VAL,                                         \
771         &&lbl_BC_INST_NUM,                                                   \
772         &&lbl_BC_INST_VAR,                                                   \
773         &&lbl_BC_INST_ARRAY_ELEM,                                            \
774         &&lbl_BC_INST_ARRAY,                                                 \
775         &&lbl_BC_INST_ZERO,                                                  \
776         &&lbl_BC_INST_ONE,                                                   \
777         &&lbl_BC_INST_LAST,                                                  \
778         &&lbl_BC_INST_IBASE,                                                 \
779         &&lbl_BC_INST_OBASE,                                                 \
780         &&lbl_BC_INST_SCALE,                                                 \
781         &&lbl_BC_INST_LENGTH,                                                \
782         &&lbl_BC_INST_SCALE_FUNC,                                            \
783         &&lbl_BC_INST_SQRT,                                                  \
784         &&lbl_BC_INST_ABS,                                                   \
785         &&lbl_BC_INST_ASCIIFY,                                               \
786         &&lbl_BC_INST_READ,                                                  \
787         &&lbl_BC_INST_MAXIBASE,                                              \
788         &&lbl_BC_INST_MAXOBASE,                                              \
789         &&lbl_BC_INST_MAXSCALE,                                              \
790         &&lbl_BC_INST_LINE_LENGTH,                                           \
791         &&lbl_BC_INST_GLOBAL_STACKS,                                         \
792         &&lbl_BC_INST_LEADING_ZERO,                                          \
793         &&lbl_BC_INST_PRINT,                                                 \
794         &&lbl_BC_INST_PRINT_POP,                                             \
795         &&lbl_BC_INST_STR,                                                   \
796         &&lbl_BC_INST_PRINT_STR,                                             \
797         &&lbl_BC_INST_JUMP,                                                  \
798         &&lbl_BC_INST_JUMP_ZERO,                                             \
799         &&lbl_BC_INST_CALL,                                                  \
800         &&lbl_BC_INST_RET,                                                   \
801         &&lbl_BC_INST_RET0,                                                  \
802         &&lbl_BC_INST_RET_VOID,                                              \
803         &&lbl_BC_INST_HALT,                                                  \
804         &&lbl_BC_INST_POP,                                                   \
805         &&lbl_BC_INST_SWAP,                                                  \
806         &&lbl_BC_INST_MODEXP,                                                \
807         &&lbl_BC_INST_DIVMOD,                                                \
808         &&lbl_BC_INST_PRINT_STREAM,                                          \
809         &&lbl_BC_INST_INVALID,                                               \
810 }
811
812 #endif // BC_ENABLE_EXTRA_MATH
813
814 #endif // DC_ENABLED
815
816 #else // BC_ENABLED
817
818 #if BC_ENABLE_EXTRA_MATH
819
820 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
821         &&lbl_BC_INST_NEG,                                                   \
822         &&lbl_BC_INST_BOOL_NOT,                                              \
823         &&lbl_BC_INST_TRUNC,                                                 \
824         &&lbl_BC_INST_POWER,                                                 \
825         &&lbl_BC_INST_MULTIPLY,                                              \
826         &&lbl_BC_INST_DIVIDE,                                                \
827         &&lbl_BC_INST_MODULUS,                                               \
828         &&lbl_BC_INST_PLUS,                                                  \
829         &&lbl_BC_INST_MINUS,                                                 \
830         &&lbl_BC_INST_PLACES,                                                \
831         &&lbl_BC_INST_LSHIFT,                                                \
832         &&lbl_BC_INST_RSHIFT,                                                \
833         &&lbl_BC_INST_REL_EQ,                                                \
834         &&lbl_BC_INST_REL_LE,                                                \
835         &&lbl_BC_INST_REL_GE,                                                \
836         &&lbl_BC_INST_REL_NE,                                                \
837         &&lbl_BC_INST_REL_LT,                                                \
838         &&lbl_BC_INST_REL_GT,                                                \
839         &&lbl_BC_INST_BOOL_OR,                                               \
840         &&lbl_BC_INST_BOOL_AND,                                              \
841         &&lbl_BC_INST_ASSIGN_NO_VAL,                                         \
842         &&lbl_BC_INST_NUM,                                                   \
843         &&lbl_BC_INST_VAR,                                                   \
844         &&lbl_BC_INST_ARRAY_ELEM,                                            \
845         &&lbl_BC_INST_ARRAY,                                                 \
846         &&lbl_BC_INST_ZERO,                                                  \
847         &&lbl_BC_INST_ONE,                                                   \
848         &&lbl_BC_INST_IBASE,                                                 \
849         &&lbl_BC_INST_OBASE,                                                 \
850         &&lbl_BC_INST_SCALE,                                                 \
851         &&lbl_BC_INST_SEED,                                                  \
852         &&lbl_BC_INST_LENGTH,                                                \
853         &&lbl_BC_INST_SCALE_FUNC,                                            \
854         &&lbl_BC_INST_SQRT,                                                  \
855         &&lbl_BC_INST_ABS,                                                   \
856         &&lbl_BC_INST_IRAND,                                                 \
857         &&lbl_BC_INST_ASCIIFY,                                               \
858         &&lbl_BC_INST_READ,                                                  \
859         &&lbl_BC_INST_RAND,                                                  \
860         &&lbl_BC_INST_MAXIBASE,                                              \
861         &&lbl_BC_INST_MAXOBASE,                                              \
862         &&lbl_BC_INST_MAXSCALE,                                              \
863         &&lbl_BC_INST_MAXRAND,                                               \
864         &&lbl_BC_INST_LINE_LENGTH,                                           \
865         &&lbl_BC_INST_LEADING_ZERO,                                          \
866         &&lbl_BC_INST_PRINT,                                                 \
867         &&lbl_BC_INST_PRINT_POP,                                             \
868         &&lbl_BC_INST_STR,                                                   \
869         &&lbl_BC_INST_POP,                                                   \
870         &&lbl_BC_INST_SWAP,                                                  \
871         &&lbl_BC_INST_MODEXP,                                                \
872         &&lbl_BC_INST_DIVMOD,                                                \
873         &&lbl_BC_INST_PRINT_STREAM,                                          \
874         &&lbl_BC_INST_POP_EXEC,                                              \
875         &&lbl_BC_INST_EXECUTE,                                               \
876         &&lbl_BC_INST_EXEC_COND,                                             \
877         &&lbl_BC_INST_PRINT_STACK,                                           \
878         &&lbl_BC_INST_CLEAR_STACK,                                           \
879         &&lbl_BC_INST_REG_STACK_LEN,                                         \
880         &&lbl_BC_INST_STACK_LEN,                                             \
881         &&lbl_BC_INST_DUPLICATE,                                             \
882         &&lbl_BC_INST_LOAD,                                                  \
883         &&lbl_BC_INST_PUSH_VAR,                                              \
884         &&lbl_BC_INST_PUSH_TO_VAR,                                           \
885         &&lbl_BC_INST_QUIT,                                                  \
886         &&lbl_BC_INST_NQUIT,                                                 \
887         &&lbl_BC_INST_EXEC_STACK_LEN,                                        \
888         &&lbl_BC_INST_INVALID,                                               \
889 }
890
891 #else // BC_ENABLE_EXTRA_MATH
892
893 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
894         &&lbl_BC_INST_NEG,                                                   \
895         &&lbl_BC_INST_BOOL_NOT,                                              \
896         &&lbl_BC_INST_POWER,                                                 \
897         &&lbl_BC_INST_MULTIPLY,                                              \
898         &&lbl_BC_INST_DIVIDE,                                                \
899         &&lbl_BC_INST_MODULUS,                                               \
900         &&lbl_BC_INST_PLUS,                                                  \
901         &&lbl_BC_INST_MINUS,                                                 \
902         &&lbl_BC_INST_REL_EQ,                                                \
903         &&lbl_BC_INST_REL_LE,                                                \
904         &&lbl_BC_INST_REL_GE,                                                \
905         &&lbl_BC_INST_REL_NE,                                                \
906         &&lbl_BC_INST_REL_LT,                                                \
907         &&lbl_BC_INST_REL_GT,                                                \
908         &&lbl_BC_INST_BOOL_OR,                                               \
909         &&lbl_BC_INST_BOOL_AND,                                              \
910         &&lbl_BC_INST_ASSIGN_NO_VAL,                                         \
911         &&lbl_BC_INST_NUM,                                                   \
912         &&lbl_BC_INST_VAR,                                                   \
913         &&lbl_BC_INST_ARRAY_ELEM,                                            \
914         &&lbl_BC_INST_ARRAY,                                                 \
915         &&lbl_BC_INST_ZERO,                                                  \
916         &&lbl_BC_INST_ONE,                                                   \
917         &&lbl_BC_INST_IBASE,                                                 \
918         &&lbl_BC_INST_OBASE,                                                 \
919         &&lbl_BC_INST_SCALE,                                                 \
920         &&lbl_BC_INST_LENGTH,                                                \
921         &&lbl_BC_INST_SCALE_FUNC,                                            \
922         &&lbl_BC_INST_SQRT,                                                  \
923         &&lbl_BC_INST_ABS,                                                   \
924         &&lbl_BC_INST_ASCIIFY,                                               \
925         &&lbl_BC_INST_READ,                                                  \
926         &&lbl_BC_INST_MAXIBASE,                                              \
927         &&lbl_BC_INST_MAXOBASE,                                              \
928         &&lbl_BC_INST_MAXSCALE,                                              \
929         &&lbl_BC_INST_LINE_LENGTH,                                           \
930         &&lbl_BC_INST_LEADING_ZERO,                                          \
931         &&lbl_BC_INST_PRINT,                                                 \
932         &&lbl_BC_INST_PRINT_POP,                                             \
933         &&lbl_BC_INST_STR,                                                   \
934         &&lbl_BC_INST_POP,                                                   \
935         &&lbl_BC_INST_SWAP,                                                  \
936         &&lbl_BC_INST_MODEXP,                                                \
937         &&lbl_BC_INST_DIVMOD,                                                \
938         &&lbl_BC_INST_PRINT_STREAM,                                          \
939         &&lbl_BC_INST_POP_EXEC,                                              \
940         &&lbl_BC_INST_EXECUTE,                                               \
941         &&lbl_BC_INST_EXEC_COND,                                             \
942         &&lbl_BC_INST_PRINT_STACK,                                           \
943         &&lbl_BC_INST_CLEAR_STACK,                                           \
944         &&lbl_BC_INST_REG_STACK_LEN,                                         \
945         &&lbl_BC_INST_STACK_LEN,                                             \
946         &&lbl_BC_INST_DUPLICATE,                                             \
947         &&lbl_BC_INST_LOAD,                                                  \
948         &&lbl_BC_INST_PUSH_VAR,                                              \
949         &&lbl_BC_INST_PUSH_TO_VAR,                                           \
950         &&lbl_BC_INST_QUIT,                                                  \
951         &&lbl_BC_INST_NQUIT,                                                 \
952         &&lbl_BC_INST_EXEC_STACK_LEN,                                        \
953         &&lbl_BC_INST_INVALID,                                               \
954 }
955
956 #endif // BC_ENABLE_EXTRA_MATH
957
958 #endif // BC_ENABLED
959
960 #else // BC_HAS_COMPUTED_GOTO
961
962 #define BC_PROG_JUMP(inst, code, ip) break
963 #define BC_PROG_DIRECT_JUMP(l)
964 #define BC_PROG_LBL(l) case l
965 #define BC_PROG_FALLTHROUGH BC_FALLTHROUGH
966
967 #define BC_PROG_LBLS
968
969 #endif // BC_HAS_COMPUTED_GOTO
970
971 #endif // BC_PROGRAM_H