| /* |
| * ***************************************************************************** |
| * |
| * SPDX-License-Identifier: BSD-2-Clause |
| * |
| * Copyright (c) 2018-2021 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]; |
| |
| /// The array of globals stacks. |
| BcVec globals_v[BC_PROG_GLOBALS_LEN]; |
| |
| #if BC_ENABLE_EXTRA_MATH |
| |
| /// The pseudo-random 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; |
| |
| #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(p, name, t) |
| |
| #endif // !BC_ENABLED |
| |
| #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(p, code, bgn) |
| |
| // 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 debug-only function. |
| * @param p The program. |
| */ |
| void bc_program_code(const BcProgram *p); |
| |
| /** |
| * Prints an instruction. This is a debug-only 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 debug-only 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); |
| |
| #endif // BC_ENABLE_EXTRA_MATH |
| |
| /// 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 command-line 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 |
| |
| #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) |
| |
| #else // BC_DEBUG_CODE |
| |
| #define BC_PROG_JUMP(inst, code, ip) \ |
| do { \ |
| inst = (uchar) (code)[(ip)->idx++]; \ |
| goto *bc_program_inst_lbls[inst]; \ |
| } while (0) |
| |
| #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_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_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, \ |
| &&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_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_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_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_INVALID, \ |
| } |
| |
| #endif // BC_ENABLE_EXTRA_MATH |
| |
| #endif // DC_ENABLED |
| |
| #else // BC_ENABLED |
| |
| #if BC_ENABLE_EXTRA_MATH |
| |
| #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \ |
| &&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_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_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_PRINT, \ |
| &&lbl_BC_INST_PRINT_POP, \ |
| &&lbl_BC_INST_STR, \ |
| &&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_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_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_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_PRINT, \ |
| &&lbl_BC_INST_PRINT_POP, \ |
| &&lbl_BC_INST_STR, \ |
| &&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 |
| |
| #endif // BC_ENABLED |
| |
| #else // BC_HAS_COMPUTED_GOTO |
| |
| #define BC_PROG_JUMP(inst, code, ip) break |
| #define BC_PROG_DIRECT_JUMP(l) |
| #define BC_PROG_LBL(l) case l |
| #define BC_PROG_FALLTHROUGH BC_FALLTHROUGH |
| |
| #define BC_PROG_LBLS |
| |
| #endif // BC_HAS_COMPUTED_GOTO |
| |
| #endif // BC_PROGRAM_H |