aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-30 15:56:36 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-30 15:56:36 +0100
commit2cd8c04632a0e966e7ada16f5e44d1086c65a3a1 (patch)
treea2e86af4f60e8b65d3d30ea0712387638e52569c
parent8ab209f00ebfc9afeeed70bc950817a2567e7389 (diff)
downloadbusybox-w32-2cd8c04632a0e966e7ada16f5e44d1086c65a3a1.tar.gz
busybox-w32-2cd8c04632a0e966e7ada16f5e44d1086c65a3a1.tar.bz2
busybox-w32-2cd8c04632a0e966e7ada16f5e44d1086c65a3a1.zip
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>
-rw-r--r--miscutils/bc.c87
1 files changed, 44 insertions, 43 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 081e48ba8..de6f9aab8 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -4,6 +4,17 @@
4 * Adapted from https://github.com/gavinhoward/bc 4 * Adapted from https://github.com/gavinhoward/bc
5 * Original code copyright (c) 2018 Gavin D. Howard and contributors. 5 * Original code copyright (c) 2018 Gavin D. Howard and contributors.
6 */ 6 */
7//TODO: GNU extensions:
8// support ibase up to 36
9// support "define void f()..."
10// support "define f(*param[])" - "pass array by reference" syntax
11
12#define DEBUG_LEXER 0
13#define DEBUG_COMPILE 0
14#define DEBUG_EXEC 0
15// This can be left enabled for production as well:
16#define SANITY_CHECKS 1
17
7//config:config BC 18//config:config BC
8//config: bool "bc (45 kb)" 19//config: bool "bc (45 kb)"
9//config: default y 20//config: default y
@@ -156,12 +167,6 @@
156# include "dc.c" 167# include "dc.c"
157#else 168#else
158 169
159#define DEBUG_LEXER 0
160#define DEBUG_COMPILE 0
161#define DEBUG_EXEC 0
162// This can be left enabled for production as well:
163#define SANITY_CHECKS 1
164
165#if DEBUG_LEXER 170#if DEBUG_LEXER
166static uint8_t lex_indent; 171static uint8_t lex_indent;
167#define dbg_lex(...) \ 172#define dbg_lex(...) \
@@ -203,8 +208,8 @@ typedef enum BcStatus {
203 BC_STATUS_PARSE_EMPTY_EXP = 2, // bc_parse_expr_empty_ok() uses this 208 BC_STATUS_PARSE_EMPTY_EXP = 2, // bc_parse_expr_empty_ok() uses this
204} BcStatus; 209} BcStatus;
205 210
206#define BC_VEC_INVALID_IDX ((size_t) -1) 211#define BC_VEC_INVALID_IDX ((size_t) -1)
207#define BC_VEC_START_CAP (1 << 5) 212#define BC_VEC_START_CAP (1 << 5)
208 213
209typedef void (*BcVecFree)(void *) FAST_FUNC; 214typedef void (*BcVecFree)(void *) FAST_FUNC;
210 215
@@ -228,10 +233,10 @@ typedef struct BcNum {
228 233
229#define BC_NUM_MAX_IBASE ((unsigned long) 16) 234#define BC_NUM_MAX_IBASE ((unsigned long) 16)
230// larger value might speed up BIGNUM calculations a bit: 235// larger value might speed up BIGNUM calculations a bit:
231#define BC_NUM_DEF_SIZE (16) 236#define BC_NUM_DEF_SIZE 16
232#define BC_NUM_PRINT_WIDTH (69) 237#define BC_NUM_PRINT_WIDTH 69
233 238
234#define BC_NUM_KARATSUBA_LEN (32) 239#define BC_NUM_KARATSUBA_LEN 32
235 240
236typedef enum BcInst { 241typedef enum BcInst {
237#if ENABLE_BC 242#if ENABLE_BC
@@ -441,10 +446,10 @@ typedef enum BcLexType {
441 BC_LEX_KEY_FOR, 446 BC_LEX_KEY_FOR,
442 BC_LEX_KEY_HALT, 447 BC_LEX_KEY_HALT,
443 // code uses "type - BC_LEX_KEY_IBASE + XC_INST_IBASE" construct, 448 // code uses "type - BC_LEX_KEY_IBASE + XC_INST_IBASE" construct,
444 BC_LEX_KEY_IBASE, // relative order should match for: XC_INST_IBASE 449 BC_LEX_KEY_IBASE, // relative order should match for: XC_INST_IBASE
445 BC_LEX_KEY_OBASE, // relative order should match for: XC_INST_OBASE 450 BC_LEX_KEY_OBASE, // relative order should match for: XC_INST_OBASE
446 BC_LEX_KEY_IF, 451 BC_LEX_KEY_IF,
447 IF_BC(BC_LEX_KEY_LAST,) // relative order should match for: BC_INST_LAST 452 BC_LEX_KEY_LAST, // relative order should match for: BC_INST_LAST
448 BC_LEX_KEY_LENGTH, 453 BC_LEX_KEY_LENGTH,
449 BC_LEX_KEY_LIMITS, 454 BC_LEX_KEY_LIMITS,
450 BC_LEX_KEY_PRINT, 455 BC_LEX_KEY_PRINT,
@@ -598,7 +603,7 @@ static ALWAYS_INLINE long lex_allowed_in_bc_expr(unsigned i)
598 603
599// This is an array of data for operators that correspond to 604// This is an array of data for operators that correspond to
600// [XC_LEX_1st_op...] token types. 605// [XC_LEX_1st_op...] token types.
601static const uint8_t bc_parse_ops[] ALIGN1 = { 606static const uint8_t bc_ops_prec_and_assoc[] ALIGN1 = {
602#define OP(p,l) ((int)(l) * 0x10 + (p)) 607#define OP(p,l) ((int)(l) * 0x10 + (p))
603 OP(1, false), // neg 608 OP(1, false), // neg
604 OP(6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), // == <= >= != < > 609 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 = {
612 OP(0, false), OP( 0, false ), // inc dec 617 OP(0, false), OP( 0, false ), // inc dec
613#undef OP 618#undef OP
614}; 619};
615#define bc_parse_op_PREC(i) (bc_parse_ops[i] & 0x0f) 620#define bc_operation_PREC(i) (bc_ops_prec_and_assoc[i] & 0x0f)
616#define bc_parse_op_LEFT(i) (bc_parse_ops[i] & 0x10) 621#define bc_operation_LEFT(i) (bc_ops_prec_and_assoc[i] & 0x10)
617#endif // ENABLE_BC 622#endif // ENABLE_BC
618 623
619#if ENABLE_DC 624#if ENABLE_DC
@@ -798,16 +803,12 @@ struct globals {
798# define BC_PARSE_NOCALL (1 << 3) 803# define BC_PARSE_NOCALL (1 << 3)
799#endif 804#endif
800 805
801#define BC_PROG_MAIN (0) 806#define BC_PROG_MAIN 0
802#define BC_PROG_READ (1) 807#define BC_PROG_READ 1
803#if ENABLE_DC 808#if ENABLE_DC
804#define BC_PROG_REQ_FUNCS (2) 809#define BC_PROG_REQ_FUNCS 2
805#endif 810#endif
806 811
807#define BC_PROG_STR(n) (!(n)->num && !(n)->cap)
808#define BC_PROG_NUM(r, n) \
809 ((r)->t != XC_RESULT_ARRAY && (r)->t != XC_RESULT_STR && !BC_PROG_STR(n))
810
811#define BC_FLAG_W (1 << 0) 812#define BC_FLAG_W (1 << 0)
812#define BC_FLAG_V (1 << 1) 813#define BC_FLAG_V (1 << 1)
813#define BC_FLAG_S (1 << 2) 814#define BC_FLAG_S (1 << 2)
@@ -816,9 +817,6 @@ struct globals {
816#define BC_FLAG_I ((1 << 5) * ENABLE_DC) 817#define BC_FLAG_I ((1 << 5) * ENABLE_DC)
817#define DC_FLAG_X ((1 << 6) * ENABLE_DC) 818#define DC_FLAG_X ((1 << 6) * ENABLE_DC)
818 819
819#define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
820#define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
821
822#define BC_MAX_OBASE ((unsigned) 999) 820#define BC_MAX_OBASE ((unsigned) 999)
823#define BC_MAX_DIM ((unsigned) INT_MAX) 821#define BC_MAX_DIM ((unsigned) INT_MAX)
824#define BC_MAX_SCALE ((unsigned) UINT_MAX) 822#define BC_MAX_SCALE ((unsigned) UINT_MAX)
@@ -884,6 +882,9 @@ struct globals {
884// Utility routines 882// Utility routines
885// 883//
886 884
885#define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
886#define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
887
887static void fflush_and_check(void) 888static void fflush_and_check(void)
888{ 889{
889 fflush_all(); 890 fflush_all();
@@ -3712,14 +3713,14 @@ static BC_STATUS zbc_parse_stmt_allow_NLINE_before(const char *after_X)
3712static void bc_parse_operator(BcLexType type, size_t start, size_t *nexprs) 3713static void bc_parse_operator(BcLexType type, size_t start, size_t *nexprs)
3713{ 3714{
3714 BcParse *p = &G.prs; 3715 BcParse *p = &G.prs;
3715 char l, r = bc_parse_op_PREC(type - XC_LEX_1st_op); 3716 char l, r = bc_operation_PREC(type - XC_LEX_1st_op);
3716 bool left = bc_parse_op_LEFT(type - XC_LEX_1st_op); 3717 bool left = bc_operation_LEFT(type - XC_LEX_1st_op);
3717 3718
3718 while (p->ops.len > start) { 3719 while (p->ops.len > start) {
3719 BcLexType t = BC_PARSE_TOP_OP(p); 3720 BcLexType t = BC_PARSE_TOP_OP(p);
3720 if (t == BC_LEX_LPAREN) break; 3721 if (t == BC_LEX_LPAREN) break;
3721 3722
3722 l = bc_parse_op_PREC(t - XC_LEX_1st_op); 3723 l = bc_operation_PREC(t - XC_LEX_1st_op);
3723 if (l >= r && (l != r || !left)) break; 3724 if (l >= r && (l != r || !left)) break;
3724 3725
3725 xc_parse_push(BC_TOKEN_2_INST(t)); 3726 xc_parse_push(BC_TOKEN_2_INST(t));
@@ -5064,6 +5065,10 @@ static BC_STATUS zdc_parse_exprs_until_eof(void)
5064// Execution engine 5065// Execution engine
5065// 5066//
5066 5067
5068#define BC_PROG_STR(n) (!(n)->num && !(n)->cap)
5069#define BC_PROG_NUM(r, n) \
5070 ((r)->t != XC_RESULT_ARRAY && (r)->t != XC_RESULT_STR && !BC_PROG_STR(n))
5071
5067#define STACK_HAS_MORE_THAN(s, n) ((s)->len > ((size_t)(n))) 5072#define STACK_HAS_MORE_THAN(s, n) ((s)->len > ((size_t)(n)))
5068#define STACK_HAS_EQUAL_OR_MORE_THAN(s, n) ((s)->len >= ((size_t)(n))) 5073#define STACK_HAS_EQUAL_OR_MORE_THAN(s, n) ((s)->len >= ((size_t)(n)))
5069 5074
@@ -6218,8 +6223,8 @@ static BC_STATUS zdc_program_asciify(void)
6218 6223
6219 if (!STACK_HAS_MORE_THAN(&G.prog.results, 0)) 6224 if (!STACK_HAS_MORE_THAN(&G.prog.results, 0))
6220 RETURN_STATUS(bc_error_stack_has_too_few_elements()); 6225 RETURN_STATUS(bc_error_stack_has_too_few_elements());
6221 r = bc_vec_top(&G.prog.results);
6222 6226
6227 r = bc_vec_top(&G.prog.results);
6223 s = zxc_program_num(r, &num); 6228 s = zxc_program_num(r, &num);
6224 if (s) RETURN_STATUS(s); 6229 if (s) RETURN_STATUS(s);
6225 6230
@@ -6235,8 +6240,8 @@ static BC_STATUS zdc_program_asciify(void)
6235 strmb.cap = ARRAY_SIZE(strmb_digs); 6240 strmb.cap = ARRAY_SIZE(strmb_digs);
6236 strmb.num = strmb_digs; 6241 strmb.num = strmb_digs;
6237 bc_num_ulong2num(&strmb, 0x100); 6242 bc_num_ulong2num(&strmb, 0x100);
6238 s = zbc_num_mod(&n, &strmb, &n, 0);
6239 6243
6244 s = zbc_num_mod(&n, &strmb, &n, 0);
6240 if (s) goto num_err; 6245 if (s) goto num_err;
6241 s = zbc_num_ulong(&n, &val); 6246 s = zbc_num_ulong(&n, &val);
6242 if (s) goto num_err; 6247 if (s) goto num_err;
@@ -7188,14 +7193,6 @@ static void xc_program_free(void)
7188 IF_BC(bc_num_free(&G.prog.one);) 7193 IF_BC(bc_num_free(&G.prog.one);)
7189 bc_vec_free(&G.input_buffer); 7194 bc_vec_free(&G.input_buffer);
7190} 7195}
7191
7192static void xc_vm_free(void)
7193{
7194 bc_vec_free(&G.files);
7195 xc_program_free();
7196 xc_parse_free();
7197 free(G.env_args);
7198}
7199#endif 7196#endif
7200 7197
7201static void xc_program_init(void) 7198static void xc_program_init(void)
@@ -7249,12 +7246,12 @@ static void xc_program_init(void)
7249 7246
7250static int xc_vm_init(const char *env_len) 7247static int xc_vm_init(const char *env_len)
7251{ 7248{
7249 G.prog.len = xc_vm_envLen(env_len);
7252#if ENABLE_FEATURE_EDITING 7250#if ENABLE_FEATURE_EDITING
7253 G.line_input_state = new_line_input_t(DO_HISTORY); 7251 G.line_input_state = new_line_input_t(DO_HISTORY);
7254#endif 7252#endif
7255 G.prog.len = xc_vm_envLen(env_len);
7256
7257 bc_vec_init(&G.files, sizeof(char *), NULL); 7253 bc_vec_init(&G.files, sizeof(char *), NULL);
7254
7258 xc_program_init(); 7255 xc_program_init();
7259 IF_BC(if (IS_BC) bc_vm_envArgs();) 7256 IF_BC(if (IS_BC) bc_vm_envArgs();)
7260 xc_parse_create(BC_PROG_MAIN); 7257 xc_parse_create(BC_PROG_MAIN);
@@ -7295,7 +7292,11 @@ static BcStatus xc_vm_run(void)
7295#if ENABLE_FEATURE_CLEAN_UP 7292#if ENABLE_FEATURE_CLEAN_UP
7296 if (G_exiting) // it was actually "halt" or "quit" 7293 if (G_exiting) // it was actually "halt" or "quit"
7297 st = EXIT_SUCCESS; 7294 st = EXIT_SUCCESS;
7298 xc_vm_free(); 7295
7296 bc_vec_free(&G.files);
7297 xc_program_free();
7298 xc_parse_free();
7299 free(G.env_args);
7299# if ENABLE_FEATURE_EDITING 7300# if ENABLE_FEATURE_EDITING
7300 free_line_input_t(G.line_input_state); 7301 free_line_input_t(G.line_input_state);
7301# endif 7302# endif