xref: /src/contrib/bc/include/program.h (revision fdc4a7c8012b214986cfa2e2fb6d99731f004b1b)
11f958cfaSStefan Eßer /*
21f958cfaSStefan Eßer  * *****************************************************************************
31f958cfaSStefan Eßer  *
43960d892SStefan Eßer  * SPDX-License-Identifier: BSD-2-Clause
51f958cfaSStefan Eßer  *
6682da5a0SStefan Eßer  * Copyright (c) 2018-2025 Gavin D. Howard and contributors.
71f958cfaSStefan Eßer  *
81f958cfaSStefan Eßer  * Redistribution and use in source and binary forms, with or without
91f958cfaSStefan Eßer  * modification, are permitted provided that the following conditions are met:
101f958cfaSStefan Eßer  *
111f958cfaSStefan Eßer  * * Redistributions of source code must retain the above copyright notice, this
121f958cfaSStefan Eßer  *   list of conditions and the following disclaimer.
131f958cfaSStefan Eßer  *
141f958cfaSStefan Eßer  * * Redistributions in binary form must reproduce the above copyright notice,
151f958cfaSStefan Eßer  *   this list of conditions and the following disclaimer in the documentation
161f958cfaSStefan Eßer  *   and/or other materials provided with the distribution.
171f958cfaSStefan Eßer  *
181f958cfaSStefan Eßer  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
191f958cfaSStefan Eßer  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
201f958cfaSStefan Eßer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
211f958cfaSStefan Eßer  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
221f958cfaSStefan Eßer  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
231f958cfaSStefan Eßer  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
241f958cfaSStefan Eßer  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
251f958cfaSStefan Eßer  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
261f958cfaSStefan Eßer  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
271f958cfaSStefan Eßer  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
281f958cfaSStefan Eßer  * POSSIBILITY OF SUCH DAMAGE.
291f958cfaSStefan Eßer  *
301f958cfaSStefan Eßer  * *****************************************************************************
311f958cfaSStefan Eßer  *
321f958cfaSStefan Eßer  * Definitions for bc programs.
331f958cfaSStefan Eßer  *
341f958cfaSStefan Eßer  */
351f958cfaSStefan Eßer 
361f958cfaSStefan Eßer #ifndef BC_PROGRAM_H
371f958cfaSStefan Eßer #define BC_PROGRAM_H
381f958cfaSStefan Eßer 
392f57ecaeSStefan Eßer #include <assert.h>
401f958cfaSStefan Eßer #include <stddef.h>
411f958cfaSStefan Eßer 
421f958cfaSStefan Eßer #include <status.h>
431f958cfaSStefan Eßer #include <parse.h>
441f958cfaSStefan Eßer #include <lang.h>
451f958cfaSStefan Eßer #include <num.h>
461f958cfaSStefan Eßer #include <rand.h>
471f958cfaSStefan Eßer 
482f57ecaeSStefan Eßer /// The index of ibase in the globals array.
491f958cfaSStefan Eßer #define BC_PROG_GLOBALS_IBASE (0)
502f57ecaeSStefan Eßer 
512f57ecaeSStefan Eßer /// The index of obase in the globals array.
521f958cfaSStefan Eßer #define BC_PROG_GLOBALS_OBASE (1)
532f57ecaeSStefan Eßer 
542f57ecaeSStefan Eßer /// The index of scale in the globals array.
551f958cfaSStefan Eßer #define BC_PROG_GLOBALS_SCALE (2)
561f958cfaSStefan Eßer 
571f958cfaSStefan Eßer #if BC_ENABLE_EXTRA_MATH
582f57ecaeSStefan Eßer 
592f57ecaeSStefan Eßer /// The index of the rand max in the maxes array.
601f958cfaSStefan Eßer #define BC_PROG_MAX_RAND (3)
612f57ecaeSStefan Eßer 
621f958cfaSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
631f958cfaSStefan Eßer 
642f57ecaeSStefan Eßer /// The length of the globals array.
651f958cfaSStefan Eßer #define BC_PROG_GLOBALS_LEN (3 + BC_ENABLE_EXTRA_MATH)
661f958cfaSStefan Eßer 
675bdd6265SStefan Eßer typedef struct BcProgram
685bdd6265SStefan Eßer {
692f57ecaeSStefan Eßer 	/// The array of globals values.
701f958cfaSStefan Eßer 	BcBigDig globals[BC_PROG_GLOBALS_LEN];
712f57ecaeSStefan Eßer 
72161a37ccSStefan Eßer #if BC_ENABLED
732f57ecaeSStefan Eßer 	/// The array of globals stacks.
741f958cfaSStefan Eßer 	BcVec globals_v[BC_PROG_GLOBALS_LEN];
75161a37ccSStefan Eßer #endif // BC_ENABLED
761f958cfaSStefan Eßer 
772f57ecaeSStefan Eßer #if BC_ENABLE_EXTRA_MATH
781f958cfaSStefan Eßer 
792f57ecaeSStefan Eßer 	/// The pseudo-random number generator.
802f57ecaeSStefan Eßer 	BcRNG rng;
812f57ecaeSStefan Eßer 
822f57ecaeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
832f57ecaeSStefan Eßer 
842f57ecaeSStefan Eßer 	/// The results stack.
851f958cfaSStefan Eßer 	BcVec results;
862f57ecaeSStefan Eßer 
872f57ecaeSStefan Eßer 	/// The execution stack.
881f958cfaSStefan Eßer 	BcVec stack;
891f958cfaSStefan Eßer 
900b671e8cSStefan Eßer 	/// The constants encountered in the program. They are global to the program
910b671e8cSStefan Eßer 	/// to prevent bad accesses when functions that used non-auto variables are
920b671e8cSStefan Eßer 	/// replaced.
930b671e8cSStefan Eßer 	BcVec consts;
942f57ecaeSStefan Eßer 
950b671e8cSStefan Eßer 	/// The map of constants to go with consts.
960b671e8cSStefan Eßer 	BcVec const_map;
970b671e8cSStefan Eßer 
980b671e8cSStefan Eßer 	/// The strings encountered in the program. They are global to the program
990b671e8cSStefan Eßer 	/// to prevent bad accesses when functions that used non-auto variables are
1000b671e8cSStefan Eßer 	/// replaced.
1010b671e8cSStefan Eßer 	BcVec strs;
1020b671e8cSStefan Eßer 
1030b671e8cSStefan Eßer 	/// The map of strings to go with strs.
1040b671e8cSStefan Eßer 	BcVec str_map;
1051f958cfaSStefan Eßer 
1062f57ecaeSStefan Eßer 	/// The array of functions.
1071f958cfaSStefan Eßer 	BcVec fns;
1082f57ecaeSStefan Eßer 
1092f57ecaeSStefan Eßer 	/// The map of functions to go with fns.
1101f958cfaSStefan Eßer 	BcVec fn_map;
1111f958cfaSStefan Eßer 
1122f57ecaeSStefan Eßer 	/// The array of variables.
1131f958cfaSStefan Eßer 	BcVec vars;
1142f57ecaeSStefan Eßer 
1152f57ecaeSStefan Eßer 	/// The map of variables to go with vars.
1161f958cfaSStefan Eßer 	BcVec var_map;
1171f958cfaSStefan Eßer 
1182f57ecaeSStefan Eßer 	/// The array of arrays.
1191f958cfaSStefan Eßer 	BcVec arrs;
1202f57ecaeSStefan Eßer 
1212f57ecaeSStefan Eßer 	/// The map of arrays to go with arrs.
1221f958cfaSStefan Eßer 	BcVec arr_map;
1231f958cfaSStefan Eßer 
1241f958cfaSStefan Eßer #if DC_ENABLED
1253960d892SStefan Eßer 
1262f57ecaeSStefan Eßer 	/// A vector of tail calls. These are just integers, which are the number of
1272f57ecaeSStefan Eßer 	/// tail calls that have been executed for each function (string) on the
1282f57ecaeSStefan Eßer 	/// stack for dc. This is to prevent dc from constantly growing memory use
1292f57ecaeSStefan Eßer 	/// because of pushing more and more string executions on the stack.
1301f958cfaSStefan Eßer 	BcVec tail_calls;
1311f958cfaSStefan Eßer 
1321f958cfaSStefan Eßer #endif // DC_ENABLED
1331f958cfaSStefan Eßer 
1342f57ecaeSStefan Eßer 	/// A BcNum that has the proper base for asciify.
1352f57ecaeSStefan Eßer 	BcNum strmb;
1361f958cfaSStefan Eßer 
137161a37ccSStefan Eßer 	// A BcNum to run asciify. This is to prevent GCC longjmp() clobbering
138161a37ccSStefan Eßer 	// warnings.
139161a37ccSStefan Eßer 	BcNum asciify;
140161a37ccSStefan Eßer 
1411f958cfaSStefan Eßer #if BC_ENABLED
1422f57ecaeSStefan Eßer 
1432f57ecaeSStefan Eßer 	/// The last printed value for bc.
1441f958cfaSStefan Eßer 	BcNum last;
1452f57ecaeSStefan Eßer 
1461f958cfaSStefan Eßer #endif // BC_ENABLED
1471f958cfaSStefan Eßer 
148682da5a0SStefan Eßer 	/// The number of results that have not been retired.
149682da5a0SStefan Eßer 	size_t nresults;
150682da5a0SStefan Eßer 
1512f57ecaeSStefan Eßer 	// The BcDig array for strmb. This uses BC_NUM_LONG_LOG10 because it is used
1522f57ecaeSStefan Eßer 	// in bc_num_ulong2num(), which attempts to realloc, unless it is big
1532f57ecaeSStefan Eßer 	// enough. This is big enough.
1541f958cfaSStefan Eßer 	BcDig strmb_num[BC_NUM_BIGDIG_LOG10];
1551f958cfaSStefan Eßer 
1561f958cfaSStefan Eßer } BcProgram;
1571f958cfaSStefan Eßer 
1582f57ecaeSStefan Eßer /**
1592f57ecaeSStefan Eßer  * Returns true if the stack @a s has at least @a n items, false otherwise.
1602f57ecaeSStefan Eßer  * @param s  The stack to check.
1612f57ecaeSStefan Eßer  * @param n  The number of items the stack must have.
1622f57ecaeSStefan Eßer  * @return   True if @a s has at least @a n items, false otherwise.
1632f57ecaeSStefan Eßer  */
1641f958cfaSStefan Eßer #define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) (n)))
1651f958cfaSStefan Eßer 
1662f57ecaeSStefan Eßer /**
1672f57ecaeSStefan Eßer  * Get a pointer to the top value in a global value stack.
1682f57ecaeSStefan Eßer  * @param v  The global value stack.
1692f57ecaeSStefan Eßer  * @return   A pointer to the top value in @a v.
1702f57ecaeSStefan Eßer  */
1711f958cfaSStefan Eßer #define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v))
1722f57ecaeSStefan Eßer 
1732f57ecaeSStefan Eßer /**
1742f57ecaeSStefan Eßer  * Get the top value in a global value stack.
1752f57ecaeSStefan Eßer  * @param v  The global value stack.
1762f57ecaeSStefan Eßer  * @return   The top value in @a v.
1772f57ecaeSStefan Eßer  */
1781f958cfaSStefan Eßer #define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v)))
1791f958cfaSStefan Eßer 
1802f57ecaeSStefan Eßer /**
1812f57ecaeSStefan Eßer  * Returns the current value of ibase.
1822f57ecaeSStefan Eßer  * @param p  The program.
1832f57ecaeSStefan Eßer  * @return   The current ibase.
1842f57ecaeSStefan Eßer  */
1851f958cfaSStefan Eßer #define BC_PROG_IBASE(p) ((p)->globals[BC_PROG_GLOBALS_IBASE])
1862f57ecaeSStefan Eßer 
1872f57ecaeSStefan Eßer /**
1882f57ecaeSStefan Eßer  * Returns the current value of obase.
1892f57ecaeSStefan Eßer  * @param p  The program.
1902f57ecaeSStefan Eßer  * @return   The current obase.
1912f57ecaeSStefan Eßer  */
1921f958cfaSStefan Eßer #define BC_PROG_OBASE(p) ((p)->globals[BC_PROG_GLOBALS_OBASE])
1932f57ecaeSStefan Eßer 
1942f57ecaeSStefan Eßer /**
1952f57ecaeSStefan Eßer  * Returns the current value of scale.
1962f57ecaeSStefan Eßer  * @param p  The program.
1972f57ecaeSStefan Eßer  * @return   The current scale.
1982f57ecaeSStefan Eßer  */
1991f958cfaSStefan Eßer #define BC_PROG_SCALE(p) ((p)->globals[BC_PROG_GLOBALS_SCALE])
2001f958cfaSStefan Eßer 
2012f57ecaeSStefan Eßer /// The index for the main function in the functions array.//
2021f958cfaSStefan Eßer #define BC_PROG_MAIN (0)
2032f57ecaeSStefan Eßer 
2042f57ecaeSStefan Eßer /// The index for the read function in the functions array.
2051f958cfaSStefan Eßer #define BC_PROG_READ (1)
2061f958cfaSStefan Eßer 
2072f57ecaeSStefan Eßer /**
2082f57ecaeSStefan Eßer  * Retires (completes the execution of) an instruction. Some instructions
2092f57ecaeSStefan Eßer  * require special retirement, but most can use this. This basically pops the
2102f57ecaeSStefan Eßer  * operands while preserving the result (which we assumed was pushed before the
2112f57ecaeSStefan Eßer  * actual operation).
2122f57ecaeSStefan Eßer  * @param p     The program.
2132f57ecaeSStefan Eßer  * @param nops  The number of operands used by the instruction.
2142f57ecaeSStefan Eßer  */
215682da5a0SStefan Eßer #define bc_program_retire(p, nops)                                \
216682da5a0SStefan Eßer 	do                                                            \
217682da5a0SStefan Eßer 	{                                                             \
218682da5a0SStefan Eßer 		bc_vec_npopAt(&(p)->results, (nops),                      \
219682da5a0SStefan Eßer 		              (p)->results.len - ((p)->nresults + nops)); \
220682da5a0SStefan Eßer 		p->nresults = 0;                                          \
221682da5a0SStefan Eßer 	}                                                             \
222682da5a0SStefan Eßer 	while (0)
2231f958cfaSStefan Eßer 
2241f958cfaSStefan Eßer #if DC_ENABLED
2252f57ecaeSStefan Eßer 
2262f57ecaeSStefan Eßer /// A constant that tells how many functions are required in dc.
2271f958cfaSStefan Eßer #define BC_PROG_REQ_FUNCS (2)
2282f57ecaeSStefan Eßer 
2291f958cfaSStefan Eßer #if !BC_ENABLED
2302f57ecaeSStefan Eßer 
231161a37ccSStefan Eßer /// Returns true if the calculator should pop after printing.
232161a37ccSStefan Eßer #define BC_PROGRAM_POP(pop) (pop)
233161a37ccSStefan Eßer 
234161a37ccSStefan Eßer #else // !BC_ENABLED
235161a37ccSStefan Eßer 
236161a37ccSStefan Eßer /// Returns true if the calculator should pop after printing.
237161a37ccSStefan Eßer #define BC_PROGRAM_POP(pop) (BC_IS_BC || (pop))
2382f57ecaeSStefan Eßer 
2391f958cfaSStefan Eßer #endif // !BC_ENABLED
2402f57ecaeSStefan Eßer 
241161a37ccSStefan Eßer // This is here to satisfy a clang warning about recursive macros.
242161a37ccSStefan Eßer #define bc_program_pushVar(p, code, bgn, pop, copy) \
243161a37ccSStefan Eßer 	bc_program_pushVar_impl(p, code, bgn, pop, copy)
244161a37ccSStefan Eßer 
2451f958cfaSStefan Eßer #else // DC_ENABLED
2462f57ecaeSStefan Eßer 
247161a37ccSStefan Eßer // This define disappears pop and copy because for bc, 'pop' and 'copy' are
248161a37ccSStefan Eßer // always false.
2491f958cfaSStefan Eßer #define bc_program_pushVar(p, code, bgn, pop, copy) \
250161a37ccSStefan Eßer 	bc_program_pushVar_impl(p, code, bgn)
251161a37ccSStefan Eßer 
252161a37ccSStefan Eßer /// Returns true if the calculator should pop after printing.
253161a37ccSStefan Eßer #define BC_PROGRAM_POP(pop) (BC_IS_BC)
2542f57ecaeSStefan Eßer 
2552f57ecaeSStefan Eßer // In debug mode, we want bc to check the stack, but otherwise, we don't because
2562f57ecaeSStefan Eßer // the bc language implicitly mandates that the stack should always have enough
2572f57ecaeSStefan Eßer // items.
25861e1a12bSStefan Eßer #ifdef BC_DEBUG
2591f958cfaSStefan Eßer #define BC_PROG_NO_STACK_CHECK
26061e1a12bSStefan Eßer #endif // BC_DEBUG
2612f57ecaeSStefan Eßer 
2621f958cfaSStefan Eßer #endif // DC_ENABLED
2631f958cfaSStefan Eßer 
2642f57ecaeSStefan Eßer /**
2652f57ecaeSStefan Eßer  * Returns true if the BcNum @a n is acting as a string.
2662f57ecaeSStefan Eßer  * @param n  The BcNum to test.
2672f57ecaeSStefan Eßer  * @return   True if @a n is acting as a string, false otherwise.
2682f57ecaeSStefan Eßer  */
2691f958cfaSStefan Eßer #define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap)
2702f57ecaeSStefan Eßer 
2711f958cfaSStefan Eßer #if BC_ENABLED
2722f57ecaeSStefan Eßer 
2732f57ecaeSStefan Eßer /**
2742f57ecaeSStefan Eßer  * Returns true if the result @a r and @a n is a number.
2752f57ecaeSStefan Eßer  * @param r  The result.
2762f57ecaeSStefan Eßer  * @param n  The number corresponding to the result.
2772f57ecaeSStefan Eßer  * @return   True if the result holds a number, false otherwise.
2782f57ecaeSStefan Eßer  */
2791f958cfaSStefan Eßer #define BC_PROG_NUM(r, n) \
2801f958cfaSStefan Eßer 	((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
2812f57ecaeSStefan Eßer 
2821f958cfaSStefan Eßer #else // BC_ENABLED
2832f57ecaeSStefan Eßer 
2842f57ecaeSStefan Eßer /**
2852f57ecaeSStefan Eßer  * Returns true if the result @a r and @a n is a number.
2862f57ecaeSStefan Eßer  * @param r  The result.
2872f57ecaeSStefan Eßer  * @param n  The number corresponding to the result.
2882f57ecaeSStefan Eßer  * @return   True if the result holds a number, false otherwise.
2892f57ecaeSStefan Eßer  */
2901f958cfaSStefan Eßer #define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
2912f57ecaeSStefan Eßer 
2921f958cfaSStefan Eßer #endif // BC_ENABLED
2931f958cfaSStefan Eßer 
2942f57ecaeSStefan Eßer /**
2952f57ecaeSStefan Eßer  * This is a function type for unary operations. Currently, these include
2962f57ecaeSStefan Eßer  * boolean not, negation, and truncation with extra math.
2972f57ecaeSStefan Eßer  * @param r  The BcResult to store the result into.
2982f57ecaeSStefan Eßer  * @param n  The parameter to the unary operation.
2992f57ecaeSStefan Eßer  */
3002f57ecaeSStefan Eßer typedef void (*BcProgramUnary)(BcResult* r, BcNum* n);
3011f958cfaSStefan Eßer 
3022f57ecaeSStefan Eßer /**
3032f57ecaeSStefan Eßer  * Initializes the BcProgram.
3042f57ecaeSStefan Eßer  * @param p  The program to initialize.
3052f57ecaeSStefan Eßer  */
3065bdd6265SStefan Eßer void
3075bdd6265SStefan Eßer bc_program_init(BcProgram* p);
3082f57ecaeSStefan Eßer 
30961e1a12bSStefan Eßer #if BC_DEBUG
3102f57ecaeSStefan Eßer 
3112f57ecaeSStefan Eßer /**
3122f57ecaeSStefan Eßer  * Frees a BcProgram. This is only used in debug builds because a BcProgram is
3132f57ecaeSStefan Eßer  * only freed on program exit, and we don't care about freeing resources on
3142f57ecaeSStefan Eßer  * exit.
3152f57ecaeSStefan Eßer  * @param p  The program to initialize.
3162f57ecaeSStefan Eßer  */
3175bdd6265SStefan Eßer void
3185bdd6265SStefan Eßer bc_program_free(BcProgram* p);
3191f958cfaSStefan Eßer 
32061e1a12bSStefan Eßer #endif // BC_DEBUG
3212f57ecaeSStefan Eßer 
322e7017237SStefan Eßer /**
323e7017237SStefan Eßer  * Prints a stack trace of the bc functions or dc strings currently executing.
324e7017237SStefan Eßer  * @param p  The program.
325e7017237SStefan Eßer  */
326e7017237SStefan Eßer void
327e7017237SStefan Eßer bc_program_printStackTrace(BcProgram* p);
328e7017237SStefan Eßer 
3291f958cfaSStefan Eßer #if BC_DEBUG_CODE
3301f958cfaSStefan Eßer #if BC_ENABLED && DC_ENABLED
3312f57ecaeSStefan Eßer 
3322f57ecaeSStefan Eßer /**
3332f57ecaeSStefan Eßer  * Prints the bytecode in a function. This is a debug-only function.
3342f57ecaeSStefan Eßer  * @param p  The program.
3352f57ecaeSStefan Eßer  */
3365bdd6265SStefan Eßer void
3375bdd6265SStefan Eßer bc_program_code(const BcProgram* p);
3382f57ecaeSStefan Eßer 
3392f57ecaeSStefan Eßer /**
3402f57ecaeSStefan Eßer  * Prints an instruction. This is a debug-only function.
3412f57ecaeSStefan Eßer  * @param p  The program.
3422f57ecaeSStefan Eßer  * @param code  The bytecode array.
3432f57ecaeSStefan Eßer  * @param bgn   A pointer to the current index. It is also updated to the next
3442f57ecaeSStefan Eßer  *              index.
3452f57ecaeSStefan Eßer  */
3465bdd6265SStefan Eßer void
3475bdd6265SStefan Eßer bc_program_printInst(const BcProgram* p, const char* code,
3481f958cfaSStefan Eßer                      size_t* restrict bgn);
3492f57ecaeSStefan Eßer 
3502f57ecaeSStefan Eßer /**
3512f57ecaeSStefan Eßer  * Prints the stack. This is a debug-only function.
3522f57ecaeSStefan Eßer  * @param p  The program.
3532f57ecaeSStefan Eßer  */
3545bdd6265SStefan Eßer void
3555bdd6265SStefan Eßer bc_program_printStackDebug(BcProgram* p);
3562f57ecaeSStefan Eßer 
3571f958cfaSStefan Eßer #endif // BC_ENABLED && DC_ENABLED
3581f958cfaSStefan Eßer #endif // BC_DEBUG_CODE
3591f958cfaSStefan Eßer 
3602f57ecaeSStefan Eßer /**
3612f57ecaeSStefan Eßer  * Returns the index of the variable or array in their respective arrays.
3622f57ecaeSStefan Eßer  * @param p     The program.
3630b671e8cSStefan Eßer  * @param name  The name of the variable or array.
3642f57ecaeSStefan Eßer  * @param var   True if the search should be for a variable, false for an array.
3652f57ecaeSStefan Eßer  * @return      The index of the variable or array in the correct array.
3662f57ecaeSStefan Eßer  */
3675bdd6265SStefan Eßer size_t
3680b671e8cSStefan Eßer bc_program_search(BcProgram* p, const char* name, bool var);
3692f57ecaeSStefan Eßer 
3702f57ecaeSStefan Eßer /**
3710b671e8cSStefan Eßer  * Adds a string to the program and returns the string's index in the program.
3722f57ecaeSStefan Eßer  * @param p    The program.
3732f57ecaeSStefan Eßer  * @param str  The string to add.
3740b671e8cSStefan Eßer  * @return     The string's index in the program.
3752f57ecaeSStefan Eßer  */
3765bdd6265SStefan Eßer size_t
3770b671e8cSStefan Eßer bc_program_addString(BcProgram* p, const char* str);
3782f57ecaeSStefan Eßer 
3792f57ecaeSStefan Eßer /**
3802f57ecaeSStefan Eßer  * Inserts a function into the program and returns the index of the function in
3812f57ecaeSStefan Eßer  * the fns array.
3822f57ecaeSStefan Eßer  * @param p     The program.
3832f57ecaeSStefan Eßer  * @param name  The name of the function.
3842f57ecaeSStefan Eßer  * @return      The index of the function after insertion.
3852f57ecaeSStefan Eßer  */
3865bdd6265SStefan Eßer size_t
3875bdd6265SStefan Eßer bc_program_insertFunc(BcProgram* p, const char* name);
3882f57ecaeSStefan Eßer 
3892f57ecaeSStefan Eßer /**
3902f57ecaeSStefan Eßer  * Resets a program, usually because of resetting after an error.
3912f57ecaeSStefan Eßer  * @param p  The program to reset.
3922f57ecaeSStefan Eßer  */
3935bdd6265SStefan Eßer void
3945bdd6265SStefan Eßer bc_program_reset(BcProgram* p);
3952f57ecaeSStefan Eßer 
3962f57ecaeSStefan Eßer /**
3972f57ecaeSStefan Eßer  * Executes bc or dc code in the BcProgram.
3982f57ecaeSStefan Eßer  * @param p  The program.
3992f57ecaeSStefan Eßer  */
4005bdd6265SStefan Eßer void
4015bdd6265SStefan Eßer bc_program_exec(BcProgram* p);
4021f958cfaSStefan Eßer 
4032f57ecaeSStefan Eßer /**
4042f57ecaeSStefan Eßer  * Negates a copy of a BcNum. This is a BcProgramUnary function.
4052f57ecaeSStefan Eßer  * @param r  The BcResult to store the result into.
4062f57ecaeSStefan Eßer  * @param n  The parameter to the unary operation.
4072f57ecaeSStefan Eßer  */
4085bdd6265SStefan Eßer void
4095bdd6265SStefan Eßer bc_program_negate(BcResult* r, BcNum* n);
4102f57ecaeSStefan Eßer 
4112f57ecaeSStefan Eßer /**
4122f57ecaeSStefan Eßer  * Returns a boolean not of a BcNum. This is a BcProgramUnary function.
4132f57ecaeSStefan Eßer  * @param r  The BcResult to store the result into.
4142f57ecaeSStefan Eßer  * @param n  The parameter to the unary operation.
4152f57ecaeSStefan Eßer  */
4165bdd6265SStefan Eßer void
4175bdd6265SStefan Eßer bc_program_not(BcResult* r, BcNum* n);
4182f57ecaeSStefan Eßer 
4191f958cfaSStefan Eßer #if BC_ENABLE_EXTRA_MATH
4202f57ecaeSStefan Eßer 
4212f57ecaeSStefan Eßer /**
4222f57ecaeSStefan Eßer  * Truncates a copy of a BcNum. This is a BcProgramUnary function.
4232f57ecaeSStefan Eßer  * @param r  The BcResult to store the result into.
4242f57ecaeSStefan Eßer  * @param n  The parameter to the unary operation.
4252f57ecaeSStefan Eßer  */
4265bdd6265SStefan Eßer void
4275bdd6265SStefan Eßer bc_program_trunc(BcResult* r, BcNum* n);
4285bdd6265SStefan Eßer 
4295bdd6265SStefan Eßer /**
4305bdd6265SStefan Eßer  * Assigns a value to the seed builtin variable.
4315bdd6265SStefan Eßer  * @param p    The program.
4325bdd6265SStefan Eßer  * @param val  The value to assign to the seed.
4335bdd6265SStefan Eßer  */
4345bdd6265SStefan Eßer void
4355bdd6265SStefan Eßer bc_program_assignSeed(BcProgram* p, BcNum* val);
4362f57ecaeSStefan Eßer 
4371f958cfaSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
4381f958cfaSStefan Eßer 
4395bdd6265SStefan Eßer /**
4405bdd6265SStefan Eßer  * Assigns a value to a builtin value that is not seed.
4415bdd6265SStefan Eßer  * @param p      The program.
4425bdd6265SStefan Eßer  * @param scale  True if the builtin is scale.
4435bdd6265SStefan Eßer  * @param obase  True if the builtin is obase. This cannot be true at the same
4445bdd6265SStefan Eßer  *               time @a scale is.
4455bdd6265SStefan Eßer  * @param val    The value to assign to the builtin.
4465bdd6265SStefan Eßer  */
4475bdd6265SStefan Eßer void
4485bdd6265SStefan Eßer bc_program_assignBuiltin(BcProgram* p, bool scale, bool obase, BcBigDig val);
4495bdd6265SStefan Eßer 
4502f57ecaeSStefan Eßer /// A reference to an array of binary operator functions.
4511f958cfaSStefan Eßer extern const BcNumBinaryOp bc_program_ops[];
4522f57ecaeSStefan Eßer 
4532f57ecaeSStefan Eßer /// A reference to an array of binary operator allocation request functions.
4541f958cfaSStefan Eßer extern const BcNumBinaryOpReq bc_program_opReqs[];
4552f57ecaeSStefan Eßer 
4562f57ecaeSStefan Eßer /// A reference to an array of unary operator functions.
4571f958cfaSStefan Eßer extern const BcProgramUnary bc_program_unarys[];
4582f57ecaeSStefan Eßer 
4592f57ecaeSStefan Eßer /// A reference to a filename for command-line expressions.
4601f958cfaSStefan Eßer extern const char bc_program_exprs_name[];
4612f57ecaeSStefan Eßer 
4622f57ecaeSStefan Eßer /// A reference to a filename for stdin.
4631f958cfaSStefan Eßer extern const char bc_program_stdin_name[];
4642f57ecaeSStefan Eßer 
4652f57ecaeSStefan Eßer /// A reference to the ready message printed on SIGINT.
4661f958cfaSStefan Eßer extern const char bc_program_ready_msg[];
4672f57ecaeSStefan Eßer 
4682f57ecaeSStefan Eßer /// A reference to the length of the ready message.
4691f958cfaSStefan Eßer extern const size_t bc_program_ready_msg_len;
4702f57ecaeSStefan Eßer 
4712f57ecaeSStefan Eßer /// A reference to an array of escape characters for the print statement.
4721f958cfaSStefan Eßer extern const char bc_program_esc_chars[];
4732f57ecaeSStefan Eßer 
4742f57ecaeSStefan Eßer /// A reference to an array of the characters corresponding to the escape
4752f57ecaeSStefan Eßer /// characters in bc_program_esc_chars.
4761f958cfaSStefan Eßer extern const char bc_program_esc_seqs[];
4771f958cfaSStefan Eßer 
4782f57ecaeSStefan Eßer #if BC_HAS_COMPUTED_GOTO
4792f57ecaeSStefan Eßer 
4802f57ecaeSStefan Eßer #if BC_DEBUG_CODE
4812f57ecaeSStefan Eßer 
4825bdd6265SStefan Eßer // clang-format off
4832f57ecaeSStefan Eßer #define BC_PROG_JUMP(inst, code, ip)                                  \
4845bdd6265SStefan Eßer 	do                                                                \
4855bdd6265SStefan Eßer 	{                                                                 \
4862f57ecaeSStefan Eßer 		inst = (uchar) (code)[(ip)->idx++];                           \
487161a37ccSStefan Eßer 		bc_file_printf(&vm->ferr, "inst: %s\n", bc_inst_names[inst]); \
488161a37ccSStefan Eßer 		bc_file_flush(&vm->ferr, bc_flush_none);                      \
4892f57ecaeSStefan Eßer 		goto *bc_program_inst_lbls[inst];                             \
4905bdd6265SStefan Eßer 	}                                                                 \
4915bdd6265SStefan Eßer 	while (0)
4925bdd6265SStefan Eßer // clang-format on
4932f57ecaeSStefan Eßer 
4942f57ecaeSStefan Eßer #else // BC_DEBUG_CODE
4952f57ecaeSStefan Eßer 
4965bdd6265SStefan Eßer // clang-format off
4972f57ecaeSStefan Eßer #define BC_PROG_JUMP(inst, code, ip)        \
4985bdd6265SStefan Eßer 	do                                      \
4995bdd6265SStefan Eßer 	{                                       \
5002f57ecaeSStefan Eßer 		inst = (uchar) (code)[(ip)->idx++]; \
5012f57ecaeSStefan Eßer 		goto *bc_program_inst_lbls[inst];   \
5025bdd6265SStefan Eßer 	}                                       \
5035bdd6265SStefan Eßer 	while (0)
5045bdd6265SStefan Eßer // clang-format on
5052f57ecaeSStefan Eßer 
5062f57ecaeSStefan Eßer #endif // BC_DEBUG_CODE
5072f57ecaeSStefan Eßer 
5082f57ecaeSStefan Eßer #define BC_PROG_DIRECT_JUMP(l) goto lbl_##l;
5092f57ecaeSStefan Eßer #define BC_PROG_LBL(l) lbl_##l
5102f57ecaeSStefan Eßer #define BC_PROG_FALLTHROUGH
5112f57ecaeSStefan Eßer 
5122f57ecaeSStefan Eßer #if BC_C11
5132f57ecaeSStefan Eßer 
5142f57ecaeSStefan Eßer #define BC_PROG_LBLS_SIZE (sizeof(bc_program_inst_lbls) / sizeof(void*))
5152f57ecaeSStefan Eßer #define BC_PROG_LBLS_ASSERT                                  \
5165bdd6265SStefan Eßer 	_Static_assert(BC_PROG_LBLS_SIZE == BC_INST_INVALID + 1, \
5172f57ecaeSStefan Eßer 	               "bc_program_inst_lbls[] mismatches the instructions")
5182f57ecaeSStefan Eßer 
5192f57ecaeSStefan Eßer #else // BC_C11
5202f57ecaeSStefan Eßer 
5212f57ecaeSStefan Eßer #define BC_PROG_LBLS_ASSERT
5222f57ecaeSStefan Eßer 
5232f57ecaeSStefan Eßer #endif // BC_C11
5242f57ecaeSStefan Eßer 
5252f57ecaeSStefan Eßer #if BC_ENABLED
5262f57ecaeSStefan Eßer 
5272f57ecaeSStefan Eßer #if DC_ENABLED
5282f57ecaeSStefan Eßer 
5292f57ecaeSStefan Eßer #if BC_ENABLE_EXTRA_MATH
5302f57ecaeSStefan Eßer 
5315bdd6265SStefan Eßer #define BC_PROG_LBLS                                    \
5325bdd6265SStefan Eßer 	static const void* const bc_program_inst_lbls[] = { \
5332f57ecaeSStefan Eßer 		&&lbl_BC_INST_INC,                              \
5342f57ecaeSStefan Eßer 		&&lbl_BC_INST_DEC,                              \
5352f57ecaeSStefan Eßer 		&&lbl_BC_INST_NEG,                              \
5362f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_NOT,                         \
5372f57ecaeSStefan Eßer 		&&lbl_BC_INST_TRUNC,                            \
5382f57ecaeSStefan Eßer 		&&lbl_BC_INST_POWER,                            \
5392f57ecaeSStefan Eßer 		&&lbl_BC_INST_MULTIPLY,                         \
5402f57ecaeSStefan Eßer 		&&lbl_BC_INST_DIVIDE,                           \
5412f57ecaeSStefan Eßer 		&&lbl_BC_INST_MODULUS,                          \
5422f57ecaeSStefan Eßer 		&&lbl_BC_INST_PLUS,                             \
5432f57ecaeSStefan Eßer 		&&lbl_BC_INST_MINUS,                            \
5442f57ecaeSStefan Eßer 		&&lbl_BC_INST_PLACES,                           \
5452f57ecaeSStefan Eßer 		&&lbl_BC_INST_LSHIFT,                           \
5462f57ecaeSStefan Eßer 		&&lbl_BC_INST_RSHIFT,                           \
5472f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_EQ,                           \
5482f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_LE,                           \
5492f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_GE,                           \
5502f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_NE,                           \
5512f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_LT,                           \
5522f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_GT,                           \
5532f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_OR,                          \
5542f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_AND,                         \
5552f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER,                     \
5562f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
5572f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE,                    \
5582f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS,                   \
5592f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS,                      \
5602f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS,                     \
5612f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLACES,                    \
5622f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_LSHIFT,                    \
5632f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_RSHIFT,                    \
5642f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN,                           \
5652f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
5662f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
5672f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
5682f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
5692f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
5702f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
5712f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLACES_NO_VAL,             \
5722f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL,             \
5732f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL,             \
5742f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL,                    \
5752f57ecaeSStefan Eßer 		&&lbl_BC_INST_NUM,                              \
5762f57ecaeSStefan Eßer 		&&lbl_BC_INST_VAR,                              \
5772f57ecaeSStefan Eßer 		&&lbl_BC_INST_ARRAY_ELEM,                       \
5782f57ecaeSStefan Eßer 		&&lbl_BC_INST_ARRAY,                            \
5792f57ecaeSStefan Eßer 		&&lbl_BC_INST_ZERO,                             \
5802f57ecaeSStefan Eßer 		&&lbl_BC_INST_ONE,                              \
5812f57ecaeSStefan Eßer 		&&lbl_BC_INST_LAST,                             \
5822f57ecaeSStefan Eßer 		&&lbl_BC_INST_IBASE,                            \
5832f57ecaeSStefan Eßer 		&&lbl_BC_INST_OBASE,                            \
5842f57ecaeSStefan Eßer 		&&lbl_BC_INST_SCALE,                            \
5852f57ecaeSStefan Eßer 		&&lbl_BC_INST_SEED,                             \
5862f57ecaeSStefan Eßer 		&&lbl_BC_INST_LENGTH,                           \
5872f57ecaeSStefan Eßer 		&&lbl_BC_INST_SCALE_FUNC,                       \
5882f57ecaeSStefan Eßer 		&&lbl_BC_INST_SQRT,                             \
5892f57ecaeSStefan Eßer 		&&lbl_BC_INST_ABS,                              \
5900b671e8cSStefan Eßer 		&&lbl_BC_INST_IS_NUMBER,                        \
5910b671e8cSStefan Eßer 		&&lbl_BC_INST_IS_STRING,                        \
5922f57ecaeSStefan Eßer 		&&lbl_BC_INST_IRAND,                            \
5932f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASCIIFY,                          \
5942f57ecaeSStefan Eßer 		&&lbl_BC_INST_READ,                             \
5952f57ecaeSStefan Eßer 		&&lbl_BC_INST_RAND,                             \
5962f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXIBASE,                         \
5972f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXOBASE,                         \
5982f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXSCALE,                         \
5992f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXRAND,                          \
6005d58a515SStefan Eßer 		&&lbl_BC_INST_LINE_LENGTH,                      \
6015d58a515SStefan Eßer 		&&lbl_BC_INST_GLOBAL_STACKS,                    \
6025d58a515SStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,                     \
6032f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT,                            \
6042f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_POP,                        \
6052f57ecaeSStefan Eßer 		&&lbl_BC_INST_STR,                              \
6062f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_STR,                        \
6072f57ecaeSStefan Eßer 		&&lbl_BC_INST_JUMP,                             \
6082f57ecaeSStefan Eßer 		&&lbl_BC_INST_JUMP_ZERO,                        \
6092f57ecaeSStefan Eßer 		&&lbl_BC_INST_CALL,                             \
6102f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET,                              \
6112f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET0,                             \
6122f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET_VOID,                         \
6132f57ecaeSStefan Eßer 		&&lbl_BC_INST_HALT,                             \
6142f57ecaeSStefan Eßer 		&&lbl_BC_INST_POP,                              \
6152f57ecaeSStefan Eßer 		&&lbl_BC_INST_SWAP,                             \
6162f57ecaeSStefan Eßer 		&&lbl_BC_INST_MODEXP,                           \
6172f57ecaeSStefan Eßer 		&&lbl_BC_INST_DIVMOD,                           \
6182f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,                     \
61961e1a12bSStefan Eßer 		&&lbl_BC_INST_EXTENDED_REGISTERS,               \
6202f57ecaeSStefan Eßer 		&&lbl_BC_INST_POP_EXEC,                         \
6212f57ecaeSStefan Eßer 		&&lbl_BC_INST_EXECUTE,                          \
6222f57ecaeSStefan Eßer 		&&lbl_BC_INST_EXEC_COND,                        \
6232f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_STACK,                      \
6242f57ecaeSStefan Eßer 		&&lbl_BC_INST_CLEAR_STACK,                      \
6252f57ecaeSStefan Eßer 		&&lbl_BC_INST_REG_STACK_LEN,                    \
6262f57ecaeSStefan Eßer 		&&lbl_BC_INST_STACK_LEN,                        \
6272f57ecaeSStefan Eßer 		&&lbl_BC_INST_DUPLICATE,                        \
6282f57ecaeSStefan Eßer 		&&lbl_BC_INST_LOAD,                             \
6292f57ecaeSStefan Eßer 		&&lbl_BC_INST_PUSH_VAR,                         \
6302f57ecaeSStefan Eßer 		&&lbl_BC_INST_PUSH_TO_VAR,                      \
6312f57ecaeSStefan Eßer 		&&lbl_BC_INST_QUIT,                             \
6322f57ecaeSStefan Eßer 		&&lbl_BC_INST_NQUIT,                            \
6332f57ecaeSStefan Eßer 		&&lbl_BC_INST_EXEC_STACK_LEN,                   \
6342f57ecaeSStefan Eßer 		&&lbl_BC_INST_INVALID,                          \
6352f57ecaeSStefan Eßer 	}
6362f57ecaeSStefan Eßer 
6372f57ecaeSStefan Eßer #else // BC_ENABLE_EXTRA_MATH
6382f57ecaeSStefan Eßer 
6395bdd6265SStefan Eßer #define BC_PROG_LBLS                                    \
6405bdd6265SStefan Eßer 	static const void* const bc_program_inst_lbls[] = { \
6412f57ecaeSStefan Eßer 		&&lbl_BC_INST_INC,                              \
6422f57ecaeSStefan Eßer 		&&lbl_BC_INST_DEC,                              \
6432f57ecaeSStefan Eßer 		&&lbl_BC_INST_NEG,                              \
6442f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_NOT,                         \
6452f57ecaeSStefan Eßer 		&&lbl_BC_INST_POWER,                            \
6462f57ecaeSStefan Eßer 		&&lbl_BC_INST_MULTIPLY,                         \
6472f57ecaeSStefan Eßer 		&&lbl_BC_INST_DIVIDE,                           \
6482f57ecaeSStefan Eßer 		&&lbl_BC_INST_MODULUS,                          \
6492f57ecaeSStefan Eßer 		&&lbl_BC_INST_PLUS,                             \
6502f57ecaeSStefan Eßer 		&&lbl_BC_INST_MINUS,                            \
6512f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_EQ,                           \
6522f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_LE,                           \
6532f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_GE,                           \
6542f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_NE,                           \
6552f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_LT,                           \
6562f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_GT,                           \
6572f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_OR,                          \
6582f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_AND,                         \
6592f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER,                     \
6602f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
6612f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE,                    \
6622f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS,                   \
6632f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS,                      \
6642f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS,                     \
6652f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN,                           \
6662f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
6672f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
6682f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
6692f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
6702f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
6712f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
6722f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL,                    \
6732f57ecaeSStefan Eßer 		&&lbl_BC_INST_NUM,                              \
6742f57ecaeSStefan Eßer 		&&lbl_BC_INST_VAR,                              \
6752f57ecaeSStefan Eßer 		&&lbl_BC_INST_ARRAY_ELEM,                       \
6762f57ecaeSStefan Eßer 		&&lbl_BC_INST_ARRAY,                            \
6772f57ecaeSStefan Eßer 		&&lbl_BC_INST_ZERO,                             \
6782f57ecaeSStefan Eßer 		&&lbl_BC_INST_ONE,                              \
6792f57ecaeSStefan Eßer 		&&lbl_BC_INST_LAST,                             \
6802f57ecaeSStefan Eßer 		&&lbl_BC_INST_IBASE,                            \
6812f57ecaeSStefan Eßer 		&&lbl_BC_INST_OBASE,                            \
6822f57ecaeSStefan Eßer 		&&lbl_BC_INST_SCALE,                            \
6832f57ecaeSStefan Eßer 		&&lbl_BC_INST_LENGTH,                           \
6842f57ecaeSStefan Eßer 		&&lbl_BC_INST_SCALE_FUNC,                       \
6852f57ecaeSStefan Eßer 		&&lbl_BC_INST_SQRT,                             \
6862f57ecaeSStefan Eßer 		&&lbl_BC_INST_ABS,                              \
6870b671e8cSStefan Eßer 		&&lbl_BC_INST_IS_NUMBER,                        \
6880b671e8cSStefan Eßer 		&&lbl_BC_INST_IS_STRING,                        \
6892f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASCIIFY,                          \
6902f57ecaeSStefan Eßer 		&&lbl_BC_INST_READ,                             \
6912f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXIBASE,                         \
6922f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXOBASE,                         \
6932f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXSCALE,                         \
6945d58a515SStefan Eßer 		&&lbl_BC_INST_LINE_LENGTH,                      \
6955d58a515SStefan Eßer 		&&lbl_BC_INST_GLOBAL_STACKS,                    \
6965d58a515SStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,                     \
6972f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT,                            \
6982f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_POP,                        \
6992f57ecaeSStefan Eßer 		&&lbl_BC_INST_STR,                              \
7002f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_STR,                        \
7012f57ecaeSStefan Eßer 		&&lbl_BC_INST_JUMP,                             \
7022f57ecaeSStefan Eßer 		&&lbl_BC_INST_JUMP_ZERO,                        \
7032f57ecaeSStefan Eßer 		&&lbl_BC_INST_CALL,                             \
7042f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET,                              \
7052f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET0,                             \
7062f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET_VOID,                         \
7072f57ecaeSStefan Eßer 		&&lbl_BC_INST_HALT,                             \
7082f57ecaeSStefan Eßer 		&&lbl_BC_INST_POP,                              \
7092f57ecaeSStefan Eßer 		&&lbl_BC_INST_SWAP,                             \
7102f57ecaeSStefan Eßer 		&&lbl_BC_INST_MODEXP,                           \
7112f57ecaeSStefan Eßer 		&&lbl_BC_INST_DIVMOD,                           \
7122f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,                     \
71361e1a12bSStefan Eßer 		&&lbl_BC_INST_EXTENDED_REGISTERS,               \
7142f57ecaeSStefan Eßer 		&&lbl_BC_INST_POP_EXEC,                         \
7152f57ecaeSStefan Eßer 		&&lbl_BC_INST_EXECUTE,                          \
7162f57ecaeSStefan Eßer 		&&lbl_BC_INST_EXEC_COND,                        \
7172f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_STACK,                      \
7182f57ecaeSStefan Eßer 		&&lbl_BC_INST_CLEAR_STACK,                      \
7192f57ecaeSStefan Eßer 		&&lbl_BC_INST_REG_STACK_LEN,                    \
7202f57ecaeSStefan Eßer 		&&lbl_BC_INST_STACK_LEN,                        \
7212f57ecaeSStefan Eßer 		&&lbl_BC_INST_DUPLICATE,                        \
7222f57ecaeSStefan Eßer 		&&lbl_BC_INST_LOAD,                             \
7232f57ecaeSStefan Eßer 		&&lbl_BC_INST_PUSH_VAR,                         \
7242f57ecaeSStefan Eßer 		&&lbl_BC_INST_PUSH_TO_VAR,                      \
7252f57ecaeSStefan Eßer 		&&lbl_BC_INST_QUIT,                             \
7262f57ecaeSStefan Eßer 		&&lbl_BC_INST_NQUIT,                            \
7272f57ecaeSStefan Eßer 		&&lbl_BC_INST_EXEC_STACK_LEN,                   \
7282f57ecaeSStefan Eßer 		&&lbl_BC_INST_INVALID,                          \
7292f57ecaeSStefan Eßer 	}
7302f57ecaeSStefan Eßer 
7312f57ecaeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
7322f57ecaeSStefan Eßer 
7332f57ecaeSStefan Eßer #else // DC_ENABLED
7342f57ecaeSStefan Eßer 
7352f57ecaeSStefan Eßer #if BC_ENABLE_EXTRA_MATH
7362f57ecaeSStefan Eßer 
7375bdd6265SStefan Eßer #define BC_PROG_LBLS                                    \
7385bdd6265SStefan Eßer 	static const void* const bc_program_inst_lbls[] = { \
7392f57ecaeSStefan Eßer 		&&lbl_BC_INST_INC,                              \
7402f57ecaeSStefan Eßer 		&&lbl_BC_INST_DEC,                              \
7412f57ecaeSStefan Eßer 		&&lbl_BC_INST_NEG,                              \
7422f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_NOT,                         \
7432f57ecaeSStefan Eßer 		&&lbl_BC_INST_TRUNC,                            \
7442f57ecaeSStefan Eßer 		&&lbl_BC_INST_POWER,                            \
7452f57ecaeSStefan Eßer 		&&lbl_BC_INST_MULTIPLY,                         \
7462f57ecaeSStefan Eßer 		&&lbl_BC_INST_DIVIDE,                           \
7472f57ecaeSStefan Eßer 		&&lbl_BC_INST_MODULUS,                          \
7482f57ecaeSStefan Eßer 		&&lbl_BC_INST_PLUS,                             \
7492f57ecaeSStefan Eßer 		&&lbl_BC_INST_MINUS,                            \
7502f57ecaeSStefan Eßer 		&&lbl_BC_INST_PLACES,                           \
7512f57ecaeSStefan Eßer 		&&lbl_BC_INST_LSHIFT,                           \
7522f57ecaeSStefan Eßer 		&&lbl_BC_INST_RSHIFT,                           \
7532f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_EQ,                           \
7542f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_LE,                           \
7552f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_GE,                           \
7562f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_NE,                           \
7572f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_LT,                           \
7582f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_GT,                           \
7592f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_OR,                          \
7602f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_AND,                         \
7612f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER,                     \
7622f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
7632f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE,                    \
7642f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS,                   \
7652f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS,                      \
7662f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS,                     \
7672f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLACES,                    \
7682f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_LSHIFT,                    \
7692f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_RSHIFT,                    \
7702f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN,                           \
7712f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
7722f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
7732f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
7742f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
7752f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
7762f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
7772f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLACES_NO_VAL,             \
7782f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL,             \
7792f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL,             \
7802f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL,                    \
7812f57ecaeSStefan Eßer 		&&lbl_BC_INST_NUM,                              \
7822f57ecaeSStefan Eßer 		&&lbl_BC_INST_VAR,                              \
7832f57ecaeSStefan Eßer 		&&lbl_BC_INST_ARRAY_ELEM,                       \
7842f57ecaeSStefan Eßer 		&&lbl_BC_INST_ARRAY,                            \
7852f57ecaeSStefan Eßer 		&&lbl_BC_INST_ZERO,                             \
7862f57ecaeSStefan Eßer 		&&lbl_BC_INST_ONE,                              \
7872f57ecaeSStefan Eßer 		&&lbl_BC_INST_LAST,                             \
7882f57ecaeSStefan Eßer 		&&lbl_BC_INST_IBASE,                            \
7892f57ecaeSStefan Eßer 		&&lbl_BC_INST_OBASE,                            \
7902f57ecaeSStefan Eßer 		&&lbl_BC_INST_SCALE,                            \
7912f57ecaeSStefan Eßer 		&&lbl_BC_INST_SEED,                             \
7922f57ecaeSStefan Eßer 		&&lbl_BC_INST_LENGTH,                           \
7932f57ecaeSStefan Eßer 		&&lbl_BC_INST_SCALE_FUNC,                       \
7942f57ecaeSStefan Eßer 		&&lbl_BC_INST_SQRT,                             \
7952f57ecaeSStefan Eßer 		&&lbl_BC_INST_ABS,                              \
7960b671e8cSStefan Eßer 		&&lbl_BC_INST_IS_NUMBER,                        \
7970b671e8cSStefan Eßer 		&&lbl_BC_INST_IS_STRING,                        \
7982f57ecaeSStefan Eßer 		&&lbl_BC_INST_IRAND,                            \
7992f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASCIIFY,                          \
8002f57ecaeSStefan Eßer 		&&lbl_BC_INST_READ,                             \
8012f57ecaeSStefan Eßer 		&&lbl_BC_INST_RAND,                             \
8022f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXIBASE,                         \
8032f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXOBASE,                         \
8042f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXSCALE,                         \
8052f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXRAND,                          \
8065d58a515SStefan Eßer 		&&lbl_BC_INST_LINE_LENGTH,                      \
8075d58a515SStefan Eßer 		&&lbl_BC_INST_GLOBAL_STACKS,                    \
8085d58a515SStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,                     \
8092f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT,                            \
8102f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_POP,                        \
8112f57ecaeSStefan Eßer 		&&lbl_BC_INST_STR,                              \
8122f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_STR,                        \
8132f57ecaeSStefan Eßer 		&&lbl_BC_INST_JUMP,                             \
8142f57ecaeSStefan Eßer 		&&lbl_BC_INST_JUMP_ZERO,                        \
8152f57ecaeSStefan Eßer 		&&lbl_BC_INST_CALL,                             \
8162f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET,                              \
8172f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET0,                             \
8182f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET_VOID,                         \
8192f57ecaeSStefan Eßer 		&&lbl_BC_INST_HALT,                             \
8202f57ecaeSStefan Eßer 		&&lbl_BC_INST_POP,                              \
8212f57ecaeSStefan Eßer 		&&lbl_BC_INST_SWAP,                             \
8222f57ecaeSStefan Eßer 		&&lbl_BC_INST_MODEXP,                           \
8232f57ecaeSStefan Eßer 		&&lbl_BC_INST_DIVMOD,                           \
8242f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,                     \
8252f57ecaeSStefan Eßer 		&&lbl_BC_INST_INVALID,                          \
8262f57ecaeSStefan Eßer 	}
8272f57ecaeSStefan Eßer 
8282f57ecaeSStefan Eßer #else // BC_ENABLE_EXTRA_MATH
8292f57ecaeSStefan Eßer 
8305bdd6265SStefan Eßer #define BC_PROG_LBLS                                    \
8315bdd6265SStefan Eßer 	static const void* const bc_program_inst_lbls[] = { \
8322f57ecaeSStefan Eßer 		&&lbl_BC_INST_INC,                              \
8332f57ecaeSStefan Eßer 		&&lbl_BC_INST_DEC,                              \
8342f57ecaeSStefan Eßer 		&&lbl_BC_INST_NEG,                              \
8352f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_NOT,                         \
8362f57ecaeSStefan Eßer 		&&lbl_BC_INST_POWER,                            \
8372f57ecaeSStefan Eßer 		&&lbl_BC_INST_MULTIPLY,                         \
8382f57ecaeSStefan Eßer 		&&lbl_BC_INST_DIVIDE,                           \
8392f57ecaeSStefan Eßer 		&&lbl_BC_INST_MODULUS,                          \
8402f57ecaeSStefan Eßer 		&&lbl_BC_INST_PLUS,                             \
8412f57ecaeSStefan Eßer 		&&lbl_BC_INST_MINUS,                            \
8422f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_EQ,                           \
8432f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_LE,                           \
8442f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_GE,                           \
8452f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_NE,                           \
8462f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_LT,                           \
8472f57ecaeSStefan Eßer 		&&lbl_BC_INST_REL_GT,                           \
8482f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_OR,                          \
8492f57ecaeSStefan Eßer 		&&lbl_BC_INST_BOOL_AND,                         \
8502f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER,                     \
8512f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
8522f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE,                    \
8532f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS,                   \
8542f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS,                      \
8552f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS,                     \
8562f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN,                           \
8572f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
8582f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
8592f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
8602f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
8612f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
8622f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
8632f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL,                    \
8642f57ecaeSStefan Eßer 		&&lbl_BC_INST_NUM,                              \
8652f57ecaeSStefan Eßer 		&&lbl_BC_INST_VAR,                              \
8662f57ecaeSStefan Eßer 		&&lbl_BC_INST_ARRAY_ELEM,                       \
8672f57ecaeSStefan Eßer 		&&lbl_BC_INST_ARRAY,                            \
8682f57ecaeSStefan Eßer 		&&lbl_BC_INST_ZERO,                             \
8692f57ecaeSStefan Eßer 		&&lbl_BC_INST_ONE,                              \
8702f57ecaeSStefan Eßer 		&&lbl_BC_INST_LAST,                             \
8712f57ecaeSStefan Eßer 		&&lbl_BC_INST_IBASE,                            \
8722f57ecaeSStefan Eßer 		&&lbl_BC_INST_OBASE,                            \
8732f57ecaeSStefan Eßer 		&&lbl_BC_INST_SCALE,                            \
8742f57ecaeSStefan Eßer 		&&lbl_BC_INST_LENGTH,                           \
8752f57ecaeSStefan Eßer 		&&lbl_BC_INST_SCALE_FUNC,                       \
8762f57ecaeSStefan Eßer 		&&lbl_BC_INST_SQRT,                             \
8772f57ecaeSStefan Eßer 		&&lbl_BC_INST_ABS,                              \
8780b671e8cSStefan Eßer 		&&lbl_BC_INST_IS_NUMBER,                        \
8790b671e8cSStefan Eßer 		&&lbl_BC_INST_IS_STRING,                        \
8802f57ecaeSStefan Eßer 		&&lbl_BC_INST_ASCIIFY,                          \
8812f57ecaeSStefan Eßer 		&&lbl_BC_INST_READ,                             \
8822f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXIBASE,                         \
8832f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXOBASE,                         \
8842f57ecaeSStefan Eßer 		&&lbl_BC_INST_MAXSCALE,                         \
8855d58a515SStefan Eßer 		&&lbl_BC_INST_LINE_LENGTH,                      \
8865d58a515SStefan Eßer 		&&lbl_BC_INST_GLOBAL_STACKS,                    \
8875d58a515SStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,                     \
8882f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT,                            \
8892f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_POP,                        \
8902f57ecaeSStefan Eßer 		&&lbl_BC_INST_STR,                              \
8912f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_STR,                        \
8922f57ecaeSStefan Eßer 		&&lbl_BC_INST_JUMP,                             \
8932f57ecaeSStefan Eßer 		&&lbl_BC_INST_JUMP_ZERO,                        \
8942f57ecaeSStefan Eßer 		&&lbl_BC_INST_CALL,                             \
8952f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET,                              \
8962f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET0,                             \
8972f57ecaeSStefan Eßer 		&&lbl_BC_INST_RET_VOID,                         \
8982f57ecaeSStefan Eßer 		&&lbl_BC_INST_HALT,                             \
8992f57ecaeSStefan Eßer 		&&lbl_BC_INST_POP,                              \
9002f57ecaeSStefan Eßer 		&&lbl_BC_INST_SWAP,                             \
9012f57ecaeSStefan Eßer 		&&lbl_BC_INST_MODEXP,                           \
9022f57ecaeSStefan Eßer 		&&lbl_BC_INST_DIVMOD,                           \
9032f57ecaeSStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,                     \
9042f57ecaeSStefan Eßer 		&&lbl_BC_INST_INVALID,                          \
9052f57ecaeSStefan Eßer 	}
9062f57ecaeSStefan Eßer 
9072f57ecaeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
9082f57ecaeSStefan Eßer 
9092f57ecaeSStefan Eßer #endif // DC_ENABLED
9102f57ecaeSStefan Eßer 
9112f57ecaeSStefan Eßer #else // BC_ENABLED
9122f57ecaeSStefan Eßer 
9132f57ecaeSStefan Eßer #if BC_ENABLE_EXTRA_MATH
9142f57ecaeSStefan Eßer 
9155bdd6265SStefan Eßer #define BC_PROG_LBLS                                                   \
9165bdd6265SStefan Eßer 	static const void* const bc_program_inst_lbls[] = {                \
9170ff539ebSStefan Eßer 		&&lbl_BC_INST_NEG,           &&lbl_BC_INST_BOOL_NOT,           \
9180ff539ebSStefan Eßer 		&&lbl_BC_INST_TRUNC,         &&lbl_BC_INST_POWER,              \
9190ff539ebSStefan Eßer 		&&lbl_BC_INST_MULTIPLY,      &&lbl_BC_INST_DIVIDE,             \
9200ff539ebSStefan Eßer 		&&lbl_BC_INST_MODULUS,       &&lbl_BC_INST_PLUS,               \
9210ff539ebSStefan Eßer 		&&lbl_BC_INST_MINUS,         &&lbl_BC_INST_PLACES,             \
9220ff539ebSStefan Eßer 		&&lbl_BC_INST_LSHIFT,        &&lbl_BC_INST_RSHIFT,             \
9230ff539ebSStefan Eßer 		&&lbl_BC_INST_REL_EQ,        &&lbl_BC_INST_REL_LE,             \
9240ff539ebSStefan Eßer 		&&lbl_BC_INST_REL_GE,        &&lbl_BC_INST_REL_NE,             \
9250ff539ebSStefan Eßer 		&&lbl_BC_INST_REL_LT,        &&lbl_BC_INST_REL_GT,             \
9260ff539ebSStefan Eßer 		&&lbl_BC_INST_BOOL_OR,       &&lbl_BC_INST_BOOL_AND,           \
9270ff539ebSStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL, &&lbl_BC_INST_NUM,                \
9280ff539ebSStefan Eßer 		&&lbl_BC_INST_VAR,           &&lbl_BC_INST_ARRAY_ELEM,         \
9290ff539ebSStefan Eßer 		&&lbl_BC_INST_ARRAY,         &&lbl_BC_INST_ZERO,               \
9300ff539ebSStefan Eßer 		&&lbl_BC_INST_ONE,           &&lbl_BC_INST_IBASE,              \
9310ff539ebSStefan Eßer 		&&lbl_BC_INST_OBASE,         &&lbl_BC_INST_SCALE,              \
9320ff539ebSStefan Eßer 		&&lbl_BC_INST_SEED,          &&lbl_BC_INST_LENGTH,             \
9330ff539ebSStefan Eßer 		&&lbl_BC_INST_SCALE_FUNC,    &&lbl_BC_INST_SQRT,               \
9340ff539ebSStefan Eßer 		&&lbl_BC_INST_ABS,           &&lbl_BC_INST_IS_NUMBER,          \
9350ff539ebSStefan Eßer 		&&lbl_BC_INST_IS_STRING,     &&lbl_BC_INST_IRAND,              \
9360ff539ebSStefan Eßer 		&&lbl_BC_INST_ASCIIFY,       &&lbl_BC_INST_READ,               \
9370ff539ebSStefan Eßer 		&&lbl_BC_INST_RAND,          &&lbl_BC_INST_MAXIBASE,           \
9380ff539ebSStefan Eßer 		&&lbl_BC_INST_MAXOBASE,      &&lbl_BC_INST_MAXSCALE,           \
9390ff539ebSStefan Eßer 		&&lbl_BC_INST_MAXRAND,       &&lbl_BC_INST_LINE_LENGTH,        \
9400ff539ebSStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,  &&lbl_BC_INST_PRINT,              \
9410ff539ebSStefan Eßer 		&&lbl_BC_INST_PRINT_POP,     &&lbl_BC_INST_STR,                \
9420ff539ebSStefan Eßer 		&&lbl_BC_INST_POP,           &&lbl_BC_INST_SWAP,               \
9430ff539ebSStefan Eßer 		&&lbl_BC_INST_MODEXP,        &&lbl_BC_INST_DIVMOD,             \
9440ff539ebSStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,  &&lbl_BC_INST_EXTENDED_REGISTERS, \
9450ff539ebSStefan Eßer 		&&lbl_BC_INST_POP_EXEC,      &&lbl_BC_INST_EXECUTE,            \
9460ff539ebSStefan Eßer 		&&lbl_BC_INST_EXEC_COND,     &&lbl_BC_INST_PRINT_STACK,        \
9470ff539ebSStefan Eßer 		&&lbl_BC_INST_CLEAR_STACK,   &&lbl_BC_INST_REG_STACK_LEN,      \
9480ff539ebSStefan Eßer 		&&lbl_BC_INST_STACK_LEN,     &&lbl_BC_INST_DUPLICATE,          \
9490ff539ebSStefan Eßer 		&&lbl_BC_INST_LOAD,          &&lbl_BC_INST_PUSH_VAR,           \
9500ff539ebSStefan Eßer 		&&lbl_BC_INST_PUSH_TO_VAR,   &&lbl_BC_INST_QUIT,               \
9510ff539ebSStefan Eßer 		&&lbl_BC_INST_NQUIT,         &&lbl_BC_INST_EXEC_STACK_LEN,     \
9522f57ecaeSStefan Eßer 		&&lbl_BC_INST_INVALID,                                         \
9532f57ecaeSStefan Eßer 	}
9542f57ecaeSStefan Eßer 
9552f57ecaeSStefan Eßer #else // BC_ENABLE_EXTRA_MATH
9562f57ecaeSStefan Eßer 
9575bdd6265SStefan Eßer #define BC_PROG_LBLS                                                   \
9585bdd6265SStefan Eßer 	static const void* const bc_program_inst_lbls[] = {                \
9590ff539ebSStefan Eßer 		&&lbl_BC_INST_NEG,           &&lbl_BC_INST_BOOL_NOT,           \
9600ff539ebSStefan Eßer 		&&lbl_BC_INST_POWER,         &&lbl_BC_INST_MULTIPLY,           \
9610ff539ebSStefan Eßer 		&&lbl_BC_INST_DIVIDE,        &&lbl_BC_INST_MODULUS,            \
9620ff539ebSStefan Eßer 		&&lbl_BC_INST_PLUS,          &&lbl_BC_INST_MINUS,              \
9630ff539ebSStefan Eßer 		&&lbl_BC_INST_REL_EQ,        &&lbl_BC_INST_REL_LE,             \
9640ff539ebSStefan Eßer 		&&lbl_BC_INST_REL_GE,        &&lbl_BC_INST_REL_NE,             \
9650ff539ebSStefan Eßer 		&&lbl_BC_INST_REL_LT,        &&lbl_BC_INST_REL_GT,             \
9660ff539ebSStefan Eßer 		&&lbl_BC_INST_BOOL_OR,       &&lbl_BC_INST_BOOL_AND,           \
9670ff539ebSStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL, &&lbl_BC_INST_NUM,                \
9680ff539ebSStefan Eßer 		&&lbl_BC_INST_VAR,           &&lbl_BC_INST_ARRAY_ELEM,         \
9690ff539ebSStefan Eßer 		&&lbl_BC_INST_ARRAY,         &&lbl_BC_INST_ZERO,               \
9700ff539ebSStefan Eßer 		&&lbl_BC_INST_ONE,           &&lbl_BC_INST_IBASE,              \
9710ff539ebSStefan Eßer 		&&lbl_BC_INST_OBASE,         &&lbl_BC_INST_SCALE,              \
9720ff539ebSStefan Eßer 		&&lbl_BC_INST_LENGTH,        &&lbl_BC_INST_SCALE_FUNC,         \
9730ff539ebSStefan Eßer 		&&lbl_BC_INST_SQRT,          &&lbl_BC_INST_ABS,                \
9740ff539ebSStefan Eßer 		&&lbl_BC_INST_IS_NUMBER,     &&lbl_BC_INST_IS_STRING,          \
9750ff539ebSStefan Eßer 		&&lbl_BC_INST_ASCIIFY,       &&lbl_BC_INST_READ,               \
9760ff539ebSStefan Eßer 		&&lbl_BC_INST_MAXIBASE,      &&lbl_BC_INST_MAXOBASE,           \
9770ff539ebSStefan Eßer 		&&lbl_BC_INST_MAXSCALE,      &&lbl_BC_INST_LINE_LENGTH,        \
9780ff539ebSStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,  &&lbl_BC_INST_PRINT,              \
9790ff539ebSStefan Eßer 		&&lbl_BC_INST_PRINT_POP,     &&lbl_BC_INST_STR,                \
9800ff539ebSStefan Eßer 		&&lbl_BC_INST_POP,           &&lbl_BC_INST_SWAP,               \
9810ff539ebSStefan Eßer 		&&lbl_BC_INST_MODEXP,        &&lbl_BC_INST_DIVMOD,             \
9820ff539ebSStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,  &&lbl_BC_INST_EXTENDED_REGISTERS, \
9830ff539ebSStefan Eßer 		&&lbl_BC_INST_POP_EXEC,      &&lbl_BC_INST_EXECUTE,            \
9840ff539ebSStefan Eßer 		&&lbl_BC_INST_EXEC_COND,     &&lbl_BC_INST_PRINT_STACK,        \
9850ff539ebSStefan Eßer 		&&lbl_BC_INST_CLEAR_STACK,   &&lbl_BC_INST_REG_STACK_LEN,      \
9860ff539ebSStefan Eßer 		&&lbl_BC_INST_STACK_LEN,     &&lbl_BC_INST_DUPLICATE,          \
9870ff539ebSStefan Eßer 		&&lbl_BC_INST_LOAD,          &&lbl_BC_INST_PUSH_VAR,           \
9880ff539ebSStefan Eßer 		&&lbl_BC_INST_PUSH_TO_VAR,   &&lbl_BC_INST_QUIT,               \
9890ff539ebSStefan Eßer 		&&lbl_BC_INST_NQUIT,         &&lbl_BC_INST_EXEC_STACK_LEN,     \
9902f57ecaeSStefan Eßer 		&&lbl_BC_INST_INVALID,                                         \
9912f57ecaeSStefan Eßer 	}
9922f57ecaeSStefan Eßer 
9932f57ecaeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
9942f57ecaeSStefan Eßer 
9952f57ecaeSStefan Eßer #endif // BC_ENABLED
9962f57ecaeSStefan Eßer 
9972f57ecaeSStefan Eßer #else // BC_HAS_COMPUTED_GOTO
9982f57ecaeSStefan Eßer 
9992f57ecaeSStefan Eßer #define BC_PROG_JUMP(inst, code, ip) break
10002f57ecaeSStefan Eßer #define BC_PROG_DIRECT_JUMP(l)
10012f57ecaeSStefan Eßer #define BC_PROG_LBL(l) case l
10022f57ecaeSStefan Eßer #define BC_PROG_FALLTHROUGH BC_FALLTHROUGH
10032f57ecaeSStefan Eßer 
10042f57ecaeSStefan Eßer #define BC_PROG_LBLS
10052f57ecaeSStefan Eßer 
10062f57ecaeSStefan Eßer #endif // BC_HAS_COMPUTED_GOTO
10072f57ecaeSStefan Eßer 
10081f958cfaSStefan Eßer #endif // BC_PROGRAM_H
1009