bc: tidying up, no logic changes
function old new delta bc_ops_prec_and_assoc - 25 +25 xc_vm_init 665 663 -2 bc_parse_ops 25 - -25 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 0/1 up/down: 25/-27) Total: -2 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
8ab209f00e
commit
2cd8c04632
@ -4,6 +4,17 @@
|
|||||||
* Adapted from https://github.com/gavinhoward/bc
|
* Adapted from https://github.com/gavinhoward/bc
|
||||||
* Original code copyright (c) 2018 Gavin D. Howard and contributors.
|
* Original code copyright (c) 2018 Gavin D. Howard and contributors.
|
||||||
*/
|
*/
|
||||||
|
//TODO: GNU extensions:
|
||||||
|
// support ibase up to 36
|
||||||
|
// support "define void f()..."
|
||||||
|
// support "define f(*param[])" - "pass array by reference" syntax
|
||||||
|
|
||||||
|
#define DEBUG_LEXER 0
|
||||||
|
#define DEBUG_COMPILE 0
|
||||||
|
#define DEBUG_EXEC 0
|
||||||
|
// This can be left enabled for production as well:
|
||||||
|
#define SANITY_CHECKS 1
|
||||||
|
|
||||||
//config:config BC
|
//config:config BC
|
||||||
//config: bool "bc (45 kb)"
|
//config: bool "bc (45 kb)"
|
||||||
//config: default y
|
//config: default y
|
||||||
@ -156,12 +167,6 @@
|
|||||||
# include "dc.c"
|
# include "dc.c"
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define DEBUG_LEXER 0
|
|
||||||
#define DEBUG_COMPILE 0
|
|
||||||
#define DEBUG_EXEC 0
|
|
||||||
// This can be left enabled for production as well:
|
|
||||||
#define SANITY_CHECKS 1
|
|
||||||
|
|
||||||
#if DEBUG_LEXER
|
#if DEBUG_LEXER
|
||||||
static uint8_t lex_indent;
|
static uint8_t lex_indent;
|
||||||
#define dbg_lex(...) \
|
#define dbg_lex(...) \
|
||||||
@ -203,8 +208,8 @@ typedef enum BcStatus {
|
|||||||
BC_STATUS_PARSE_EMPTY_EXP = 2, // bc_parse_expr_empty_ok() uses this
|
BC_STATUS_PARSE_EMPTY_EXP = 2, // bc_parse_expr_empty_ok() uses this
|
||||||
} BcStatus;
|
} BcStatus;
|
||||||
|
|
||||||
#define BC_VEC_INVALID_IDX ((size_t) -1)
|
#define BC_VEC_INVALID_IDX ((size_t) -1)
|
||||||
#define BC_VEC_START_CAP (1 << 5)
|
#define BC_VEC_START_CAP (1 << 5)
|
||||||
|
|
||||||
typedef void (*BcVecFree)(void *) FAST_FUNC;
|
typedef void (*BcVecFree)(void *) FAST_FUNC;
|
||||||
|
|
||||||
@ -228,10 +233,10 @@ typedef struct BcNum {
|
|||||||
|
|
||||||
#define BC_NUM_MAX_IBASE ((unsigned long) 16)
|
#define BC_NUM_MAX_IBASE ((unsigned long) 16)
|
||||||
// larger value might speed up BIGNUM calculations a bit:
|
// larger value might speed up BIGNUM calculations a bit:
|
||||||
#define BC_NUM_DEF_SIZE (16)
|
#define BC_NUM_DEF_SIZE 16
|
||||||
#define BC_NUM_PRINT_WIDTH (69)
|
#define BC_NUM_PRINT_WIDTH 69
|
||||||
|
|
||||||
#define BC_NUM_KARATSUBA_LEN (32)
|
#define BC_NUM_KARATSUBA_LEN 32
|
||||||
|
|
||||||
typedef enum BcInst {
|
typedef enum BcInst {
|
||||||
#if ENABLE_BC
|
#if ENABLE_BC
|
||||||
@ -441,10 +446,10 @@ typedef enum BcLexType {
|
|||||||
BC_LEX_KEY_FOR,
|
BC_LEX_KEY_FOR,
|
||||||
BC_LEX_KEY_HALT,
|
BC_LEX_KEY_HALT,
|
||||||
// code uses "type - BC_LEX_KEY_IBASE + XC_INST_IBASE" construct,
|
// code uses "type - BC_LEX_KEY_IBASE + XC_INST_IBASE" construct,
|
||||||
BC_LEX_KEY_IBASE, // relative order should match for: XC_INST_IBASE
|
BC_LEX_KEY_IBASE, // relative order should match for: XC_INST_IBASE
|
||||||
BC_LEX_KEY_OBASE, // relative order should match for: XC_INST_OBASE
|
BC_LEX_KEY_OBASE, // relative order should match for: XC_INST_OBASE
|
||||||
BC_LEX_KEY_IF,
|
BC_LEX_KEY_IF,
|
||||||
IF_BC(BC_LEX_KEY_LAST,) // relative order should match for: BC_INST_LAST
|
BC_LEX_KEY_LAST, // relative order should match for: BC_INST_LAST
|
||||||
BC_LEX_KEY_LENGTH,
|
BC_LEX_KEY_LENGTH,
|
||||||
BC_LEX_KEY_LIMITS,
|
BC_LEX_KEY_LIMITS,
|
||||||
BC_LEX_KEY_PRINT,
|
BC_LEX_KEY_PRINT,
|
||||||
@ -598,7 +603,7 @@ static ALWAYS_INLINE long lex_allowed_in_bc_expr(unsigned i)
|
|||||||
|
|
||||||
// This is an array of data for operators that correspond to
|
// This is an array of data for operators that correspond to
|
||||||
// [XC_LEX_1st_op...] token types.
|
// [XC_LEX_1st_op...] token types.
|
||||||
static const uint8_t bc_parse_ops[] ALIGN1 = {
|
static const uint8_t bc_ops_prec_and_assoc[] ALIGN1 = {
|
||||||
#define OP(p,l) ((int)(l) * 0x10 + (p))
|
#define OP(p,l) ((int)(l) * 0x10 + (p))
|
||||||
OP(1, false), // neg
|
OP(1, false), // neg
|
||||||
OP(6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), // == <= >= != < >
|
OP(6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), // == <= >= != < >
|
||||||
@ -612,8 +617,8 @@ static const uint8_t bc_parse_ops[] ALIGN1 = {
|
|||||||
OP(0, false), OP( 0, false ), // inc dec
|
OP(0, false), OP( 0, false ), // inc dec
|
||||||
#undef OP
|
#undef OP
|
||||||
};
|
};
|
||||||
#define bc_parse_op_PREC(i) (bc_parse_ops[i] & 0x0f)
|
#define bc_operation_PREC(i) (bc_ops_prec_and_assoc[i] & 0x0f)
|
||||||
#define bc_parse_op_LEFT(i) (bc_parse_ops[i] & 0x10)
|
#define bc_operation_LEFT(i) (bc_ops_prec_and_assoc[i] & 0x10)
|
||||||
#endif // ENABLE_BC
|
#endif // ENABLE_BC
|
||||||
|
|
||||||
#if ENABLE_DC
|
#if ENABLE_DC
|
||||||
@ -798,16 +803,12 @@ struct globals {
|
|||||||
# define BC_PARSE_NOCALL (1 << 3)
|
# define BC_PARSE_NOCALL (1 << 3)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BC_PROG_MAIN (0)
|
#define BC_PROG_MAIN 0
|
||||||
#define BC_PROG_READ (1)
|
#define BC_PROG_READ 1
|
||||||
#if ENABLE_DC
|
#if ENABLE_DC
|
||||||
#define BC_PROG_REQ_FUNCS (2)
|
#define BC_PROG_REQ_FUNCS 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BC_PROG_STR(n) (!(n)->num && !(n)->cap)
|
|
||||||
#define BC_PROG_NUM(r, n) \
|
|
||||||
((r)->t != XC_RESULT_ARRAY && (r)->t != XC_RESULT_STR && !BC_PROG_STR(n))
|
|
||||||
|
|
||||||
#define BC_FLAG_W (1 << 0)
|
#define BC_FLAG_W (1 << 0)
|
||||||
#define BC_FLAG_V (1 << 1)
|
#define BC_FLAG_V (1 << 1)
|
||||||
#define BC_FLAG_S (1 << 2)
|
#define BC_FLAG_S (1 << 2)
|
||||||
@ -816,9 +817,6 @@ struct globals {
|
|||||||
#define BC_FLAG_I ((1 << 5) * ENABLE_DC)
|
#define BC_FLAG_I ((1 << 5) * ENABLE_DC)
|
||||||
#define DC_FLAG_X ((1 << 6) * ENABLE_DC)
|
#define DC_FLAG_X ((1 << 6) * ENABLE_DC)
|
||||||
|
|
||||||
#define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
|
|
||||||
#define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
|
|
||||||
#define BC_MAX_OBASE ((unsigned) 999)
|
#define BC_MAX_OBASE ((unsigned) 999)
|
||||||
#define BC_MAX_DIM ((unsigned) INT_MAX)
|
#define BC_MAX_DIM ((unsigned) INT_MAX)
|
||||||
#define BC_MAX_SCALE ((unsigned) UINT_MAX)
|
#define BC_MAX_SCALE ((unsigned) UINT_MAX)
|
||||||
@ -884,6 +882,9 @@ struct globals {
|
|||||||
// Utility routines
|
// Utility routines
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
#define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
static void fflush_and_check(void)
|
static void fflush_and_check(void)
|
||||||
{
|
{
|
||||||
fflush_all();
|
fflush_all();
|
||||||
@ -3712,14 +3713,14 @@ static BC_STATUS zbc_parse_stmt_allow_NLINE_before(const char *after_X)
|
|||||||
static void bc_parse_operator(BcLexType type, size_t start, size_t *nexprs)
|
static void bc_parse_operator(BcLexType type, size_t start, size_t *nexprs)
|
||||||
{
|
{
|
||||||
BcParse *p = &G.prs;
|
BcParse *p = &G.prs;
|
||||||
char l, r = bc_parse_op_PREC(type - XC_LEX_1st_op);
|
char l, r = bc_operation_PREC(type - XC_LEX_1st_op);
|
||||||
bool left = bc_parse_op_LEFT(type - XC_LEX_1st_op);
|
bool left = bc_operation_LEFT(type - XC_LEX_1st_op);
|
||||||
|
|
||||||
while (p->ops.len > start) {
|
while (p->ops.len > start) {
|
||||||
BcLexType t = BC_PARSE_TOP_OP(p);
|
BcLexType t = BC_PARSE_TOP_OP(p);
|
||||||
if (t == BC_LEX_LPAREN) break;
|
if (t == BC_LEX_LPAREN) break;
|
||||||
|
|
||||||
l = bc_parse_op_PREC(t - XC_LEX_1st_op);
|
l = bc_operation_PREC(t - XC_LEX_1st_op);
|
||||||
if (l >= r && (l != r || !left)) break;
|
if (l >= r && (l != r || !left)) break;
|
||||||
|
|
||||||
xc_parse_push(BC_TOKEN_2_INST(t));
|
xc_parse_push(BC_TOKEN_2_INST(t));
|
||||||
@ -5064,6 +5065,10 @@ static BC_STATUS zdc_parse_exprs_until_eof(void)
|
|||||||
// Execution engine
|
// Execution engine
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#define BC_PROG_STR(n) (!(n)->num && !(n)->cap)
|
||||||
|
#define BC_PROG_NUM(r, n) \
|
||||||
|
((r)->t != XC_RESULT_ARRAY && (r)->t != XC_RESULT_STR && !BC_PROG_STR(n))
|
||||||
|
|
||||||
#define STACK_HAS_MORE_THAN(s, n) ((s)->len > ((size_t)(n)))
|
#define STACK_HAS_MORE_THAN(s, n) ((s)->len > ((size_t)(n)))
|
||||||
#define STACK_HAS_EQUAL_OR_MORE_THAN(s, n) ((s)->len >= ((size_t)(n)))
|
#define STACK_HAS_EQUAL_OR_MORE_THAN(s, n) ((s)->len >= ((size_t)(n)))
|
||||||
|
|
||||||
@ -6218,8 +6223,8 @@ static BC_STATUS zdc_program_asciify(void)
|
|||||||
|
|
||||||
if (!STACK_HAS_MORE_THAN(&G.prog.results, 0))
|
if (!STACK_HAS_MORE_THAN(&G.prog.results, 0))
|
||||||
RETURN_STATUS(bc_error_stack_has_too_few_elements());
|
RETURN_STATUS(bc_error_stack_has_too_few_elements());
|
||||||
r = bc_vec_top(&G.prog.results);
|
|
||||||
|
|
||||||
|
r = bc_vec_top(&G.prog.results);
|
||||||
s = zxc_program_num(r, &num);
|
s = zxc_program_num(r, &num);
|
||||||
if (s) RETURN_STATUS(s);
|
if (s) RETURN_STATUS(s);
|
||||||
|
|
||||||
@ -6235,8 +6240,8 @@ static BC_STATUS zdc_program_asciify(void)
|
|||||||
strmb.cap = ARRAY_SIZE(strmb_digs);
|
strmb.cap = ARRAY_SIZE(strmb_digs);
|
||||||
strmb.num = strmb_digs;
|
strmb.num = strmb_digs;
|
||||||
bc_num_ulong2num(&strmb, 0x100);
|
bc_num_ulong2num(&strmb, 0x100);
|
||||||
s = zbc_num_mod(&n, &strmb, &n, 0);
|
|
||||||
|
|
||||||
|
s = zbc_num_mod(&n, &strmb, &n, 0);
|
||||||
if (s) goto num_err;
|
if (s) goto num_err;
|
||||||
s = zbc_num_ulong(&n, &val);
|
s = zbc_num_ulong(&n, &val);
|
||||||
if (s) goto num_err;
|
if (s) goto num_err;
|
||||||
@ -7188,14 +7193,6 @@ static void xc_program_free(void)
|
|||||||
IF_BC(bc_num_free(&G.prog.one);)
|
IF_BC(bc_num_free(&G.prog.one);)
|
||||||
bc_vec_free(&G.input_buffer);
|
bc_vec_free(&G.input_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xc_vm_free(void)
|
|
||||||
{
|
|
||||||
bc_vec_free(&G.files);
|
|
||||||
xc_program_free();
|
|
||||||
xc_parse_free();
|
|
||||||
free(G.env_args);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void xc_program_init(void)
|
static void xc_program_init(void)
|
||||||
@ -7249,12 +7246,12 @@ static void xc_program_init(void)
|
|||||||
|
|
||||||
static int xc_vm_init(const char *env_len)
|
static int xc_vm_init(const char *env_len)
|
||||||
{
|
{
|
||||||
|
G.prog.len = xc_vm_envLen(env_len);
|
||||||
#if ENABLE_FEATURE_EDITING
|
#if ENABLE_FEATURE_EDITING
|
||||||
G.line_input_state = new_line_input_t(DO_HISTORY);
|
G.line_input_state = new_line_input_t(DO_HISTORY);
|
||||||
#endif
|
#endif
|
||||||
G.prog.len = xc_vm_envLen(env_len);
|
|
||||||
|
|
||||||
bc_vec_init(&G.files, sizeof(char *), NULL);
|
bc_vec_init(&G.files, sizeof(char *), NULL);
|
||||||
|
|
||||||
xc_program_init();
|
xc_program_init();
|
||||||
IF_BC(if (IS_BC) bc_vm_envArgs();)
|
IF_BC(if (IS_BC) bc_vm_envArgs();)
|
||||||
xc_parse_create(BC_PROG_MAIN);
|
xc_parse_create(BC_PROG_MAIN);
|
||||||
@ -7295,7 +7292,11 @@ static BcStatus xc_vm_run(void)
|
|||||||
#if ENABLE_FEATURE_CLEAN_UP
|
#if ENABLE_FEATURE_CLEAN_UP
|
||||||
if (G_exiting) // it was actually "halt" or "quit"
|
if (G_exiting) // it was actually "halt" or "quit"
|
||||||
st = EXIT_SUCCESS;
|
st = EXIT_SUCCESS;
|
||||||
xc_vm_free();
|
|
||||||
|
bc_vec_free(&G.files);
|
||||||
|
xc_program_free();
|
||||||
|
xc_parse_free();
|
||||||
|
free(G.env_args);
|
||||||
# if ENABLE_FEATURE_EDITING
|
# if ENABLE_FEATURE_EDITING
|
||||||
free_line_input_t(G.line_input_state);
|
free_line_input_t(G.line_input_state);
|
||||||
# endif
|
# endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user