


/*




* *****************************************************************************




*




* SPDXLicenseIdentifier: BSD2Clause




*




* Copyright (c) 20182021 Gavin D. Howard and contributors.




*




* Redistribution and use in source and binary forms, with or without




* modification, are permitted provided that the following conditions are met:




*




* * Redistributions of source code must retain the above copyright notice, this




* list of conditions and the following disclaimer.




*




* * Redistributions in binary form must reproduce the above copyright notice,




* this list of conditions and the following disclaimer in the documentation




* and/or other materials provided with the distribution.




*




* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"




* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE




* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE




* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE




* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR




* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF




* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS




* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN




* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)




* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE




* POSSIBILITY OF SUCH DAMAGE.




*




* *****************************************************************************




*




* Definitions for bc programs.




*




*/








#ifndef BC_PROGRAM_H




#define BC_PROGRAM_H








#include <assert.h>




#include <stddef.h>








#include <status.h>




#include <parse.h>




#include <lang.h>




#include <num.h>




#include <rand.h>








/// The index of ibase in the globals array.




#define BC_PROG_GLOBALS_IBASE (0)








/// The index of obase in the globals array.




#define BC_PROG_GLOBALS_OBASE (1)








/// The index of scale in the globals array.




#define BC_PROG_GLOBALS_SCALE (2)








#if BC_ENABLE_EXTRA_MATH








/// The index of the rand max in the maxes array.




#define BC_PROG_MAX_RAND (3)








#endif // BC_ENABLE_EXTRA_MATH








/// The length of the globals array.




#define BC_PROG_GLOBALS_LEN (3 + BC_ENABLE_EXTRA_MATH)








typedef struct BcProgram




{




/// The array of globals values.




BcBigDig globals[BC_PROG_GLOBALS_LEN];








#if BC_ENABLED




/// The array of globals stacks.




BcVec globals_v[BC_PROG_GLOBALS_LEN];




#endif // BC_ENABLED








#if BC_ENABLE_EXTRA_MATH








/// The pseudorandom number generator.




BcRNG rng;








#endif // BC_ENABLE_EXTRA_MATH








/// The results stack.




BcVec results;








/// The execution stack.




BcVec stack;








/// A pointer to the current function's constants.




BcVec* consts;








/// A pointer to the current function's strings.




BcVec* strs;








/// The array of functions.




BcVec fns;








/// The map of functions to go with fns.




BcVec fn_map;








/// The array of variables.




BcVec vars;








/// The map of variables to go with vars.




BcVec var_map;








/// The array of arrays.




BcVec arrs;








/// The map of arrays to go with arrs.




BcVec arr_map;








#if DC_ENABLED








/// A vector of tail calls. These are just integers, which are the number of




/// tail calls that have been executed for each function (string) on the




/// stack for dc. This is to prevent dc from constantly growing memory use




/// because of pushing more and more string executions on the stack.




BcVec tail_calls;








#endif // DC_ENABLED








/// A BcNum that has the proper base for asciify.




BcNum strmb;








// A BcNum to run asciify. This is to prevent GCC longjmp() clobbering




// warnings.




BcNum asciify;








#if BC_ENABLED








/// The last printed value for bc.




BcNum last;








#endif // BC_ENABLED








// The BcDig array for strmb. This uses BC_NUM_LONG_LOG10 because it is used




// in bc_num_ulong2num(), which attempts to realloc, unless it is big




// enough. This is big enough.




BcDig strmb_num[BC_NUM_BIGDIG_LOG10];








} BcProgram;








/**




* Returns true if the stack @a s has at least @a n items, false otherwise.




* @param s The stack to check.




* @param n The number of items the stack must have.




* @return True if @a s has at least @a n items, false otherwise.




*/




#define BC_PROG_STACK(s, n) ((s)>len >= ((size_t) (n)))








/**




* Get a pointer to the top value in a global value stack.




* @param v The global value stack.




* @return A pointer to the top value in @a v.




*/




#define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v))








/**




* Get the top value in a global value stack.




* @param v The global value stack.




* @return The top value in @a v.




*/




#define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v)))








/**




* Returns the current value of ibase.




* @param p The program.




* @return The current ibase.




*/




#define BC_PROG_IBASE(p) ((p)>globals[BC_PROG_GLOBALS_IBASE])








/**




* Returns the current value of obase.




* @param p The program.




* @return The current obase.




*/




#define BC_PROG_OBASE(p) ((p)>globals[BC_PROG_GLOBALS_OBASE])








/**




* Returns the current value of scale.




* @param p The program.




* @return The current scale.




*/




#define BC_PROG_SCALE(p) ((p)>globals[BC_PROG_GLOBALS_SCALE])








/// The index for the main function in the functions array.//




#define BC_PROG_MAIN (0)








/// The index for the read function in the functions array.




#define BC_PROG_READ (1)








/**




* Retires (completes the execution of) an instruction. Some instructions




* require special retirement, but most can use this. This basically pops the




* operands while preserving the result (which we assumed was pushed before the




* actual operation).




* @param p The program.




* @param nres The number of results returned by the instruction.




* @param nops The number of operands used by the instruction.




*/




#define bc_program_retire(p, nres, nops) \




(bc_vec_npopAt(&(p)>results, (nops), (p)>results.len  (nres + nops)))








#if DC_ENABLED








/// A constant that tells how many functions are required in dc.




#define BC_PROG_REQ_FUNCS (2)








#if !BC_ENABLED








/// This define disappears the parameter last because for dc only, last is




/// always true.




#define bc_program_copyToVar(p, name, t, last) \




bc_program_copyToVar_impl(p, name, t)








/// Returns true if the calculator should pop after printing.




#define BC_PROGRAM_POP(pop) (pop)








#else // !BC_ENABLED








// This is here to quiet a compiler warning.




#define bc_program_copyToVar(p, name, t, last) \




bc_program_copyToVar_impl(p, name, t, last)








/// Returns true if the calculator should pop after printing.




#define BC_PROGRAM_POP(pop) (BC_IS_BC  (pop))








#endif // !BC_ENABLED








// This is here to satisfy a clang warning about recursive macros.




#define bc_program_pushVar(p, code, bgn, pop, copy) \




bc_program_pushVar_impl(p, code, bgn, pop, copy)








#else // DC_ENABLED








// This define disappears pop and copy because for bc, 'pop' and 'copy' are




// always false.




#define bc_program_pushVar(p, code, bgn, pop, copy) \




bc_program_pushVar_impl(p, code, bgn)








/// Returns true if the calculator should pop after printing.




#define BC_PROGRAM_POP(pop) (BC_IS_BC)








// In debug mode, we want bc to check the stack, but otherwise, we don't because




// the bc language implicitly mandates that the stack should always have enough




// items.




#ifdef NDEBUG




#define BC_PROG_NO_STACK_CHECK




#endif // NDEBUG








#endif // DC_ENABLED








/**




* Returns true if the BcNum @a n is acting as a string.




* @param n The BcNum to test.




* @return True if @a n is acting as a string, false otherwise.




*/




#define BC_PROG_STR(n) ((n)>num == NULL && !(n)>cap)








#if BC_ENABLED








/**




* Returns true if the result @a r and @a n is a number.




* @param r The result.




* @param n The number corresponding to the result.




* @return True if the result holds a number, false otherwise.




*/




#define BC_PROG_NUM(r, n) \




((r)>t != BC_RESULT_ARRAY && (r)>t != BC_RESULT_STR && !BC_PROG_STR(n))








#else // BC_ENABLED








/**




* Returns true if the result @a r and @a n is a number.




* @param r The result.




* @param n The number corresponding to the result.




* @return True if the result holds a number, false otherwise.




*/




#define BC_PROG_NUM(r, n) ((r)>t != BC_RESULT_STR && !BC_PROG_STR(n))








#endif // BC_ENABLED








/**




* This is a function type for unary operations. Currently, these include




* boolean not, negation, and truncation with extra math.




* @param r The BcResult to store the result into.




* @param n The parameter to the unary operation.




*/




typedef void (*BcProgramUnary)(BcResult* r, BcNum* n);








/**




* Initializes the BcProgram.




* @param p The program to initialize.




*/




void




bc_program_init(BcProgram* p);








#ifndef NDEBUG








/**




* Frees a BcProgram. This is only used in debug builds because a BcProgram is




* only freed on program exit, and we don't care about freeing resources on




* exit.




* @param p The program to initialize.




*/




void




bc_program_free(BcProgram* p);








#endif // NDEBUG








#if BC_DEBUG_CODE




#if BC_ENABLED && DC_ENABLED








/**




* Prints the bytecode in a function. This is a debugonly function.




* @param p The program.




*/




void




bc_program_code(const BcProgram* p);








/**




* Prints an instruction. This is a debugonly function.




* @param p The program.




* @param code The bytecode array.




* @param bgn A pointer to the current index. It is also updated to the next




* index.




*/




void




bc_program_printInst(const BcProgram* p, const char* code,




size_t* restrict bgn);








/**




* Prints the stack. This is a debugonly function.




* @param p The program.




*/




void




bc_program_printStackDebug(BcProgram* p);








#endif // BC_ENABLED && DC_ENABLED




#endif // BC_DEBUG_CODE








/**




* Returns the index of the variable or array in their respective arrays.




* @param p The program.




* @param id The BcId of the variable or array.




* @param var True if the search should be for a variable, false for an array.




* @return The index of the variable or array in the correct array.




*/




size_t




bc_program_search(BcProgram* p, const char* id, bool var);








/**




* Adds a string to a function and returns the string's index in the function.




* @param p The program.




* @param str The string to add.




* @param fidx The index of the function to add to.




*/




size_t




bc_program_addString(BcProgram* p, const char* str, size_t fidx);








/**




* Inserts a function into the program and returns the index of the function in




* the fns array.




* @param p The program.




* @param name The name of the function.




* @return The index of the function after insertion.




*/




size_t




bc_program_insertFunc(BcProgram* p, const char* name);








/**




* Resets a program, usually because of resetting after an error.




* @param p The program to reset.




*/




void




bc_program_reset(BcProgram* p);








/**




* Executes bc or dc code in the BcProgram.




* @param p The program.




*/




void




bc_program_exec(BcProgram* p);








/**




* Negates a copy of a BcNum. This is a BcProgramUnary function.




* @param r The BcResult to store the result into.




* @param n The parameter to the unary operation.




*/




void




bc_program_negate(BcResult* r, BcNum* n);








/**




* Returns a boolean not of a BcNum. This is a BcProgramUnary function.




* @param r The BcResult to store the result into.




* @param n The parameter to the unary operation.




*/




void




bc_program_not(BcResult* r, BcNum* n);








#if BC_ENABLE_EXTRA_MATH








/**




* Truncates a copy of a BcNum. This is a BcProgramUnary function.




* @param r The BcResult to store the result into.




* @param n The parameter to the unary operation.




*/




void




bc_program_trunc(BcResult* r, BcNum* n);








/**




* Assigns a value to the seed builtin variable.




* @param p The program.




* @param val The value to assign to the seed.




*/




void




bc_program_assignSeed(BcProgram* p, BcNum* val);








#endif // BC_ENABLE_EXTRA_MATH








/**




* Assigns a value to a builtin value that is not seed.




* @param p The program.




* @param scale True if the builtin is scale.




* @param obase True if the builtin is obase. This cannot be true at the same




* time @a scale is.




* @param val The value to assign to the builtin.




*/




void




bc_program_assignBuiltin(BcProgram* p, bool scale, bool obase, BcBigDig val);








/// A reference to an array of binary operator functions.




extern const BcNumBinaryOp bc_program_ops[];








/// A reference to an array of binary operator allocation request functions.




extern const BcNumBinaryOpReq bc_program_opReqs[];








/// A reference to an array of unary operator functions.




extern const BcProgramUnary bc_program_unarys[];








/// A reference to a filename for commandline expressions.




extern const char bc_program_exprs_name[];








/// A reference to a filename for stdin.




extern const char bc_program_stdin_name[];








/// A reference to the ready message printed on SIGINT.




extern const char bc_program_ready_msg[];








/// A reference to the length of the ready message.




extern const size_t bc_program_ready_msg_len;








/// A reference to an array of escape characters for the print statement.




extern const char bc_program_esc_chars[];








/// A reference to an array of the characters corresponding to the escape




/// characters in bc_program_esc_chars.




extern const char bc_program_esc_seqs[];








#if BC_HAS_COMPUTED_GOTO








#if BC_DEBUG_CODE








// clangformat off




#define BC_PROG_JUMP(inst, code, ip) \




do \




{ \




inst = (uchar) (code)[(ip)>idx++]; \




bc_file_printf(&vm>ferr, "inst: %s\n", bc_inst_names[inst]); \




bc_file_flush(&vm>ferr, bc_flush_none); \




goto *bc_program_inst_lbls[inst]; \




} \




while (0)




// clangformat on








#else // BC_DEBUG_CODE








// clangformat off




#define BC_PROG_JUMP(inst, code, ip) \




do \




{ \




inst = (uchar) (code)[(ip)>idx++]; \




goto *bc_program_inst_lbls[inst]; \




} \




while (0)




// clangformat on








#endif // BC_DEBUG_CODE








#define BC_PROG_DIRECT_JUMP(l) goto lbl_##l;




#define BC_PROG_LBL(l) lbl_##l




#define BC_PROG_FALLTHROUGH








#if BC_C11








#define BC_PROG_LBLS_SIZE (sizeof(bc_program_inst_lbls) / sizeof(void*))




#define BC_PROG_LBLS_ASSERT \




_Static_assert(BC_PROG_LBLS_SIZE == BC_INST_INVALID + 1, \




"bc_program_inst_lbls[] mismatches the instructions")








#else // BC_C11








#define BC_PROG_LBLS_ASSERT








#endif // BC_C11








#if BC_ENABLED








#if DC_ENABLED








#if BC_ENABLE_EXTRA_MATH








#define BC_PROG_LBLS \




static const void* const bc_program_inst_lbls[] = { \




&&lbl_BC_INST_INC, \




&&lbl_BC_INST_DEC, \




&&lbl_BC_INST_NEG, \




&&lbl_BC_INST_BOOL_NOT, \




&&lbl_BC_INST_TRUNC, \




&&lbl_BC_INST_POWER, \




&&lbl_BC_INST_MULTIPLY, \




&&lbl_BC_INST_DIVIDE, \




&&lbl_BC_INST_MODULUS, \




&&lbl_BC_INST_PLUS, \




&&lbl_BC_INST_MINUS, \




&&lbl_BC_INST_PLACES, \




&&lbl_BC_INST_LSHIFT, \




&&lbl_BC_INST_RSHIFT, \




&&lbl_BC_INST_REL_EQ, \




&&lbl_BC_INST_REL_LE, \




&&lbl_BC_INST_REL_GE, \




&&lbl_BC_INST_REL_NE, \




&&lbl_BC_INST_REL_LT, \




&&lbl_BC_INST_REL_GT, \




&&lbl_BC_INST_BOOL_OR, \




&&lbl_BC_INST_BOOL_AND, \




&&lbl_BC_INST_ASSIGN_POWER, \




&&lbl_BC_INST_ASSIGN_MULTIPLY, \




&&lbl_BC_INST_ASSIGN_DIVIDE, \




&&lbl_BC_INST_ASSIGN_MODULUS, \




&&lbl_BC_INST_ASSIGN_PLUS, \




&&lbl_BC_INST_ASSIGN_MINUS, \




&&lbl_BC_INST_ASSIGN_PLACES, \




&&lbl_BC_INST_ASSIGN_LSHIFT, \




&&lbl_BC_INST_ASSIGN_RSHIFT, \




&&lbl_BC_INST_ASSIGN, \




&&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \




&&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \




&&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \




&&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \




&&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \




&&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \




&&lbl_BC_INST_ASSIGN_PLACES_NO_VAL, \




&&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL, \




&&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL, \




&&lbl_BC_INST_ASSIGN_NO_VAL, \




&&lbl_BC_INST_NUM, \




&&lbl_BC_INST_VAR, \




&&lbl_BC_INST_ARRAY_ELEM, \




&&lbl_BC_INST_ARRAY, \




&&lbl_BC_INST_ZERO, \




&&lbl_BC_INST_ONE, \




&&lbl_BC_INST_LAST, \




&&lbl_BC_INST_IBASE, \




&&lbl_BC_INST_OBASE, \




&&lbl_BC_INST_SCALE, \




&&lbl_BC_INST_SEED, \




&&lbl_BC_INST_LENGTH, \




&&lbl_BC_INST_SCALE_FUNC, \




&&lbl_BC_INST_SQRT, \




&&lbl_BC_INST_ABS, \




&&lbl_BC_INST_IRAND, \




&&lbl_BC_INST_ASCIIFY, \




&&lbl_BC_INST_READ, \




&&lbl_BC_INST_RAND, \




&&lbl_BC_INST_MAXIBASE, \




&&lbl_BC_INST_MAXOBASE, \




&&lbl_BC_INST_MAXSCALE, \




&&lbl_BC_INST_MAXRAND, \




&&lbl_BC_INST_LINE_LENGTH, \




&&lbl_BC_INST_GLOBAL_STACKS, \




&&lbl_BC_INST_LEADING_ZERO, \




&&lbl_BC_INST_PRINT, \




&&lbl_BC_INST_PRINT_POP, \




&&lbl_BC_INST_STR, \




&&lbl_BC_INST_PRINT_STR, \




&&lbl_BC_INST_JUMP, \




&&lbl_BC_INST_JUMP_ZERO, \




&&lbl_BC_INST_CALL, \




&&lbl_BC_INST_RET, \




&&lbl_BC_INST_RET0, \




&&lbl_BC_INST_RET_VOID, \




&&lbl_BC_INST_HALT, \




&&lbl_BC_INST_POP, \




&&lbl_BC_INST_SWAP, \




&&lbl_BC_INST_MODEXP, \




&&lbl_BC_INST_DIVMOD, \




&&lbl_BC_INST_PRINT_STREAM, \




&&lbl_BC_INST_POP_EXEC, \




&&lbl_BC_INST_EXECUTE, \




&&lbl_BC_INST_EXEC_COND, \




&&lbl_BC_INST_PRINT_STACK, \




&&lbl_BC_INST_CLEAR_STACK, \




&&lbl_BC_INST_REG_STACK_LEN, \




&&lbl_BC_INST_STACK_LEN, \




&&lbl_BC_INST_DUPLICATE, \




&&lbl_BC_INST_LOAD, \




&&lbl_BC_INST_PUSH_VAR, \




&&lbl_BC_INST_PUSH_TO_VAR, \




&&lbl_BC_INST_QUIT, \




&&lbl_BC_INST_NQUIT, \




&&lbl_BC_INST_EXEC_STACK_LEN, \




&&lbl_BC_INST_INVALID, \




}








#else // BC_ENABLE_EXTRA_MATH








#define BC_PROG_LBLS \




static const void* const bc_program_inst_lbls[] = { \




&&lbl_BC_INST_INC, \




&&lbl_BC_INST_DEC, \




&&lbl_BC_INST_NEG, \




&&lbl_BC_INST_BOOL_NOT, \




&&lbl_BC_INST_POWER, \




&&lbl_BC_INST_MULTIPLY, \




&&lbl_BC_INST_DIVIDE, \




&&lbl_BC_INST_MODULUS, \




&&lbl_BC_INST_PLUS, \




&&lbl_BC_INST_MINUS, \




&&lbl_BC_INST_REL_EQ, \




&&lbl_BC_INST_REL_LE, \




&&lbl_BC_INST_REL_GE, \




&&lbl_BC_INST_REL_NE, \




&&lbl_BC_INST_REL_LT, \




&&lbl_BC_INST_REL_GT, \




&&lbl_BC_INST_BOOL_OR, \




&&lbl_BC_INST_BOOL_AND, \




&&lbl_BC_INST_ASSIGN_POWER, \




&&lbl_BC_INST_ASSIGN_MULTIPLY, \




&&lbl_BC_INST_ASSIGN_DIVIDE, \




&&lbl_BC_INST_ASSIGN_MODULUS, \




&&lbl_BC_INST_ASSIGN_PLUS, \




&&lbl_BC_INST_ASSIGN_MINUS, \




&&lbl_BC_INST_ASSIGN, \




&&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \




&&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \




&&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \




&&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \




&&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \




&&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \




&&lbl_BC_INST_ASSIGN_NO_VAL, \




&&lbl_BC_INST_NUM, \




&&lbl_BC_INST_VAR, \




&&lbl_BC_INST_ARRAY_ELEM, \




&&lbl_BC_INST_ARRAY, \




&&lbl_BC_INST_ZERO, \




&&lbl_BC_INST_ONE, \




&&lbl_BC_INST_LAST, \




&&lbl_BC_INST_IBASE, \




&&lbl_BC_INST_OBASE, \




&&lbl_BC_INST_SCALE, \




&&lbl_BC_INST_LENGTH, \




&&lbl_BC_INST_SCALE_FUNC, \




&&lbl_BC_INST_SQRT, \




&&lbl_BC_INST_ABS, \




&&lbl_BC_INST_ASCIIFY, \




&&lbl_BC_INST_READ, \




&&lbl_BC_INST_MAXIBASE, \




&&lbl_BC_INST_MAXOBASE, \




&&lbl_BC_INST_MAXSCALE, \




&&lbl_BC_INST_LINE_LENGTH, \




&&lbl_BC_INST_GLOBAL_STACKS, \




&&lbl_BC_INST_LEADING_ZERO, \




&&lbl_BC_INST_PRINT, \




&&lbl_BC_INST_PRINT_POP, \




&&lbl_BC_INST_STR, \




&&lbl_BC_INST_PRINT_STR, \




&&lbl_BC_INST_JUMP, \




&&lbl_BC_INST_JUMP_ZERO, \




&&lbl_BC_INST_CALL, \




&&lbl_BC_INST_RET, \




&&lbl_BC_INST_RET0, \




&&lbl_BC_INST_RET_VOID, \




&&lbl_BC_INST_HALT, \




&&lbl_BC_INST_POP, \




&&lbl_BC_INST_SWAP, \




&&lbl_BC_INST_MODEXP, \




&&lbl_BC_INST_DIVMOD, \




&&lbl_BC_INST_PRINT_STREAM, \




&&lbl_BC_INST_POP_EXEC, \




&&lbl_BC_INST_EXECUTE, \




&&lbl_BC_INST_EXEC_COND, \




&&lbl_BC_INST_PRINT_STACK, \




&&lbl_BC_INST_CLEAR_STACK, \




&&lbl_BC_INST_REG_STACK_LEN, \




&&lbl_BC_INST_STACK_LEN, \




&&lbl_BC_INST_DUPLICATE, \




&&lbl_BC_INST_LOAD, \




&&lbl_BC_INST_PUSH_VAR, \




&&lbl_BC_INST_PUSH_TO_VAR, \




&&lbl_BC_INST_QUIT, \




&&lbl_BC_INST_NQUIT, \




&&lbl_BC_INST_EXEC_STACK_LEN, \




&&lbl_BC_INST_INVALID, \




}








#endif // BC_ENABLE_EXTRA_MATH








#else // DC_ENABLED








#if BC_ENABLE_EXTRA_MATH








#define BC_PROG_LBLS \




static const void* const bc_program_inst_lbls[] = { \




&&lbl_BC_INST_INC, \




&&lbl_BC_INST_DEC, \




&&lbl_BC_INST_NEG, \




&&lbl_BC_INST_BOOL_NOT, \




&&lbl_BC_INST_TRUNC, \




&&lbl_BC_INST_POWER, \




&&lbl_BC_INST_MULTIPLY, \




&&lbl_BC_INST_DIVIDE, \




&&lbl_BC_INST_MODULUS, \




&&lbl_BC_INST_PLUS, \




&&lbl_BC_INST_MINUS, \




&&lbl_BC_INST_PLACES, \




&&lbl_BC_INST_LSHIFT, \




&&lbl_BC_INST_RSHIFT, \




&&lbl_BC_INST_REL_EQ, \




&&lbl_BC_INST_REL_LE, \




&&lbl_BC_INST_REL_GE, \




&&lbl_BC_INST_REL_NE, \




&&lbl_BC_INST_REL_LT, \




&&lbl_BC_INST_REL_GT, \




&&lbl_BC_INST_BOOL_OR, \




&&lbl_BC_INST_BOOL_AND, \




&&lbl_BC_INST_ASSIGN_POWER, \




&&lbl_BC_INST_ASSIGN_MULTIPLY, \




&&lbl_BC_INST_ASSIGN_DIVIDE, \




&&lbl_BC_INST_ASSIGN_MODULUS, \




&&lbl_BC_INST_ASSIGN_PLUS, \




&&lbl_BC_INST_ASSIGN_MINUS, \




&&lbl_BC_INST_ASSIGN_PLACES, \




&&lbl_BC_INST_ASSIGN_LSHIFT, \




&&lbl_BC_INST_ASSIGN_RSHIFT, \




&&lbl_BC_INST_ASSIGN, \




&&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \




&&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \




&&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \




&&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \




&&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \




&&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \




&&lbl_BC_INST_ASSIGN_PLACES_NO_VAL, \




&&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL, \




&&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL, \




&&lbl_BC_INST_ASSIGN_NO_VAL, \




&&lbl_BC_INST_NUM, \




&&lbl_BC_INST_VAR, \




&&lbl_BC_INST_ARRAY_ELEM, \




&&lbl_BC_INST_ARRAY, \




&&lbl_BC_INST_ZERO, \




&&lbl_BC_INST_ONE, \




&&lbl_BC_INST_LAST, \




&&lbl_BC_INST_IBASE, \




&&lbl_BC_INST_OBASE, \




&&lbl_BC_INST_SCALE, \




&&lbl_BC_INST_SEED, \




&&lbl_BC_INST_LENGTH, \

