d43fa8ef53
This version adds options and functions that allow to print numbers in the open interval (-1 .. 1) with or without a leading 0 digit. Additionally, an option has been added to prevent line wrap and allows to print arbitrarily long results on a single line. Merge commit '5d58a51571721190681c50d4bd3a1f45e6282d72'
972 lines
47 KiB
C
972 lines
47 KiB
C
/*
|
|
* *****************************************************************************
|
|
*
|
|
* 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_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, \
|
|
&&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_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_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_LINE_LENGTH, \
|
|
&&lbl_BC_INST_LEADING_ZERO, \
|
|
&&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_LINE_LENGTH, \
|
|
&&lbl_BC_INST_LEADING_ZERO, \
|
|
&&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
|