xref: /freebsd-src/contrib/bc/include/program.h (revision a970610a3af63b3f4df5b69d91c6b4093a00ed8f)
1252884aeSStefan Eßer /*
2252884aeSStefan Eßer  * *****************************************************************************
3252884aeSStefan Eßer  *
43aa99676SStefan Eßer  * SPDX-License-Identifier: BSD-2-Clause
5252884aeSStefan Eßer  *
6*a970610aSStefan Eßer  * Copyright (c) 2018-2024 Gavin D. Howard and contributors.
7252884aeSStefan Eßer  *
8252884aeSStefan Eßer  * Redistribution and use in source and binary forms, with or without
9252884aeSStefan Eßer  * modification, are permitted provided that the following conditions are met:
10252884aeSStefan Eßer  *
11252884aeSStefan Eßer  * * Redistributions of source code must retain the above copyright notice, this
12252884aeSStefan Eßer  *   list of conditions and the following disclaimer.
13252884aeSStefan Eßer  *
14252884aeSStefan Eßer  * * Redistributions in binary form must reproduce the above copyright notice,
15252884aeSStefan Eßer  *   this list of conditions and the following disclaimer in the documentation
16252884aeSStefan Eßer  *   and/or other materials provided with the distribution.
17252884aeSStefan Eßer  *
18252884aeSStefan Eßer  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19252884aeSStefan Eßer  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20252884aeSStefan Eßer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21252884aeSStefan Eßer  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22252884aeSStefan Eßer  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23252884aeSStefan Eßer  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24252884aeSStefan Eßer  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25252884aeSStefan Eßer  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26252884aeSStefan Eßer  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27252884aeSStefan Eßer  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28252884aeSStefan Eßer  * POSSIBILITY OF SUCH DAMAGE.
29252884aeSStefan Eßer  *
30252884aeSStefan Eßer  * *****************************************************************************
31252884aeSStefan Eßer  *
32252884aeSStefan Eßer  * Definitions for bc programs.
33252884aeSStefan Eßer  *
34252884aeSStefan Eßer  */
35252884aeSStefan Eßer 
36252884aeSStefan Eßer #ifndef BC_PROGRAM_H
37252884aeSStefan Eßer #define BC_PROGRAM_H
38252884aeSStefan Eßer 
3944d4804dSStefan Eßer #include <assert.h>
40252884aeSStefan Eßer #include <stddef.h>
41252884aeSStefan Eßer 
42252884aeSStefan Eßer #include <status.h>
43252884aeSStefan Eßer #include <parse.h>
44252884aeSStefan Eßer #include <lang.h>
45252884aeSStefan Eßer #include <num.h>
46252884aeSStefan Eßer #include <rand.h>
47252884aeSStefan Eßer 
4844d4804dSStefan Eßer /// The index of ibase in the globals array.
49252884aeSStefan Eßer #define BC_PROG_GLOBALS_IBASE (0)
5044d4804dSStefan Eßer 
5144d4804dSStefan Eßer /// The index of obase in the globals array.
52252884aeSStefan Eßer #define BC_PROG_GLOBALS_OBASE (1)
5344d4804dSStefan Eßer 
5444d4804dSStefan Eßer /// The index of scale in the globals array.
55252884aeSStefan Eßer #define BC_PROG_GLOBALS_SCALE (2)
56252884aeSStefan Eßer 
57252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH
5844d4804dSStefan Eßer 
5944d4804dSStefan Eßer /// The index of the rand max in the maxes array.
60252884aeSStefan Eßer #define BC_PROG_MAX_RAND (3)
6144d4804dSStefan Eßer 
62252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
63252884aeSStefan Eßer 
6444d4804dSStefan Eßer /// The length of the globals array.
65252884aeSStefan Eßer #define BC_PROG_GLOBALS_LEN (3 + BC_ENABLE_EXTRA_MATH)
66252884aeSStefan Eßer 
6778bc019dSStefan Eßer typedef struct BcProgram
6878bc019dSStefan Eßer {
6944d4804dSStefan Eßer 	/// The array of globals values.
70252884aeSStefan Eßer 	BcBigDig globals[BC_PROG_GLOBALS_LEN];
7144d4804dSStefan Eßer 
72d101cdd6SStefan Eßer #if BC_ENABLED
7344d4804dSStefan Eßer 	/// The array of globals stacks.
74252884aeSStefan Eßer 	BcVec globals_v[BC_PROG_GLOBALS_LEN];
75d101cdd6SStefan Eßer #endif // BC_ENABLED
76252884aeSStefan Eßer 
7744d4804dSStefan Eßer #if BC_ENABLE_EXTRA_MATH
78252884aeSStefan Eßer 
7944d4804dSStefan Eßer 	/// The pseudo-random number generator.
8044d4804dSStefan Eßer 	BcRNG rng;
8144d4804dSStefan Eßer 
8244d4804dSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
8344d4804dSStefan Eßer 
8444d4804dSStefan Eßer 	/// The results stack.
85252884aeSStefan Eßer 	BcVec results;
8644d4804dSStefan Eßer 
8744d4804dSStefan Eßer 	/// The execution stack.
88252884aeSStefan Eßer 	BcVec stack;
89252884aeSStefan Eßer 
90d101cdd6SStefan Eßer 	/// The constants encountered in the program. They are global to the program
91d101cdd6SStefan Eßer 	/// to prevent bad accesses when functions that used non-auto variables are
92d101cdd6SStefan Eßer 	/// replaced.
93d101cdd6SStefan Eßer 	BcVec consts;
9444d4804dSStefan Eßer 
95d101cdd6SStefan Eßer 	/// The map of constants to go with consts.
96d101cdd6SStefan Eßer 	BcVec const_map;
97d101cdd6SStefan Eßer 
98d101cdd6SStefan Eßer 	/// The strings encountered in the program. They are global to the program
99d101cdd6SStefan Eßer 	/// to prevent bad accesses when functions that used non-auto variables are
100d101cdd6SStefan Eßer 	/// replaced.
101d101cdd6SStefan Eßer 	BcVec strs;
102d101cdd6SStefan Eßer 
103d101cdd6SStefan Eßer 	/// The map of strings to go with strs.
104d101cdd6SStefan Eßer 	BcVec str_map;
105252884aeSStefan Eßer 
10644d4804dSStefan Eßer 	/// The array of functions.
107252884aeSStefan Eßer 	BcVec fns;
10844d4804dSStefan Eßer 
10944d4804dSStefan Eßer 	/// The map of functions to go with fns.
110252884aeSStefan Eßer 	BcVec fn_map;
111252884aeSStefan Eßer 
11244d4804dSStefan Eßer 	/// The array of variables.
113252884aeSStefan Eßer 	BcVec vars;
11444d4804dSStefan Eßer 
11544d4804dSStefan Eßer 	/// The map of variables to go with vars.
116252884aeSStefan Eßer 	BcVec var_map;
117252884aeSStefan Eßer 
11844d4804dSStefan Eßer 	/// The array of arrays.
119252884aeSStefan Eßer 	BcVec arrs;
12044d4804dSStefan Eßer 
12144d4804dSStefan Eßer 	/// The map of arrays to go with arrs.
122252884aeSStefan Eßer 	BcVec arr_map;
123252884aeSStefan Eßer 
124252884aeSStefan Eßer #if DC_ENABLED
1253aa99676SStefan Eßer 
12644d4804dSStefan Eßer 	/// A vector of tail calls. These are just integers, which are the number of
12744d4804dSStefan Eßer 	/// tail calls that have been executed for each function (string) on the
12844d4804dSStefan Eßer 	/// stack for dc. This is to prevent dc from constantly growing memory use
12944d4804dSStefan Eßer 	/// because of pushing more and more string executions on the stack.
130252884aeSStefan Eßer 	BcVec tail_calls;
131252884aeSStefan Eßer 
132252884aeSStefan Eßer #endif // DC_ENABLED
133252884aeSStefan Eßer 
13444d4804dSStefan Eßer 	/// A BcNum that has the proper base for asciify.
13544d4804dSStefan Eßer 	BcNum strmb;
136252884aeSStefan Eßer 
137d101cdd6SStefan Eßer 	// A BcNum to run asciify. This is to prevent GCC longjmp() clobbering
138d101cdd6SStefan Eßer 	// warnings.
139d101cdd6SStefan Eßer 	BcNum asciify;
140d101cdd6SStefan Eßer 
141252884aeSStefan Eßer #if BC_ENABLED
14244d4804dSStefan Eßer 
14344d4804dSStefan Eßer 	/// The last printed value for bc.
144252884aeSStefan Eßer 	BcNum last;
14544d4804dSStefan Eßer 
146252884aeSStefan Eßer #endif // BC_ENABLED
147252884aeSStefan Eßer 
14844d4804dSStefan Eßer 	// The BcDig array for strmb. This uses BC_NUM_LONG_LOG10 because it is used
14944d4804dSStefan Eßer 	// in bc_num_ulong2num(), which attempts to realloc, unless it is big
15044d4804dSStefan Eßer 	// enough. This is big enough.
151252884aeSStefan Eßer 	BcDig strmb_num[BC_NUM_BIGDIG_LOG10];
152252884aeSStefan Eßer 
153252884aeSStefan Eßer } BcProgram;
154252884aeSStefan Eßer 
15544d4804dSStefan Eßer /**
15644d4804dSStefan Eßer  * Returns true if the stack @a s has at least @a n items, false otherwise.
15744d4804dSStefan Eßer  * @param s  The stack to check.
15844d4804dSStefan Eßer  * @param n  The number of items the stack must have.
15944d4804dSStefan Eßer  * @return   True if @a s has at least @a n items, false otherwise.
16044d4804dSStefan Eßer  */
161252884aeSStefan Eßer #define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) (n)))
162252884aeSStefan Eßer 
16344d4804dSStefan Eßer /**
16444d4804dSStefan Eßer  * Get a pointer to the top value in a global value stack.
16544d4804dSStefan Eßer  * @param v  The global value stack.
16644d4804dSStefan Eßer  * @return   A pointer to the top value in @a v.
16744d4804dSStefan Eßer  */
168252884aeSStefan Eßer #define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v))
16944d4804dSStefan Eßer 
17044d4804dSStefan Eßer /**
17144d4804dSStefan Eßer  * Get the top value in a global value stack.
17244d4804dSStefan Eßer  * @param v  The global value stack.
17344d4804dSStefan Eßer  * @return   The top value in @a v.
17444d4804dSStefan Eßer  */
175252884aeSStefan Eßer #define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v)))
176252884aeSStefan Eßer 
17744d4804dSStefan Eßer /**
17844d4804dSStefan Eßer  * Returns the current value of ibase.
17944d4804dSStefan Eßer  * @param p  The program.
18044d4804dSStefan Eßer  * @return   The current ibase.
18144d4804dSStefan Eßer  */
182252884aeSStefan Eßer #define BC_PROG_IBASE(p) ((p)->globals[BC_PROG_GLOBALS_IBASE])
18344d4804dSStefan Eßer 
18444d4804dSStefan Eßer /**
18544d4804dSStefan Eßer  * Returns the current value of obase.
18644d4804dSStefan Eßer  * @param p  The program.
18744d4804dSStefan Eßer  * @return   The current obase.
18844d4804dSStefan Eßer  */
189252884aeSStefan Eßer #define BC_PROG_OBASE(p) ((p)->globals[BC_PROG_GLOBALS_OBASE])
19044d4804dSStefan Eßer 
19144d4804dSStefan Eßer /**
19244d4804dSStefan Eßer  * Returns the current value of scale.
19344d4804dSStefan Eßer  * @param p  The program.
19444d4804dSStefan Eßer  * @return   The current scale.
19544d4804dSStefan Eßer  */
196252884aeSStefan Eßer #define BC_PROG_SCALE(p) ((p)->globals[BC_PROG_GLOBALS_SCALE])
197252884aeSStefan Eßer 
19844d4804dSStefan Eßer /// The index for the main function in the functions array.//
199252884aeSStefan Eßer #define BC_PROG_MAIN (0)
20044d4804dSStefan Eßer 
20144d4804dSStefan Eßer /// The index for the read function in the functions array.
202252884aeSStefan Eßer #define BC_PROG_READ (1)
203252884aeSStefan Eßer 
20444d4804dSStefan Eßer /**
20544d4804dSStefan Eßer  * Retires (completes the execution of) an instruction. Some instructions
20644d4804dSStefan Eßer  * require special retirement, but most can use this. This basically pops the
20744d4804dSStefan Eßer  * operands while preserving the result (which we assumed was pushed before the
20844d4804dSStefan Eßer  * actual operation).
20944d4804dSStefan Eßer  * @param p     The program.
21044d4804dSStefan Eßer  * @param nres  The number of results returned by the instruction.
21144d4804dSStefan Eßer  * @param nops  The number of operands used by the instruction.
21244d4804dSStefan Eßer  */
213252884aeSStefan Eßer #define bc_program_retire(p, nres, nops) \
214252884aeSStefan Eßer 	(bc_vec_npopAt(&(p)->results, (nops), (p)->results.len - (nres + nops)))
215252884aeSStefan Eßer 
216252884aeSStefan Eßer #if DC_ENABLED
21744d4804dSStefan Eßer 
21844d4804dSStefan Eßer /// A constant that tells how many functions are required in dc.
219252884aeSStefan Eßer #define BC_PROG_REQ_FUNCS (2)
22044d4804dSStefan Eßer 
221252884aeSStefan Eßer #if !BC_ENABLED
22244d4804dSStefan Eßer 
223d101cdd6SStefan Eßer /// Returns true if the calculator should pop after printing.
224d101cdd6SStefan Eßer #define BC_PROGRAM_POP(pop) (pop)
225d101cdd6SStefan Eßer 
226d101cdd6SStefan Eßer #else // !BC_ENABLED
227d101cdd6SStefan Eßer 
228d101cdd6SStefan Eßer /// Returns true if the calculator should pop after printing.
229d101cdd6SStefan Eßer #define BC_PROGRAM_POP(pop) (BC_IS_BC || (pop))
23044d4804dSStefan Eßer 
231252884aeSStefan Eßer #endif // !BC_ENABLED
23244d4804dSStefan Eßer 
233d101cdd6SStefan Eßer // This is here to satisfy a clang warning about recursive macros.
234d101cdd6SStefan Eßer #define bc_program_pushVar(p, code, bgn, pop, copy) \
235d101cdd6SStefan Eßer 	bc_program_pushVar_impl(p, code, bgn, pop, copy)
236d101cdd6SStefan Eßer 
237252884aeSStefan Eßer #else // DC_ENABLED
23844d4804dSStefan Eßer 
239d101cdd6SStefan Eßer // This define disappears pop and copy because for bc, 'pop' and 'copy' are
240d101cdd6SStefan Eßer // always false.
241252884aeSStefan Eßer #define bc_program_pushVar(p, code, bgn, pop, copy) \
242d101cdd6SStefan Eßer 	bc_program_pushVar_impl(p, code, bgn)
243d101cdd6SStefan Eßer 
244d101cdd6SStefan Eßer /// Returns true if the calculator should pop after printing.
245d101cdd6SStefan Eßer #define BC_PROGRAM_POP(pop) (BC_IS_BC)
24644d4804dSStefan Eßer 
24744d4804dSStefan Eßer // In debug mode, we want bc to check the stack, but otherwise, we don't because
24844d4804dSStefan Eßer // the bc language implicitly mandates that the stack should always have enough
24944d4804dSStefan Eßer // items.
250103d7cdfSStefan Eßer #ifdef BC_DEBUG
251252884aeSStefan Eßer #define BC_PROG_NO_STACK_CHECK
252103d7cdfSStefan Eßer #endif // BC_DEBUG
25344d4804dSStefan Eßer 
254252884aeSStefan Eßer #endif // DC_ENABLED
255252884aeSStefan Eßer 
25644d4804dSStefan Eßer /**
25744d4804dSStefan Eßer  * Returns true if the BcNum @a n is acting as a string.
25844d4804dSStefan Eßer  * @param n  The BcNum to test.
25944d4804dSStefan Eßer  * @return   True if @a n is acting as a string, false otherwise.
26044d4804dSStefan Eßer  */
261252884aeSStefan Eßer #define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap)
26244d4804dSStefan Eßer 
263252884aeSStefan Eßer #if BC_ENABLED
26444d4804dSStefan Eßer 
26544d4804dSStefan Eßer /**
26644d4804dSStefan Eßer  * Returns true if the result @a r and @a n is a number.
26744d4804dSStefan Eßer  * @param r  The result.
26844d4804dSStefan Eßer  * @param n  The number corresponding to the result.
26944d4804dSStefan Eßer  * @return   True if the result holds a number, false otherwise.
27044d4804dSStefan Eßer  */
271252884aeSStefan Eßer #define BC_PROG_NUM(r, n) \
272252884aeSStefan Eßer 	((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
27344d4804dSStefan Eßer 
274252884aeSStefan Eßer #else // BC_ENABLED
27544d4804dSStefan Eßer 
27644d4804dSStefan Eßer /**
27744d4804dSStefan Eßer  * Returns true if the result @a r and @a n is a number.
27844d4804dSStefan Eßer  * @param r  The result.
27944d4804dSStefan Eßer  * @param n  The number corresponding to the result.
28044d4804dSStefan Eßer  * @return   True if the result holds a number, false otherwise.
28144d4804dSStefan Eßer  */
282252884aeSStefan Eßer #define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
28344d4804dSStefan Eßer 
284252884aeSStefan Eßer #endif // BC_ENABLED
285252884aeSStefan Eßer 
28644d4804dSStefan Eßer /**
28744d4804dSStefan Eßer  * This is a function type for unary operations. Currently, these include
28844d4804dSStefan Eßer  * boolean not, negation, and truncation with extra math.
28944d4804dSStefan Eßer  * @param r  The BcResult to store the result into.
29044d4804dSStefan Eßer  * @param n  The parameter to the unary operation.
29144d4804dSStefan Eßer  */
29244d4804dSStefan Eßer typedef void (*BcProgramUnary)(BcResult* r, BcNum* n);
293252884aeSStefan Eßer 
29444d4804dSStefan Eßer /**
29544d4804dSStefan Eßer  * Initializes the BcProgram.
29644d4804dSStefan Eßer  * @param p  The program to initialize.
29744d4804dSStefan Eßer  */
29878bc019dSStefan Eßer void
29978bc019dSStefan Eßer bc_program_init(BcProgram* p);
30044d4804dSStefan Eßer 
301103d7cdfSStefan Eßer #if BC_DEBUG
30244d4804dSStefan Eßer 
30344d4804dSStefan Eßer /**
30444d4804dSStefan Eßer  * Frees a BcProgram. This is only used in debug builds because a BcProgram is
30544d4804dSStefan Eßer  * only freed on program exit, and we don't care about freeing resources on
30644d4804dSStefan Eßer  * exit.
30744d4804dSStefan Eßer  * @param p  The program to initialize.
30844d4804dSStefan Eßer  */
30978bc019dSStefan Eßer void
31078bc019dSStefan Eßer bc_program_free(BcProgram* p);
311252884aeSStefan Eßer 
312103d7cdfSStefan Eßer #endif // BC_DEBUG
31344d4804dSStefan Eßer 
314d101cdd6SStefan Eßer /**
315d101cdd6SStefan Eßer  * Prints a stack trace of the bc functions or dc strings currently executing.
316d101cdd6SStefan Eßer  * @param p  The program.
317d101cdd6SStefan Eßer  */
318d101cdd6SStefan Eßer void
319d101cdd6SStefan Eßer bc_program_printStackTrace(BcProgram* p);
320d101cdd6SStefan Eßer 
321252884aeSStefan Eßer #if BC_DEBUG_CODE
322252884aeSStefan Eßer #if BC_ENABLED && DC_ENABLED
32344d4804dSStefan Eßer 
32444d4804dSStefan Eßer /**
32544d4804dSStefan Eßer  * Prints the bytecode in a function. This is a debug-only function.
32644d4804dSStefan Eßer  * @param p  The program.
32744d4804dSStefan Eßer  */
32878bc019dSStefan Eßer void
32978bc019dSStefan Eßer bc_program_code(const BcProgram* p);
33044d4804dSStefan Eßer 
33144d4804dSStefan Eßer /**
33244d4804dSStefan Eßer  * Prints an instruction. This is a debug-only function.
33344d4804dSStefan Eßer  * @param p  The program.
33444d4804dSStefan Eßer  * @param code  The bytecode array.
33544d4804dSStefan Eßer  * @param bgn   A pointer to the current index. It is also updated to the next
33644d4804dSStefan Eßer  *              index.
33744d4804dSStefan Eßer  */
33878bc019dSStefan Eßer void
33978bc019dSStefan Eßer bc_program_printInst(const BcProgram* p, const char* code,
340252884aeSStefan Eßer                      size_t* restrict bgn);
34144d4804dSStefan Eßer 
34244d4804dSStefan Eßer /**
34344d4804dSStefan Eßer  * Prints the stack. This is a debug-only function.
34444d4804dSStefan Eßer  * @param p  The program.
34544d4804dSStefan Eßer  */
34678bc019dSStefan Eßer void
34778bc019dSStefan Eßer bc_program_printStackDebug(BcProgram* p);
34844d4804dSStefan Eßer 
349252884aeSStefan Eßer #endif // BC_ENABLED && DC_ENABLED
350252884aeSStefan Eßer #endif // BC_DEBUG_CODE
351252884aeSStefan Eßer 
35244d4804dSStefan Eßer /**
35344d4804dSStefan Eßer  * Returns the index of the variable or array in their respective arrays.
35444d4804dSStefan Eßer  * @param p     The program.
355d101cdd6SStefan Eßer  * @param name  The name of the variable or array.
35644d4804dSStefan Eßer  * @param var   True if the search should be for a variable, false for an array.
35744d4804dSStefan Eßer  * @return      The index of the variable or array in the correct array.
35844d4804dSStefan Eßer  */
35978bc019dSStefan Eßer size_t
360d101cdd6SStefan Eßer bc_program_search(BcProgram* p, const char* name, bool var);
36144d4804dSStefan Eßer 
36244d4804dSStefan Eßer /**
363d101cdd6SStefan Eßer  * Adds a string to the program and returns the string's index in the program.
36444d4804dSStefan Eßer  * @param p    The program.
36544d4804dSStefan Eßer  * @param str  The string to add.
366d101cdd6SStefan Eßer  * @return     The string's index in the program.
36744d4804dSStefan Eßer  */
36878bc019dSStefan Eßer size_t
369d101cdd6SStefan Eßer bc_program_addString(BcProgram* p, const char* str);
37044d4804dSStefan Eßer 
37144d4804dSStefan Eßer /**
37244d4804dSStefan Eßer  * Inserts a function into the program and returns the index of the function in
37344d4804dSStefan Eßer  * the fns array.
37444d4804dSStefan Eßer  * @param p     The program.
37544d4804dSStefan Eßer  * @param name  The name of the function.
37644d4804dSStefan Eßer  * @return      The index of the function after insertion.
37744d4804dSStefan Eßer  */
37878bc019dSStefan Eßer size_t
37978bc019dSStefan Eßer bc_program_insertFunc(BcProgram* p, const char* name);
38044d4804dSStefan Eßer 
38144d4804dSStefan Eßer /**
38244d4804dSStefan Eßer  * Resets a program, usually because of resetting after an error.
38344d4804dSStefan Eßer  * @param p  The program to reset.
38444d4804dSStefan Eßer  */
38578bc019dSStefan Eßer void
38678bc019dSStefan Eßer bc_program_reset(BcProgram* p);
38744d4804dSStefan Eßer 
38844d4804dSStefan Eßer /**
38944d4804dSStefan Eßer  * Executes bc or dc code in the BcProgram.
39044d4804dSStefan Eßer  * @param p  The program.
39144d4804dSStefan Eßer  */
39278bc019dSStefan Eßer void
39378bc019dSStefan Eßer bc_program_exec(BcProgram* p);
394252884aeSStefan Eßer 
39544d4804dSStefan Eßer /**
39644d4804dSStefan Eßer  * Negates a copy of a BcNum. This is a BcProgramUnary function.
39744d4804dSStefan Eßer  * @param r  The BcResult to store the result into.
39844d4804dSStefan Eßer  * @param n  The parameter to the unary operation.
39944d4804dSStefan Eßer  */
40078bc019dSStefan Eßer void
40178bc019dSStefan Eßer bc_program_negate(BcResult* r, BcNum* n);
40244d4804dSStefan Eßer 
40344d4804dSStefan Eßer /**
40444d4804dSStefan Eßer  * Returns a boolean not of a BcNum. This is a BcProgramUnary function.
40544d4804dSStefan Eßer  * @param r  The BcResult to store the result into.
40644d4804dSStefan Eßer  * @param n  The parameter to the unary operation.
40744d4804dSStefan Eßer  */
40878bc019dSStefan Eßer void
40978bc019dSStefan Eßer bc_program_not(BcResult* r, BcNum* n);
41044d4804dSStefan Eßer 
411252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH
41244d4804dSStefan Eßer 
41344d4804dSStefan Eßer /**
41444d4804dSStefan Eßer  * Truncates a copy of a BcNum. This is a BcProgramUnary function.
41544d4804dSStefan Eßer  * @param r  The BcResult to store the result into.
41644d4804dSStefan Eßer  * @param n  The parameter to the unary operation.
41744d4804dSStefan Eßer  */
41878bc019dSStefan Eßer void
41978bc019dSStefan Eßer bc_program_trunc(BcResult* r, BcNum* n);
42078bc019dSStefan Eßer 
42178bc019dSStefan Eßer /**
42278bc019dSStefan Eßer  * Assigns a value to the seed builtin variable.
42378bc019dSStefan Eßer  * @param p    The program.
42478bc019dSStefan Eßer  * @param val  The value to assign to the seed.
42578bc019dSStefan Eßer  */
42678bc019dSStefan Eßer void
42778bc019dSStefan Eßer bc_program_assignSeed(BcProgram* p, BcNum* val);
42844d4804dSStefan Eßer 
429252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
430252884aeSStefan Eßer 
43178bc019dSStefan Eßer /**
43278bc019dSStefan Eßer  * Assigns a value to a builtin value that is not seed.
43378bc019dSStefan Eßer  * @param p      The program.
43478bc019dSStefan Eßer  * @param scale  True if the builtin is scale.
43578bc019dSStefan Eßer  * @param obase  True if the builtin is obase. This cannot be true at the same
43678bc019dSStefan Eßer  *               time @a scale is.
43778bc019dSStefan Eßer  * @param val    The value to assign to the builtin.
43878bc019dSStefan Eßer  */
43978bc019dSStefan Eßer void
44078bc019dSStefan Eßer bc_program_assignBuiltin(BcProgram* p, bool scale, bool obase, BcBigDig val);
44178bc019dSStefan Eßer 
44244d4804dSStefan Eßer /// A reference to an array of binary operator functions.
443252884aeSStefan Eßer extern const BcNumBinaryOp bc_program_ops[];
44444d4804dSStefan Eßer 
44544d4804dSStefan Eßer /// A reference to an array of binary operator allocation request functions.
446252884aeSStefan Eßer extern const BcNumBinaryOpReq bc_program_opReqs[];
44744d4804dSStefan Eßer 
44844d4804dSStefan Eßer /// A reference to an array of unary operator functions.
449252884aeSStefan Eßer extern const BcProgramUnary bc_program_unarys[];
45044d4804dSStefan Eßer 
45144d4804dSStefan Eßer /// A reference to a filename for command-line expressions.
452252884aeSStefan Eßer extern const char bc_program_exprs_name[];
45344d4804dSStefan Eßer 
45444d4804dSStefan Eßer /// A reference to a filename for stdin.
455252884aeSStefan Eßer extern const char bc_program_stdin_name[];
45644d4804dSStefan Eßer 
45744d4804dSStefan Eßer /// A reference to the ready message printed on SIGINT.
458252884aeSStefan Eßer extern const char bc_program_ready_msg[];
45944d4804dSStefan Eßer 
46044d4804dSStefan Eßer /// A reference to the length of the ready message.
461252884aeSStefan Eßer extern const size_t bc_program_ready_msg_len;
46244d4804dSStefan Eßer 
46344d4804dSStefan Eßer /// A reference to an array of escape characters for the print statement.
464252884aeSStefan Eßer extern const char bc_program_esc_chars[];
46544d4804dSStefan Eßer 
46644d4804dSStefan Eßer /// A reference to an array of the characters corresponding to the escape
46744d4804dSStefan Eßer /// characters in bc_program_esc_chars.
468252884aeSStefan Eßer extern const char bc_program_esc_seqs[];
469252884aeSStefan Eßer 
47044d4804dSStefan Eßer #if BC_HAS_COMPUTED_GOTO
47144d4804dSStefan Eßer 
47244d4804dSStefan Eßer #if BC_DEBUG_CODE
47344d4804dSStefan Eßer 
47478bc019dSStefan Eßer // clang-format off
47544d4804dSStefan Eßer #define BC_PROG_JUMP(inst, code, ip)                                  \
47678bc019dSStefan Eßer 	do                                                                \
47778bc019dSStefan Eßer 	{                                                                 \
47844d4804dSStefan Eßer 		inst = (uchar) (code)[(ip)->idx++];                           \
479d101cdd6SStefan Eßer 		bc_file_printf(&vm->ferr, "inst: %s\n", bc_inst_names[inst]); \
480d101cdd6SStefan Eßer 		bc_file_flush(&vm->ferr, bc_flush_none);                      \
48144d4804dSStefan Eßer 		goto *bc_program_inst_lbls[inst];                             \
48278bc019dSStefan Eßer 	}                                                                 \
48378bc019dSStefan Eßer 	while (0)
48478bc019dSStefan Eßer // clang-format on
48544d4804dSStefan Eßer 
48644d4804dSStefan Eßer #else // BC_DEBUG_CODE
48744d4804dSStefan Eßer 
48878bc019dSStefan Eßer // clang-format off
48944d4804dSStefan Eßer #define BC_PROG_JUMP(inst, code, ip)        \
49078bc019dSStefan Eßer 	do                                      \
49178bc019dSStefan Eßer 	{                                       \
49244d4804dSStefan Eßer 		inst = (uchar) (code)[(ip)->idx++]; \
49344d4804dSStefan Eßer 		goto *bc_program_inst_lbls[inst];   \
49478bc019dSStefan Eßer 	}                                       \
49578bc019dSStefan Eßer 	while (0)
49678bc019dSStefan Eßer // clang-format on
49744d4804dSStefan Eßer 
49844d4804dSStefan Eßer #endif // BC_DEBUG_CODE
49944d4804dSStefan Eßer 
50044d4804dSStefan Eßer #define BC_PROG_DIRECT_JUMP(l) goto lbl_##l;
50144d4804dSStefan Eßer #define BC_PROG_LBL(l) lbl_##l
50244d4804dSStefan Eßer #define BC_PROG_FALLTHROUGH
50344d4804dSStefan Eßer 
50444d4804dSStefan Eßer #if BC_C11
50544d4804dSStefan Eßer 
50644d4804dSStefan Eßer #define BC_PROG_LBLS_SIZE (sizeof(bc_program_inst_lbls) / sizeof(void*))
50744d4804dSStefan Eßer #define BC_PROG_LBLS_ASSERT                                  \
50878bc019dSStefan Eßer 	_Static_assert(BC_PROG_LBLS_SIZE == BC_INST_INVALID + 1, \
50944d4804dSStefan Eßer 	               "bc_program_inst_lbls[] mismatches the instructions")
51044d4804dSStefan Eßer 
51144d4804dSStefan Eßer #else // BC_C11
51244d4804dSStefan Eßer 
51344d4804dSStefan Eßer #define BC_PROG_LBLS_ASSERT
51444d4804dSStefan Eßer 
51544d4804dSStefan Eßer #endif // BC_C11
51644d4804dSStefan Eßer 
51744d4804dSStefan Eßer #if BC_ENABLED
51844d4804dSStefan Eßer 
51944d4804dSStefan Eßer #if DC_ENABLED
52044d4804dSStefan Eßer 
52144d4804dSStefan Eßer #if BC_ENABLE_EXTRA_MATH
52244d4804dSStefan Eßer 
52378bc019dSStefan Eßer #define BC_PROG_LBLS                                    \
52478bc019dSStefan Eßer 	static const void* const bc_program_inst_lbls[] = { \
52544d4804dSStefan Eßer 		&&lbl_BC_INST_INC,                              \
52644d4804dSStefan Eßer 		&&lbl_BC_INST_DEC,                              \
52744d4804dSStefan Eßer 		&&lbl_BC_INST_NEG,                              \
52844d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_NOT,                         \
52944d4804dSStefan Eßer 		&&lbl_BC_INST_TRUNC,                            \
53044d4804dSStefan Eßer 		&&lbl_BC_INST_POWER,                            \
53144d4804dSStefan Eßer 		&&lbl_BC_INST_MULTIPLY,                         \
53244d4804dSStefan Eßer 		&&lbl_BC_INST_DIVIDE,                           \
53344d4804dSStefan Eßer 		&&lbl_BC_INST_MODULUS,                          \
53444d4804dSStefan Eßer 		&&lbl_BC_INST_PLUS,                             \
53544d4804dSStefan Eßer 		&&lbl_BC_INST_MINUS,                            \
53644d4804dSStefan Eßer 		&&lbl_BC_INST_PLACES,                           \
53744d4804dSStefan Eßer 		&&lbl_BC_INST_LSHIFT,                           \
53844d4804dSStefan Eßer 		&&lbl_BC_INST_RSHIFT,                           \
53944d4804dSStefan Eßer 		&&lbl_BC_INST_REL_EQ,                           \
54044d4804dSStefan Eßer 		&&lbl_BC_INST_REL_LE,                           \
54144d4804dSStefan Eßer 		&&lbl_BC_INST_REL_GE,                           \
54244d4804dSStefan Eßer 		&&lbl_BC_INST_REL_NE,                           \
54344d4804dSStefan Eßer 		&&lbl_BC_INST_REL_LT,                           \
54444d4804dSStefan Eßer 		&&lbl_BC_INST_REL_GT,                           \
54544d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_OR,                          \
54644d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_AND,                         \
54744d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER,                     \
54844d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
54944d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE,                    \
55044d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS,                   \
55144d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS,                      \
55244d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS,                     \
55344d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLACES,                    \
55444d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_LSHIFT,                    \
55544d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_RSHIFT,                    \
55644d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN,                           \
55744d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
55844d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
55944d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
56044d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
56144d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
56244d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
56344d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLACES_NO_VAL,             \
56444d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL,             \
56544d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL,             \
56644d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL,                    \
56744d4804dSStefan Eßer 		&&lbl_BC_INST_NUM,                              \
56844d4804dSStefan Eßer 		&&lbl_BC_INST_VAR,                              \
56944d4804dSStefan Eßer 		&&lbl_BC_INST_ARRAY_ELEM,                       \
57044d4804dSStefan Eßer 		&&lbl_BC_INST_ARRAY,                            \
57144d4804dSStefan Eßer 		&&lbl_BC_INST_ZERO,                             \
57244d4804dSStefan Eßer 		&&lbl_BC_INST_ONE,                              \
57344d4804dSStefan Eßer 		&&lbl_BC_INST_LAST,                             \
57444d4804dSStefan Eßer 		&&lbl_BC_INST_IBASE,                            \
57544d4804dSStefan Eßer 		&&lbl_BC_INST_OBASE,                            \
57644d4804dSStefan Eßer 		&&lbl_BC_INST_SCALE,                            \
57744d4804dSStefan Eßer 		&&lbl_BC_INST_SEED,                             \
57844d4804dSStefan Eßer 		&&lbl_BC_INST_LENGTH,                           \
57944d4804dSStefan Eßer 		&&lbl_BC_INST_SCALE_FUNC,                       \
58044d4804dSStefan Eßer 		&&lbl_BC_INST_SQRT,                             \
58144d4804dSStefan Eßer 		&&lbl_BC_INST_ABS,                              \
582d101cdd6SStefan Eßer 		&&lbl_BC_INST_IS_NUMBER,                        \
583d101cdd6SStefan Eßer 		&&lbl_BC_INST_IS_STRING,                        \
58444d4804dSStefan Eßer 		&&lbl_BC_INST_IRAND,                            \
58544d4804dSStefan Eßer 		&&lbl_BC_INST_ASCIIFY,                          \
58644d4804dSStefan Eßer 		&&lbl_BC_INST_READ,                             \
58744d4804dSStefan Eßer 		&&lbl_BC_INST_RAND,                             \
58844d4804dSStefan Eßer 		&&lbl_BC_INST_MAXIBASE,                         \
58944d4804dSStefan Eßer 		&&lbl_BC_INST_MAXOBASE,                         \
59044d4804dSStefan Eßer 		&&lbl_BC_INST_MAXSCALE,                         \
59144d4804dSStefan Eßer 		&&lbl_BC_INST_MAXRAND,                          \
592d43fa8efSStefan Eßer 		&&lbl_BC_INST_LINE_LENGTH,                      \
593d43fa8efSStefan Eßer 		&&lbl_BC_INST_GLOBAL_STACKS,                    \
594d43fa8efSStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,                     \
59544d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT,                            \
59644d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_POP,                        \
59744d4804dSStefan Eßer 		&&lbl_BC_INST_STR,                              \
59844d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_STR,                        \
59944d4804dSStefan Eßer 		&&lbl_BC_INST_JUMP,                             \
60044d4804dSStefan Eßer 		&&lbl_BC_INST_JUMP_ZERO,                        \
60144d4804dSStefan Eßer 		&&lbl_BC_INST_CALL,                             \
60244d4804dSStefan Eßer 		&&lbl_BC_INST_RET,                              \
60344d4804dSStefan Eßer 		&&lbl_BC_INST_RET0,                             \
60444d4804dSStefan Eßer 		&&lbl_BC_INST_RET_VOID,                         \
60544d4804dSStefan Eßer 		&&lbl_BC_INST_HALT,                             \
60644d4804dSStefan Eßer 		&&lbl_BC_INST_POP,                              \
60744d4804dSStefan Eßer 		&&lbl_BC_INST_SWAP,                             \
60844d4804dSStefan Eßer 		&&lbl_BC_INST_MODEXP,                           \
60944d4804dSStefan Eßer 		&&lbl_BC_INST_DIVMOD,                           \
61044d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,                     \
611103d7cdfSStefan Eßer 		&&lbl_BC_INST_EXTENDED_REGISTERS,               \
61244d4804dSStefan Eßer 		&&lbl_BC_INST_POP_EXEC,                         \
61344d4804dSStefan Eßer 		&&lbl_BC_INST_EXECUTE,                          \
61444d4804dSStefan Eßer 		&&lbl_BC_INST_EXEC_COND,                        \
61544d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_STACK,                      \
61644d4804dSStefan Eßer 		&&lbl_BC_INST_CLEAR_STACK,                      \
61744d4804dSStefan Eßer 		&&lbl_BC_INST_REG_STACK_LEN,                    \
61844d4804dSStefan Eßer 		&&lbl_BC_INST_STACK_LEN,                        \
61944d4804dSStefan Eßer 		&&lbl_BC_INST_DUPLICATE,                        \
62044d4804dSStefan Eßer 		&&lbl_BC_INST_LOAD,                             \
62144d4804dSStefan Eßer 		&&lbl_BC_INST_PUSH_VAR,                         \
62244d4804dSStefan Eßer 		&&lbl_BC_INST_PUSH_TO_VAR,                      \
62344d4804dSStefan Eßer 		&&lbl_BC_INST_QUIT,                             \
62444d4804dSStefan Eßer 		&&lbl_BC_INST_NQUIT,                            \
62544d4804dSStefan Eßer 		&&lbl_BC_INST_EXEC_STACK_LEN,                   \
62644d4804dSStefan Eßer 		&&lbl_BC_INST_INVALID,                          \
62744d4804dSStefan Eßer 	}
62844d4804dSStefan Eßer 
62944d4804dSStefan Eßer #else // BC_ENABLE_EXTRA_MATH
63044d4804dSStefan Eßer 
63178bc019dSStefan Eßer #define BC_PROG_LBLS                                    \
63278bc019dSStefan Eßer 	static const void* const bc_program_inst_lbls[] = { \
63344d4804dSStefan Eßer 		&&lbl_BC_INST_INC,                              \
63444d4804dSStefan Eßer 		&&lbl_BC_INST_DEC,                              \
63544d4804dSStefan Eßer 		&&lbl_BC_INST_NEG,                              \
63644d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_NOT,                         \
63744d4804dSStefan Eßer 		&&lbl_BC_INST_POWER,                            \
63844d4804dSStefan Eßer 		&&lbl_BC_INST_MULTIPLY,                         \
63944d4804dSStefan Eßer 		&&lbl_BC_INST_DIVIDE,                           \
64044d4804dSStefan Eßer 		&&lbl_BC_INST_MODULUS,                          \
64144d4804dSStefan Eßer 		&&lbl_BC_INST_PLUS,                             \
64244d4804dSStefan Eßer 		&&lbl_BC_INST_MINUS,                            \
64344d4804dSStefan Eßer 		&&lbl_BC_INST_REL_EQ,                           \
64444d4804dSStefan Eßer 		&&lbl_BC_INST_REL_LE,                           \
64544d4804dSStefan Eßer 		&&lbl_BC_INST_REL_GE,                           \
64644d4804dSStefan Eßer 		&&lbl_BC_INST_REL_NE,                           \
64744d4804dSStefan Eßer 		&&lbl_BC_INST_REL_LT,                           \
64844d4804dSStefan Eßer 		&&lbl_BC_INST_REL_GT,                           \
64944d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_OR,                          \
65044d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_AND,                         \
65144d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER,                     \
65244d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
65344d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE,                    \
65444d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS,                   \
65544d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS,                      \
65644d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS,                     \
65744d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN,                           \
65844d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
65944d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
66044d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
66144d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
66244d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
66344d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
66444d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL,                    \
66544d4804dSStefan Eßer 		&&lbl_BC_INST_NUM,                              \
66644d4804dSStefan Eßer 		&&lbl_BC_INST_VAR,                              \
66744d4804dSStefan Eßer 		&&lbl_BC_INST_ARRAY_ELEM,                       \
66844d4804dSStefan Eßer 		&&lbl_BC_INST_ARRAY,                            \
66944d4804dSStefan Eßer 		&&lbl_BC_INST_ZERO,                             \
67044d4804dSStefan Eßer 		&&lbl_BC_INST_ONE,                              \
67144d4804dSStefan Eßer 		&&lbl_BC_INST_LAST,                             \
67244d4804dSStefan Eßer 		&&lbl_BC_INST_IBASE,                            \
67344d4804dSStefan Eßer 		&&lbl_BC_INST_OBASE,                            \
67444d4804dSStefan Eßer 		&&lbl_BC_INST_SCALE,                            \
67544d4804dSStefan Eßer 		&&lbl_BC_INST_LENGTH,                           \
67644d4804dSStefan Eßer 		&&lbl_BC_INST_SCALE_FUNC,                       \
67744d4804dSStefan Eßer 		&&lbl_BC_INST_SQRT,                             \
67844d4804dSStefan Eßer 		&&lbl_BC_INST_ABS,                              \
679d101cdd6SStefan Eßer 		&&lbl_BC_INST_IS_NUMBER,                        \
680d101cdd6SStefan Eßer 		&&lbl_BC_INST_IS_STRING,                        \
68144d4804dSStefan Eßer 		&&lbl_BC_INST_ASCIIFY,                          \
68244d4804dSStefan Eßer 		&&lbl_BC_INST_READ,                             \
68344d4804dSStefan Eßer 		&&lbl_BC_INST_MAXIBASE,                         \
68444d4804dSStefan Eßer 		&&lbl_BC_INST_MAXOBASE,                         \
68544d4804dSStefan Eßer 		&&lbl_BC_INST_MAXSCALE,                         \
686d43fa8efSStefan Eßer 		&&lbl_BC_INST_LINE_LENGTH,                      \
687d43fa8efSStefan Eßer 		&&lbl_BC_INST_GLOBAL_STACKS,                    \
688d43fa8efSStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,                     \
68944d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT,                            \
69044d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_POP,                        \
69144d4804dSStefan Eßer 		&&lbl_BC_INST_STR,                              \
69244d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_STR,                        \
69344d4804dSStefan Eßer 		&&lbl_BC_INST_JUMP,                             \
69444d4804dSStefan Eßer 		&&lbl_BC_INST_JUMP_ZERO,                        \
69544d4804dSStefan Eßer 		&&lbl_BC_INST_CALL,                             \
69644d4804dSStefan Eßer 		&&lbl_BC_INST_RET,                              \
69744d4804dSStefan Eßer 		&&lbl_BC_INST_RET0,                             \
69844d4804dSStefan Eßer 		&&lbl_BC_INST_RET_VOID,                         \
69944d4804dSStefan Eßer 		&&lbl_BC_INST_HALT,                             \
70044d4804dSStefan Eßer 		&&lbl_BC_INST_POP,                              \
70144d4804dSStefan Eßer 		&&lbl_BC_INST_SWAP,                             \
70244d4804dSStefan Eßer 		&&lbl_BC_INST_MODEXP,                           \
70344d4804dSStefan Eßer 		&&lbl_BC_INST_DIVMOD,                           \
70444d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,                     \
705103d7cdfSStefan Eßer 		&&lbl_BC_INST_EXTENDED_REGISTERS,               \
70644d4804dSStefan Eßer 		&&lbl_BC_INST_POP_EXEC,                         \
70744d4804dSStefan Eßer 		&&lbl_BC_INST_EXECUTE,                          \
70844d4804dSStefan Eßer 		&&lbl_BC_INST_EXEC_COND,                        \
70944d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_STACK,                      \
71044d4804dSStefan Eßer 		&&lbl_BC_INST_CLEAR_STACK,                      \
71144d4804dSStefan Eßer 		&&lbl_BC_INST_REG_STACK_LEN,                    \
71244d4804dSStefan Eßer 		&&lbl_BC_INST_STACK_LEN,                        \
71344d4804dSStefan Eßer 		&&lbl_BC_INST_DUPLICATE,                        \
71444d4804dSStefan Eßer 		&&lbl_BC_INST_LOAD,                             \
71544d4804dSStefan Eßer 		&&lbl_BC_INST_PUSH_VAR,                         \
71644d4804dSStefan Eßer 		&&lbl_BC_INST_PUSH_TO_VAR,                      \
71744d4804dSStefan Eßer 		&&lbl_BC_INST_QUIT,                             \
71844d4804dSStefan Eßer 		&&lbl_BC_INST_NQUIT,                            \
71944d4804dSStefan Eßer 		&&lbl_BC_INST_EXEC_STACK_LEN,                   \
72044d4804dSStefan Eßer 		&&lbl_BC_INST_INVALID,                          \
72144d4804dSStefan Eßer 	}
72244d4804dSStefan Eßer 
72344d4804dSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
72444d4804dSStefan Eßer 
72544d4804dSStefan Eßer #else // DC_ENABLED
72644d4804dSStefan Eßer 
72744d4804dSStefan Eßer #if BC_ENABLE_EXTRA_MATH
72844d4804dSStefan Eßer 
72978bc019dSStefan Eßer #define BC_PROG_LBLS                                    \
73078bc019dSStefan Eßer 	static const void* const bc_program_inst_lbls[] = { \
73144d4804dSStefan Eßer 		&&lbl_BC_INST_INC,                              \
73244d4804dSStefan Eßer 		&&lbl_BC_INST_DEC,                              \
73344d4804dSStefan Eßer 		&&lbl_BC_INST_NEG,                              \
73444d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_NOT,                         \
73544d4804dSStefan Eßer 		&&lbl_BC_INST_TRUNC,                            \
73644d4804dSStefan Eßer 		&&lbl_BC_INST_POWER,                            \
73744d4804dSStefan Eßer 		&&lbl_BC_INST_MULTIPLY,                         \
73844d4804dSStefan Eßer 		&&lbl_BC_INST_DIVIDE,                           \
73944d4804dSStefan Eßer 		&&lbl_BC_INST_MODULUS,                          \
74044d4804dSStefan Eßer 		&&lbl_BC_INST_PLUS,                             \
74144d4804dSStefan Eßer 		&&lbl_BC_INST_MINUS,                            \
74244d4804dSStefan Eßer 		&&lbl_BC_INST_PLACES,                           \
74344d4804dSStefan Eßer 		&&lbl_BC_INST_LSHIFT,                           \
74444d4804dSStefan Eßer 		&&lbl_BC_INST_RSHIFT,                           \
74544d4804dSStefan Eßer 		&&lbl_BC_INST_REL_EQ,                           \
74644d4804dSStefan Eßer 		&&lbl_BC_INST_REL_LE,                           \
74744d4804dSStefan Eßer 		&&lbl_BC_INST_REL_GE,                           \
74844d4804dSStefan Eßer 		&&lbl_BC_INST_REL_NE,                           \
74944d4804dSStefan Eßer 		&&lbl_BC_INST_REL_LT,                           \
75044d4804dSStefan Eßer 		&&lbl_BC_INST_REL_GT,                           \
75144d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_OR,                          \
75244d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_AND,                         \
75344d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER,                     \
75444d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
75544d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE,                    \
75644d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS,                   \
75744d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS,                      \
75844d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS,                     \
75944d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLACES,                    \
76044d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_LSHIFT,                    \
76144d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_RSHIFT,                    \
76244d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN,                           \
76344d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
76444d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
76544d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
76644d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
76744d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
76844d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
76944d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLACES_NO_VAL,             \
77044d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL,             \
77144d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL,             \
77244d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL,                    \
77344d4804dSStefan Eßer 		&&lbl_BC_INST_NUM,                              \
77444d4804dSStefan Eßer 		&&lbl_BC_INST_VAR,                              \
77544d4804dSStefan Eßer 		&&lbl_BC_INST_ARRAY_ELEM,                       \
77644d4804dSStefan Eßer 		&&lbl_BC_INST_ARRAY,                            \
77744d4804dSStefan Eßer 		&&lbl_BC_INST_ZERO,                             \
77844d4804dSStefan Eßer 		&&lbl_BC_INST_ONE,                              \
77944d4804dSStefan Eßer 		&&lbl_BC_INST_LAST,                             \
78044d4804dSStefan Eßer 		&&lbl_BC_INST_IBASE,                            \
78144d4804dSStefan Eßer 		&&lbl_BC_INST_OBASE,                            \
78244d4804dSStefan Eßer 		&&lbl_BC_INST_SCALE,                            \
78344d4804dSStefan Eßer 		&&lbl_BC_INST_SEED,                             \
78444d4804dSStefan Eßer 		&&lbl_BC_INST_LENGTH,                           \
78544d4804dSStefan Eßer 		&&lbl_BC_INST_SCALE_FUNC,                       \
78644d4804dSStefan Eßer 		&&lbl_BC_INST_SQRT,                             \
78744d4804dSStefan Eßer 		&&lbl_BC_INST_ABS,                              \
788d101cdd6SStefan Eßer 		&&lbl_BC_INST_IS_NUMBER,                        \
789d101cdd6SStefan Eßer 		&&lbl_BC_INST_IS_STRING,                        \
79044d4804dSStefan Eßer 		&&lbl_BC_INST_IRAND,                            \
79144d4804dSStefan Eßer 		&&lbl_BC_INST_ASCIIFY,                          \
79244d4804dSStefan Eßer 		&&lbl_BC_INST_READ,                             \
79344d4804dSStefan Eßer 		&&lbl_BC_INST_RAND,                             \
79444d4804dSStefan Eßer 		&&lbl_BC_INST_MAXIBASE,                         \
79544d4804dSStefan Eßer 		&&lbl_BC_INST_MAXOBASE,                         \
79644d4804dSStefan Eßer 		&&lbl_BC_INST_MAXSCALE,                         \
79744d4804dSStefan Eßer 		&&lbl_BC_INST_MAXRAND,                          \
798d43fa8efSStefan Eßer 		&&lbl_BC_INST_LINE_LENGTH,                      \
799d43fa8efSStefan Eßer 		&&lbl_BC_INST_GLOBAL_STACKS,                    \
800d43fa8efSStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,                     \
80144d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT,                            \
80244d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_POP,                        \
80344d4804dSStefan Eßer 		&&lbl_BC_INST_STR,                              \
80444d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_STR,                        \
80544d4804dSStefan Eßer 		&&lbl_BC_INST_JUMP,                             \
80644d4804dSStefan Eßer 		&&lbl_BC_INST_JUMP_ZERO,                        \
80744d4804dSStefan Eßer 		&&lbl_BC_INST_CALL,                             \
80844d4804dSStefan Eßer 		&&lbl_BC_INST_RET,                              \
80944d4804dSStefan Eßer 		&&lbl_BC_INST_RET0,                             \
81044d4804dSStefan Eßer 		&&lbl_BC_INST_RET_VOID,                         \
81144d4804dSStefan Eßer 		&&lbl_BC_INST_HALT,                             \
81244d4804dSStefan Eßer 		&&lbl_BC_INST_POP,                              \
81344d4804dSStefan Eßer 		&&lbl_BC_INST_SWAP,                             \
81444d4804dSStefan Eßer 		&&lbl_BC_INST_MODEXP,                           \
81544d4804dSStefan Eßer 		&&lbl_BC_INST_DIVMOD,                           \
81644d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,                     \
81744d4804dSStefan Eßer 		&&lbl_BC_INST_INVALID,                          \
81844d4804dSStefan Eßer 	}
81944d4804dSStefan Eßer 
82044d4804dSStefan Eßer #else // BC_ENABLE_EXTRA_MATH
82144d4804dSStefan Eßer 
82278bc019dSStefan Eßer #define BC_PROG_LBLS                                    \
82378bc019dSStefan Eßer 	static const void* const bc_program_inst_lbls[] = { \
82444d4804dSStefan Eßer 		&&lbl_BC_INST_INC,                              \
82544d4804dSStefan Eßer 		&&lbl_BC_INST_DEC,                              \
82644d4804dSStefan Eßer 		&&lbl_BC_INST_NEG,                              \
82744d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_NOT,                         \
82844d4804dSStefan Eßer 		&&lbl_BC_INST_POWER,                            \
82944d4804dSStefan Eßer 		&&lbl_BC_INST_MULTIPLY,                         \
83044d4804dSStefan Eßer 		&&lbl_BC_INST_DIVIDE,                           \
83144d4804dSStefan Eßer 		&&lbl_BC_INST_MODULUS,                          \
83244d4804dSStefan Eßer 		&&lbl_BC_INST_PLUS,                             \
83344d4804dSStefan Eßer 		&&lbl_BC_INST_MINUS,                            \
83444d4804dSStefan Eßer 		&&lbl_BC_INST_REL_EQ,                           \
83544d4804dSStefan Eßer 		&&lbl_BC_INST_REL_LE,                           \
83644d4804dSStefan Eßer 		&&lbl_BC_INST_REL_GE,                           \
83744d4804dSStefan Eßer 		&&lbl_BC_INST_REL_NE,                           \
83844d4804dSStefan Eßer 		&&lbl_BC_INST_REL_LT,                           \
83944d4804dSStefan Eßer 		&&lbl_BC_INST_REL_GT,                           \
84044d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_OR,                          \
84144d4804dSStefan Eßer 		&&lbl_BC_INST_BOOL_AND,                         \
84244d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER,                     \
84344d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY,                  \
84444d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE,                    \
84544d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS,                   \
84644d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS,                      \
84744d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS,                     \
84844d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN,                           \
84944d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_POWER_NO_VAL,              \
85044d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL,           \
85144d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL,             \
85244d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL,            \
85344d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_PLUS_NO_VAL,               \
85444d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_MINUS_NO_VAL,              \
85544d4804dSStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL,                    \
85644d4804dSStefan Eßer 		&&lbl_BC_INST_NUM,                              \
85744d4804dSStefan Eßer 		&&lbl_BC_INST_VAR,                              \
85844d4804dSStefan Eßer 		&&lbl_BC_INST_ARRAY_ELEM,                       \
85944d4804dSStefan Eßer 		&&lbl_BC_INST_ARRAY,                            \
86044d4804dSStefan Eßer 		&&lbl_BC_INST_ZERO,                             \
86144d4804dSStefan Eßer 		&&lbl_BC_INST_ONE,                              \
86244d4804dSStefan Eßer 		&&lbl_BC_INST_LAST,                             \
86344d4804dSStefan Eßer 		&&lbl_BC_INST_IBASE,                            \
86444d4804dSStefan Eßer 		&&lbl_BC_INST_OBASE,                            \
86544d4804dSStefan Eßer 		&&lbl_BC_INST_SCALE,                            \
86644d4804dSStefan Eßer 		&&lbl_BC_INST_LENGTH,                           \
86744d4804dSStefan Eßer 		&&lbl_BC_INST_SCALE_FUNC,                       \
86844d4804dSStefan Eßer 		&&lbl_BC_INST_SQRT,                             \
86944d4804dSStefan Eßer 		&&lbl_BC_INST_ABS,                              \
870d101cdd6SStefan Eßer 		&&lbl_BC_INST_IS_NUMBER,                        \
871d101cdd6SStefan Eßer 		&&lbl_BC_INST_IS_STRING,                        \
87244d4804dSStefan Eßer 		&&lbl_BC_INST_ASCIIFY,                          \
87344d4804dSStefan Eßer 		&&lbl_BC_INST_READ,                             \
87444d4804dSStefan Eßer 		&&lbl_BC_INST_MAXIBASE,                         \
87544d4804dSStefan Eßer 		&&lbl_BC_INST_MAXOBASE,                         \
87644d4804dSStefan Eßer 		&&lbl_BC_INST_MAXSCALE,                         \
877d43fa8efSStefan Eßer 		&&lbl_BC_INST_LINE_LENGTH,                      \
878d43fa8efSStefan Eßer 		&&lbl_BC_INST_GLOBAL_STACKS,                    \
879d43fa8efSStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,                     \
88044d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT,                            \
88144d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_POP,                        \
88244d4804dSStefan Eßer 		&&lbl_BC_INST_STR,                              \
88344d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_STR,                        \
88444d4804dSStefan Eßer 		&&lbl_BC_INST_JUMP,                             \
88544d4804dSStefan Eßer 		&&lbl_BC_INST_JUMP_ZERO,                        \
88644d4804dSStefan Eßer 		&&lbl_BC_INST_CALL,                             \
88744d4804dSStefan Eßer 		&&lbl_BC_INST_RET,                              \
88844d4804dSStefan Eßer 		&&lbl_BC_INST_RET0,                             \
88944d4804dSStefan Eßer 		&&lbl_BC_INST_RET_VOID,                         \
89044d4804dSStefan Eßer 		&&lbl_BC_INST_HALT,                             \
89144d4804dSStefan Eßer 		&&lbl_BC_INST_POP,                              \
89244d4804dSStefan Eßer 		&&lbl_BC_INST_SWAP,                             \
89344d4804dSStefan Eßer 		&&lbl_BC_INST_MODEXP,                           \
89444d4804dSStefan Eßer 		&&lbl_BC_INST_DIVMOD,                           \
89544d4804dSStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,                     \
89644d4804dSStefan Eßer 		&&lbl_BC_INST_INVALID,                          \
89744d4804dSStefan Eßer 	}
89844d4804dSStefan Eßer 
89944d4804dSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
90044d4804dSStefan Eßer 
90144d4804dSStefan Eßer #endif // DC_ENABLED
90244d4804dSStefan Eßer 
90344d4804dSStefan Eßer #else // BC_ENABLED
90444d4804dSStefan Eßer 
90544d4804dSStefan Eßer #if BC_ENABLE_EXTRA_MATH
90644d4804dSStefan Eßer 
90778bc019dSStefan Eßer #define BC_PROG_LBLS                                                   \
90878bc019dSStefan Eßer 	static const void* const bc_program_inst_lbls[] = {                \
909175a4d10SStefan Eßer 		&&lbl_BC_INST_NEG,           &&lbl_BC_INST_BOOL_NOT,           \
910175a4d10SStefan Eßer 		&&lbl_BC_INST_TRUNC,         &&lbl_BC_INST_POWER,              \
911175a4d10SStefan Eßer 		&&lbl_BC_INST_MULTIPLY,      &&lbl_BC_INST_DIVIDE,             \
912175a4d10SStefan Eßer 		&&lbl_BC_INST_MODULUS,       &&lbl_BC_INST_PLUS,               \
913175a4d10SStefan Eßer 		&&lbl_BC_INST_MINUS,         &&lbl_BC_INST_PLACES,             \
914175a4d10SStefan Eßer 		&&lbl_BC_INST_LSHIFT,        &&lbl_BC_INST_RSHIFT,             \
915175a4d10SStefan Eßer 		&&lbl_BC_INST_REL_EQ,        &&lbl_BC_INST_REL_LE,             \
916175a4d10SStefan Eßer 		&&lbl_BC_INST_REL_GE,        &&lbl_BC_INST_REL_NE,             \
917175a4d10SStefan Eßer 		&&lbl_BC_INST_REL_LT,        &&lbl_BC_INST_REL_GT,             \
918175a4d10SStefan Eßer 		&&lbl_BC_INST_BOOL_OR,       &&lbl_BC_INST_BOOL_AND,           \
919175a4d10SStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL, &&lbl_BC_INST_NUM,                \
920175a4d10SStefan Eßer 		&&lbl_BC_INST_VAR,           &&lbl_BC_INST_ARRAY_ELEM,         \
921175a4d10SStefan Eßer 		&&lbl_BC_INST_ARRAY,         &&lbl_BC_INST_ZERO,               \
922175a4d10SStefan Eßer 		&&lbl_BC_INST_ONE,           &&lbl_BC_INST_IBASE,              \
923175a4d10SStefan Eßer 		&&lbl_BC_INST_OBASE,         &&lbl_BC_INST_SCALE,              \
924175a4d10SStefan Eßer 		&&lbl_BC_INST_SEED,          &&lbl_BC_INST_LENGTH,             \
925175a4d10SStefan Eßer 		&&lbl_BC_INST_SCALE_FUNC,    &&lbl_BC_INST_SQRT,               \
926175a4d10SStefan Eßer 		&&lbl_BC_INST_ABS,           &&lbl_BC_INST_IS_NUMBER,          \
927175a4d10SStefan Eßer 		&&lbl_BC_INST_IS_STRING,     &&lbl_BC_INST_IRAND,              \
928175a4d10SStefan Eßer 		&&lbl_BC_INST_ASCIIFY,       &&lbl_BC_INST_READ,               \
929175a4d10SStefan Eßer 		&&lbl_BC_INST_RAND,          &&lbl_BC_INST_MAXIBASE,           \
930175a4d10SStefan Eßer 		&&lbl_BC_INST_MAXOBASE,      &&lbl_BC_INST_MAXSCALE,           \
931175a4d10SStefan Eßer 		&&lbl_BC_INST_MAXRAND,       &&lbl_BC_INST_LINE_LENGTH,        \
932175a4d10SStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,  &&lbl_BC_INST_PRINT,              \
933175a4d10SStefan Eßer 		&&lbl_BC_INST_PRINT_POP,     &&lbl_BC_INST_STR,                \
934175a4d10SStefan Eßer 		&&lbl_BC_INST_POP,           &&lbl_BC_INST_SWAP,               \
935175a4d10SStefan Eßer 		&&lbl_BC_INST_MODEXP,        &&lbl_BC_INST_DIVMOD,             \
936175a4d10SStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,  &&lbl_BC_INST_EXTENDED_REGISTERS, \
937175a4d10SStefan Eßer 		&&lbl_BC_INST_POP_EXEC,      &&lbl_BC_INST_EXECUTE,            \
938175a4d10SStefan Eßer 		&&lbl_BC_INST_EXEC_COND,     &&lbl_BC_INST_PRINT_STACK,        \
939175a4d10SStefan Eßer 		&&lbl_BC_INST_CLEAR_STACK,   &&lbl_BC_INST_REG_STACK_LEN,      \
940175a4d10SStefan Eßer 		&&lbl_BC_INST_STACK_LEN,     &&lbl_BC_INST_DUPLICATE,          \
941175a4d10SStefan Eßer 		&&lbl_BC_INST_LOAD,          &&lbl_BC_INST_PUSH_VAR,           \
942175a4d10SStefan Eßer 		&&lbl_BC_INST_PUSH_TO_VAR,   &&lbl_BC_INST_QUIT,               \
943175a4d10SStefan Eßer 		&&lbl_BC_INST_NQUIT,         &&lbl_BC_INST_EXEC_STACK_LEN,     \
94444d4804dSStefan Eßer 		&&lbl_BC_INST_INVALID,                                         \
94544d4804dSStefan Eßer 	}
94644d4804dSStefan Eßer 
94744d4804dSStefan Eßer #else // BC_ENABLE_EXTRA_MATH
94844d4804dSStefan Eßer 
94978bc019dSStefan Eßer #define BC_PROG_LBLS                                                   \
95078bc019dSStefan Eßer 	static const void* const bc_program_inst_lbls[] = {                \
951175a4d10SStefan Eßer 		&&lbl_BC_INST_NEG,           &&lbl_BC_INST_BOOL_NOT,           \
952175a4d10SStefan Eßer 		&&lbl_BC_INST_POWER,         &&lbl_BC_INST_MULTIPLY,           \
953175a4d10SStefan Eßer 		&&lbl_BC_INST_DIVIDE,        &&lbl_BC_INST_MODULUS,            \
954175a4d10SStefan Eßer 		&&lbl_BC_INST_PLUS,          &&lbl_BC_INST_MINUS,              \
955175a4d10SStefan Eßer 		&&lbl_BC_INST_REL_EQ,        &&lbl_BC_INST_REL_LE,             \
956175a4d10SStefan Eßer 		&&lbl_BC_INST_REL_GE,        &&lbl_BC_INST_REL_NE,             \
957175a4d10SStefan Eßer 		&&lbl_BC_INST_REL_LT,        &&lbl_BC_INST_REL_GT,             \
958175a4d10SStefan Eßer 		&&lbl_BC_INST_BOOL_OR,       &&lbl_BC_INST_BOOL_AND,           \
959175a4d10SStefan Eßer 		&&lbl_BC_INST_ASSIGN_NO_VAL, &&lbl_BC_INST_NUM,                \
960175a4d10SStefan Eßer 		&&lbl_BC_INST_VAR,           &&lbl_BC_INST_ARRAY_ELEM,         \
961175a4d10SStefan Eßer 		&&lbl_BC_INST_ARRAY,         &&lbl_BC_INST_ZERO,               \
962175a4d10SStefan Eßer 		&&lbl_BC_INST_ONE,           &&lbl_BC_INST_IBASE,              \
963175a4d10SStefan Eßer 		&&lbl_BC_INST_OBASE,         &&lbl_BC_INST_SCALE,              \
964175a4d10SStefan Eßer 		&&lbl_BC_INST_LENGTH,        &&lbl_BC_INST_SCALE_FUNC,         \
965175a4d10SStefan Eßer 		&&lbl_BC_INST_SQRT,          &&lbl_BC_INST_ABS,                \
966175a4d10SStefan Eßer 		&&lbl_BC_INST_IS_NUMBER,     &&lbl_BC_INST_IS_STRING,          \
967175a4d10SStefan Eßer 		&&lbl_BC_INST_ASCIIFY,       &&lbl_BC_INST_READ,               \
968175a4d10SStefan Eßer 		&&lbl_BC_INST_MAXIBASE,      &&lbl_BC_INST_MAXOBASE,           \
969175a4d10SStefan Eßer 		&&lbl_BC_INST_MAXSCALE,      &&lbl_BC_INST_LINE_LENGTH,        \
970175a4d10SStefan Eßer 		&&lbl_BC_INST_LEADING_ZERO,  &&lbl_BC_INST_PRINT,              \
971175a4d10SStefan Eßer 		&&lbl_BC_INST_PRINT_POP,     &&lbl_BC_INST_STR,                \
972175a4d10SStefan Eßer 		&&lbl_BC_INST_POP,           &&lbl_BC_INST_SWAP,               \
973175a4d10SStefan Eßer 		&&lbl_BC_INST_MODEXP,        &&lbl_BC_INST_DIVMOD,             \
974175a4d10SStefan Eßer 		&&lbl_BC_INST_PRINT_STREAM,  &&lbl_BC_INST_EXTENDED_REGISTERS, \
975175a4d10SStefan Eßer 		&&lbl_BC_INST_POP_EXEC,      &&lbl_BC_INST_EXECUTE,            \
976175a4d10SStefan Eßer 		&&lbl_BC_INST_EXEC_COND,     &&lbl_BC_INST_PRINT_STACK,        \
977175a4d10SStefan Eßer 		&&lbl_BC_INST_CLEAR_STACK,   &&lbl_BC_INST_REG_STACK_LEN,      \
978175a4d10SStefan Eßer 		&&lbl_BC_INST_STACK_LEN,     &&lbl_BC_INST_DUPLICATE,          \
979175a4d10SStefan Eßer 		&&lbl_BC_INST_LOAD,          &&lbl_BC_INST_PUSH_VAR,           \
980175a4d10SStefan Eßer 		&&lbl_BC_INST_PUSH_TO_VAR,   &&lbl_BC_INST_QUIT,               \
981175a4d10SStefan Eßer 		&&lbl_BC_INST_NQUIT,         &&lbl_BC_INST_EXEC_STACK_LEN,     \
98244d4804dSStefan Eßer 		&&lbl_BC_INST_INVALID,                                         \
98344d4804dSStefan Eßer 	}
98444d4804dSStefan Eßer 
98544d4804dSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
98644d4804dSStefan Eßer 
98744d4804dSStefan Eßer #endif // BC_ENABLED
98844d4804dSStefan Eßer 
98944d4804dSStefan Eßer #else // BC_HAS_COMPUTED_GOTO
99044d4804dSStefan Eßer 
99144d4804dSStefan Eßer #define BC_PROG_JUMP(inst, code, ip) break
99244d4804dSStefan Eßer #define BC_PROG_DIRECT_JUMP(l)
99344d4804dSStefan Eßer #define BC_PROG_LBL(l) case l
99444d4804dSStefan Eßer #define BC_PROG_FALLTHROUGH BC_FALLTHROUGH
99544d4804dSStefan Eßer 
99644d4804dSStefan Eßer #define BC_PROG_LBLS
99744d4804dSStefan Eßer 
99844d4804dSStefan Eßer #endif // BC_HAS_COMPUTED_GOTO
99944d4804dSStefan Eßer 
1000252884aeSStefan Eßer #endif // BC_PROGRAM_H
1001