aboutsummaryrefslogtreecommitdiff
path: root/miscutils/bc.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-24 13:20:57 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-24 13:20:57 +0100
commitabf6cf67654425a7ede2f9c18e83f35c48cd67f8 (patch)
tree5306c5df6bac90562e183098a8bb1953a94855b2 /miscutils/bc.c
parent7d9be0bc6dc3efdbaf39810240e47553f9c8b90d (diff)
downloadbusybox-w32-abf6cf67654425a7ede2f9c18e83f35c48cd67f8.tar.gz
busybox-w32-abf6cf67654425a7ede2f9c18e83f35c48cd67f8.tar.bz2
busybox-w32-abf6cf67654425a7ede2f9c18e83f35c48cd67f8.zip
bc: move BC_LEX_OP_INC/DEC to the end of operation LEX constants
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to '')
-rw-r--r--miscutils/bc.c188
1 files changed, 95 insertions, 93 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index b4e9e6cb1..3ae88f1a5 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -251,35 +251,34 @@ typedef enum BcInst {
251 BC_INST_INC_POST, 251 BC_INST_INC_POST,
252 BC_INST_DEC_POST, 252 BC_INST_DEC_POST,
253#endif 253#endif
254 XC_INST_NEG, 254 XC_INST_NEG, // order
255 255
256 XC_INST_POWER, 256 XC_INST_POWER, // should
257 XC_INST_MULTIPLY, 257 XC_INST_MULTIPLY, // match
258 XC_INST_DIVIDE, 258 XC_INST_DIVIDE, // LEX
259 XC_INST_MODULUS, 259 XC_INST_MODULUS, // constants
260 XC_INST_PLUS, 260 XC_INST_PLUS, // for
261 XC_INST_MINUS, 261 XC_INST_MINUS, // these
262 262
263 XC_INST_REL_EQ, 263 XC_INST_REL_EQ, // opeartions
264 XC_INST_REL_LE, 264 XC_INST_REL_LE, // |
265 XC_INST_REL_GE, 265 XC_INST_REL_GE, // |
266 XC_INST_REL_NE, 266 XC_INST_REL_NE, // |
267 XC_INST_REL_LT, 267 XC_INST_REL_LT, // |
268 XC_INST_REL_GT, 268 XC_INST_REL_GT, // |
269 269
270 XC_INST_BOOL_NOT, 270 XC_INST_BOOL_NOT, // |
271 XC_INST_BOOL_OR, 271 XC_INST_BOOL_OR, // |
272 XC_INST_BOOL_AND, 272 XC_INST_BOOL_AND, // |
273
274#if ENABLE_BC 273#if ENABLE_BC
275 BC_INST_ASSIGN_POWER, 274 BC_INST_ASSIGN_POWER, // |
276 BC_INST_ASSIGN_MULTIPLY, 275 BC_INST_ASSIGN_MULTIPLY,// |
277 BC_INST_ASSIGN_DIVIDE, 276 BC_INST_ASSIGN_DIVIDE, // |
278 BC_INST_ASSIGN_MODULUS, 277 BC_INST_ASSIGN_MODULUS, // |
279 BC_INST_ASSIGN_PLUS, 278 BC_INST_ASSIGN_PLUS, // |
280 BC_INST_ASSIGN_MINUS, 279 BC_INST_ASSIGN_MINUS, // |
281#endif 280#endif
282 XC_INST_ASSIGN, 281 XC_INST_ASSIGN, // V
283 282
284 XC_INST_NUM, 283 XC_INST_NUM,
285 XC_INST_VAR, 284 XC_INST_VAR,
@@ -394,37 +393,39 @@ typedef enum BcLexType {
394 XC_LEX_EOF, 393 XC_LEX_EOF,
395 XC_LEX_INVALID, 394 XC_LEX_INVALID,
396 395
396 BC_LEX_1st_op,
397 BC_LEX_NEG = BC_LEX_1st_op, // order
398
399 BC_LEX_OP_POWER, // should
400 BC_LEX_OP_MULTIPLY, // match
401 BC_LEX_OP_DIVIDE, // INST
402 BC_LEX_OP_MODULUS, // constants
403 BC_LEX_OP_PLUS, // for
404 BC_LEX_OP_MINUS, // these
405
406 BC_LEX_OP_REL_EQ, // opeartions
407 BC_LEX_OP_REL_LE, // |
408 BC_LEX_OP_REL_GE, // |
409 BC_LEX_OP_REL_NE, // |
410 BC_LEX_OP_REL_LT, // |
411 BC_LEX_OP_REL_GT, // |
412
413 BC_LEX_OP_BOOL_NOT, // |
414 BC_LEX_OP_BOOL_OR, // |
415 BC_LEX_OP_BOOL_AND, // |
416
417 BC_LEX_OP_ASSIGN_POWER, // |
418 BC_LEX_OP_ASSIGN_MULTIPLY, // |
419 BC_LEX_OP_ASSIGN_DIVIDE, // |
420 BC_LEX_OP_ASSIGN_MODULUS, // |
421 BC_LEX_OP_ASSIGN_PLUS, // |
422 BC_LEX_OP_ASSIGN_MINUS, // |
423
424 BC_LEX_OP_ASSIGN, // V
425
397 BC_LEX_OP_INC, 426 BC_LEX_OP_INC,
398 BC_LEX_OP_DEC, 427 BC_LEX_OP_DEC,
399 428
400 BC_LEX_NEG,
401
402 BC_LEX_OP_POWER,
403 BC_LEX_OP_MULTIPLY,
404 BC_LEX_OP_DIVIDE,
405 BC_LEX_OP_MODULUS,
406 BC_LEX_OP_PLUS,
407 BC_LEX_OP_MINUS,
408
409 BC_LEX_OP_REL_EQ,
410 BC_LEX_OP_REL_LE,
411 BC_LEX_OP_REL_GE,
412 BC_LEX_OP_REL_NE,
413 BC_LEX_OP_REL_LT,
414 BC_LEX_OP_REL_GT,
415
416 BC_LEX_OP_BOOL_NOT,
417 BC_LEX_OP_BOOL_OR,
418 BC_LEX_OP_BOOL_AND,
419
420 BC_LEX_OP_ASSIGN_POWER,
421 BC_LEX_OP_ASSIGN_MULTIPLY,
422 BC_LEX_OP_ASSIGN_DIVIDE,
423 BC_LEX_OP_ASSIGN_MODULUS,
424 BC_LEX_OP_ASSIGN_PLUS,
425 BC_LEX_OP_ASSIGN_MINUS,
426 BC_LEX_OP_ASSIGN,
427
428 BC_LEX_NLINE, 429 BC_LEX_NLINE,
429 BC_LEX_WHITESPACE, 430 BC_LEX_WHITESPACE,
430 431
@@ -565,14 +566,14 @@ enum {
565#define EXBITS(a,b,c,d,e,f,g,h) \ 566#define EXBITS(a,b,c,d,e,f,g,h) \
566 ((uint64_t)((a << 0)+(b << 1)+(c << 2)+(d << 3)+(e << 4)+(f << 5)+(g << 6)+(h << 7))) 567 ((uint64_t)((a << 0)+(b << 1)+(c << 2)+(d << 3)+(e << 4)+(f << 5)+(g << 6)+(h << 7)))
567 BC_PARSE_EXPRS_BITS = 0 // corresponding BC_LEX_xyz: 568 BC_PARSE_EXPRS_BITS = 0 // corresponding BC_LEX_xyz:
568 + (EXBITS(0,0,1,1,1,1,1,1) << (0*8)) // 0: eof inval ++ -- - ^ * / 569 + (EXBITS(0,0,1,1,1,1,1,1) << (0*8)) // 0: eof inval - ^ * / % +
569 + (EXBITS(1,1,1,1,1,1,1,1) << (1*8)) // 8: % + - == <= >= != < 570 + (EXBITS(1,1,1,1,1,1,1,1) << (1*8)) // 8: - == <= >= != < > !
570 + (EXBITS(1,1,1,1,1,1,1,1) << (2*8)) // 16: > ! || && ^= *= /= %= 571 + (EXBITS(1,1,1,1,1,1,1,1) << (2*8)) // 16: || && ^= *= /= %= += -=
571 + (EXBITS(1,1,1,0,0,1,1,0) << (3*8)) // 24: += -= = NL WS ( ) [ 572 + (EXBITS(1,1,1,0,0,1,1,0) << (3*8)) // 24: = ++ -- NL WS ( ) [
572 + (EXBITS(0,0,0,0,0,0,1,1) << (4*8)) // 32: , ] { ; } STR NAME NUM 573 + (EXBITS(0,0,0,0,0,0,1,1) << (4*8)) // 32: , ] { ; } STR NAME NUM
573 + (EXBITS(0,0,0,0,0,0,0,1) << (5*8)) // 40: auto break cont define else for halt ibase 574 + (EXBITS(0,0,0,0,0,0,0,1) << (5*8)) // 40: auto break cont define else for halt ibase
574 + (EXBITS(1,0,1,1,0,0,0,1) << (6*8)) // 48: obase if last length limits print quit read 575 + (EXBITS(1,0,1,1,0,0,0,1) << (6*8)) // 48: obase if last length limits print quit read
575 + (EXBITS(0,1,1,0,0,0,0,0) << (7*8)) // 56: return scale sqrt while 576 + (EXBITS(0,1,1,0,0,0,0,0) << (7*8)) // 56: return scale sqrt while
576#undef EXBITS 577#undef EXBITS
577}; 578};
578static ALWAYS_INLINE long bc_parse_exprs(unsigned i) 579static ALWAYS_INLINE long bc_parse_exprs(unsigned i)
@@ -592,10 +593,9 @@ static ALWAYS_INLINE long bc_parse_exprs(unsigned i)
592} 593}
593 594
594// This is an array of data for operators that correspond to 595// This is an array of data for operators that correspond to
595// [BC_LEX_OP_INC...BC_LEX_OP_ASSIGN] token types. 596// [BC_LEX_1st_op...BC_LEX_last_op] token types.
596static const uint8_t bc_parse_ops[] = { 597static const uint8_t bc_parse_ops[] = {
597#define OP(p,l) ((int)(l) * 0x10 + (p)) 598#define OP(p,l) ((int)(l) * 0x10 + (p))
598 OP(0, false), OP( 0, false ), // inc dec
599 OP(1, false), // neg 599 OP(1, false), // neg
600 OP(2, false), // pow 600 OP(2, false), // pow
601 OP(3, true ), OP( 3, true ), OP( 3, true ), // mul div mod 601 OP(3, true ), OP( 3, true ), OP( 3, true ), // mul div mod
@@ -605,6 +605,7 @@ static const uint8_t bc_parse_ops[] = {
605 OP(7, true ), OP( 7, true ), // or and 605 OP(7, true ), OP( 7, true ), // or and
606 OP(5, false), OP( 5, false ), OP( 5, false ), OP( 5, false ), OP( 5, false ), // ^= *= /= %= += 606 OP(5, false), OP( 5, false ), OP( 5, false ), OP( 5, false ), OP( 5, false ), // ^= *= /= %= +=
607 OP(5, false), OP( 5, false ), // -= = 607 OP(5, false), OP( 5, false ), // -= =
608 OP(0, false), OP( 0, false ), // inc dec
608#undef OP 609#undef OP
609}; 610};
610#define bc_parse_op_PREC(i) (bc_parse_ops[i] & 0x0f) 611#define bc_parse_op_PREC(i) (bc_parse_ops[i] & 0x0f)
@@ -658,29 +659,30 @@ dc_char_to_LEX[] = {
658static const //BcInst - should be this type. Using signed narrow type since DC_INST_INVALID is -1 659static const //BcInst - should be this type. Using signed narrow type since DC_INST_INVALID is -1
659int8_t 660int8_t
660dc_LEX_to_INST[] = { // (so many INVALIDs b/c dc parser does not generate these LEXs) // corresponding BC_LEX_xyz: 661dc_LEX_to_INST[] = { // (so many INVALIDs b/c dc parser does not generate these LEXs) // corresponding BC_LEX_xyz:
661 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, XC_INST_REL_GE, // EOF INVALID OP_INC OP_DEC 662 DC_INST_INVALID, DC_INST_INVALID, // EOF INVALID
662 DC_INST_INVALID, XC_INST_POWER, XC_INST_MULTIPLY, XC_INST_DIVIDE, // NEG OP_POWER OP_MULTIPLY OP_DIVIDE 663 DC_INST_INVALID, XC_INST_POWER, XC_INST_MULTIPLY, XC_INST_DIVIDE, // NEG OP_POWER OP_MULTIPLY OP_DIVIDE
663 XC_INST_MODULUS, XC_INST_PLUS, XC_INST_MINUS, // OP_MODULUS OP_PLUS OP_MINUS 664 XC_INST_MODULUS, XC_INST_PLUS, XC_INST_MINUS, // OP_MODULUS OP_PLUS OP_MINUS
664 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // OP_REL_EQ OP_REL_LE OP_REL_GE OP_REL_NE 665 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // OP_REL_EQ OP_REL_LE OP_REL_GE OP_REL_NE
665 DC_INST_INVALID, DC_INST_INVALID, // OP_REL_LT OP_REL_GT 666 DC_INST_INVALID, DC_INST_INVALID, // OP_REL_LT OP_REL_GT
666 XC_INST_BOOL_NOT, DC_INST_INVALID, DC_INST_INVALID, // OP_BOOL_NOT OP_BOOL_OR OP_BOOL_AND 667 XC_INST_BOOL_NOT, DC_INST_INVALID, DC_INST_INVALID, // OP_BOOL_NOT OP_BOOL_OR OP_BOOL_AND
667 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // OP_ASSIGN_POWER OP_ASSIGN_MULTIPLY OP_ASSIGN_DIVIDE OP_ASSIGN_MODULUS 668 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // OP_ASSIGN_POWER OP_ASSIGN_MULTIPLY OP_ASSIGN_DIVIDE OP_ASSIGN_MODULUS
668 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // OP_ASSIGN_PLUS OP_ASSIGN_MINUS OP_ASSIGN 669 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // OP_ASSIGN_PLUS OP_ASSIGN_MINUS OP_ASSIGN
669 DC_INST_INVALID, DC_INST_INVALID, XC_INST_REL_GT, DC_INST_INVALID, // NLINE WHITESPACE LPAREN RPAREN 670 DC_INST_INVALID, XC_INST_REL_GE, // OP_INC OP_DEC
670 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, XC_INST_REL_GE, // LBRACKET COMMA RBRACKET LBRACE 671 DC_INST_INVALID, DC_INST_INVALID, XC_INST_REL_GT, DC_INST_INVALID, // NLINE WHITESPACE LPAREN RPAREN
671 DC_INST_INVALID, DC_INST_INVALID, // SCOLON RBRACE 672 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, XC_INST_REL_GE, // LBRACKET COMMA RBRACKET LBRACE
672 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // STR NAME NUMBER 673 DC_INST_INVALID, DC_INST_INVALID, // SCOLON RBRACE
673 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // KEY_AUTO KEY_BREAK KEY_CONTINUE KEY_DEFINE 674 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // STR NAME NUMBER
674 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, XC_INST_IBASE, // KEY_ELSE KEY_FOR KEY_HALT KEY_IBASE 675 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // KEY_AUTO KEY_BREAK KEY_CONTINUE KEY_DEFINE
675 XC_INST_OBASE, DC_INST_INVALID, IF_BC(DC_INST_INVALID,) XC_INST_LENGTH,//KEY_OBASE KEY_IF KEY_LAST(bc) KEY_LENGTH 676 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, XC_INST_IBASE, // KEY_ELSE KEY_FOR KEY_HALT KEY_IBASE
676 DC_INST_INVALID, XC_INST_PRINT, DC_INST_QUIT, DC_INST_INVALID, // KEY_LIMITS KEY_PRINT KEY_QUIT KEY_READ 677 XC_INST_OBASE, DC_INST_INVALID, IF_BC(DC_INST_INVALID,) XC_INST_LENGTH,//KEY_OBASE KEY_IF KEY_LAST(bc) KEY_LENGTH
677 DC_INST_INVALID, XC_INST_SCALE, XC_INST_SQRT, DC_INST_INVALID, // KEY_RETURN KEY_SCALE KEY_SQRT KEY_WHILE 678 DC_INST_INVALID, XC_INST_PRINT, DC_INST_QUIT, DC_INST_INVALID, // KEY_LIMITS KEY_PRINT KEY_QUIT KEY_READ
678 XC_INST_REL_EQ, DC_INST_MODEXP, DC_INST_DIVMOD, DC_INST_INVALID, // EQ_NO_REG OP_MODEXP OP_DIVMOD COLON 679 DC_INST_INVALID, XC_INST_SCALE, XC_INST_SQRT, DC_INST_INVALID, // KEY_RETURN KEY_SCALE KEY_SQRT KEY_WHILE
679 DC_INST_INVALID, DC_INST_EXECUTE, DC_INST_PRINT_STACK, DC_INST_CLEAR_STACK, //ELSE EXECUTE PRINT_STACK CLEAR_STACK 680 XC_INST_REL_EQ, DC_INST_MODEXP, DC_INST_DIVMOD, DC_INST_INVALID, // EQ_NO_REG OP_MODEXP OP_DIVMOD COLON
680 DC_INST_STACK_LEN, DC_INST_DUPLICATE, DC_INST_SWAP, XC_INST_POP, // STACK_LEVEL DUPLICATE SWAP POP 681 DC_INST_INVALID, DC_INST_EXECUTE, DC_INST_PRINT_STACK, DC_INST_CLEAR_STACK, //ELSE EXECUTE PRINT_STACK CLEAR_STACK
681 DC_INST_ASCIIFY, DC_INST_PRINT_STREAM, DC_INST_INVALID, DC_INST_INVALID, //ASCIIFY PRINT_STREAM STORE_IBASE STORE_OBASE 682 DC_INST_STACK_LEN, DC_INST_DUPLICATE, DC_INST_SWAP, XC_INST_POP, // STACK_LEVEL DUPLICATE SWAP POP
682 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // STORE_SCALE LOAD LOAD_POP STORE_PUSH 683 DC_INST_ASCIIFY, DC_INST_PRINT_STREAM, DC_INST_INVALID, DC_INST_INVALID, //ASCIIFY PRINT_STREAM STORE_IBASE STORE_OBASE
683 XC_INST_PRINT, DC_INST_NQUIT, XC_INST_SCALE_FUNC, // PRINT_POP NQUIT SCALE_FACTOR 684 DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, DC_INST_INVALID, // STORE_SCALE LOAD LOAD_POP STORE_PUSH
685 XC_INST_PRINT, DC_INST_NQUIT, XC_INST_SCALE_FUNC, // PRINT_POP NQUIT SCALE_FACTOR
684}; 686};
685#endif // ENABLE_DC 687#endif // ENABLE_DC
686 688
@@ -3684,7 +3686,7 @@ static size_t bc_program_addFunc(char *name)
3684// We can calculate the conversion between tokens and exprs by subtracting the 3686// We can calculate the conversion between tokens and exprs by subtracting the
3685// position of the first operator in the lex enum and adding the position of the 3687// position of the first operator in the lex enum and adding the position of the
3686// first in the expr enum. Note: This only works for binary operators. 3688// first in the expr enum. Note: This only works for binary operators.
3687#define BC_TOKEN_2_INST(t) ((char) ((t) - BC_LEX_NEG + XC_INST_NEG)) 3689#define BC_TOKEN_2_INST(t) ((char) ((t) - BC_LEX_OP_POWER + XC_INST_POWER))
3688 3690
3689static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags); 3691static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags);
3690 3692
@@ -3724,14 +3726,14 @@ static BC_STATUS zbc_parse_stmt_allow_NLINE_before(BcParse *p, const char *after
3724static void bc_parse_operator(BcParse *p, BcLexType type, size_t start, 3726static void bc_parse_operator(BcParse *p, BcLexType type, size_t start,
3725 size_t *nexprs) 3727 size_t *nexprs)
3726{ 3728{
3727 char l, r = bc_parse_op_PREC(type - BC_LEX_OP_INC); 3729 char l, r = bc_parse_op_PREC(type - BC_LEX_1st_op);
3728 bool left = bc_parse_op_LEFT(type - BC_LEX_OP_INC); 3730 bool left = bc_parse_op_LEFT(type - BC_LEX_1st_op);
3729 3731
3730 while (p->ops.len > start) { 3732 while (p->ops.len > start) {
3731 BcLexType t = BC_PARSE_TOP_OP(p); 3733 BcLexType t = BC_PARSE_TOP_OP(p);
3732 if (t == BC_LEX_LPAREN) break; 3734 if (t == BC_LEX_LPAREN) break;
3733 3735
3734 l = bc_parse_op_PREC(t - BC_LEX_OP_INC); 3736 l = bc_parse_op_PREC(t - BC_LEX_1st_op);
3735 if (l >= r && (l != r || !left)) break; 3737 if (l >= r && (l != r || !left)) break;
3736 3738
3737 bc_parse_push(p, BC_TOKEN_2_INST(t)); 3739 bc_parse_push(p, BC_TOKEN_2_INST(t));
@@ -3754,7 +3756,7 @@ static BC_STATUS zbc_parse_rightParen(BcParse *p, size_t ops_bgn, size_t *nexs)
3754 bc_parse_push(p, BC_TOKEN_2_INST(top)); 3756 bc_parse_push(p, BC_TOKEN_2_INST(top));
3755 3757
3756 bc_vec_pop(&p->ops); 3758 bc_vec_pop(&p->ops);
3757 *nexs -= top != BC_LEX_OP_BOOL_NOT && top != BC_LEX_NEG; 3759 *nexs -= (top != BC_LEX_OP_BOOL_NOT && top != BC_LEX_NEG);
3758 3760
3759 if (p->ops.len <= ops_bgn) 3761 if (p->ops.len <= ops_bgn)
3760 RETURN_STATUS(bc_error_bad_expression()); 3762 RETURN_STATUS(bc_error_bad_expression());
@@ -4791,7 +4793,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags)
4791 4793
4792 bc_parse_push(p, BC_TOKEN_2_INST(top)); 4794 bc_parse_push(p, BC_TOKEN_2_INST(top));
4793 4795
4794 nexprs -= top != BC_LEX_OP_BOOL_NOT && top != BC_LEX_NEG; 4796 nexprs -= (top != BC_LEX_OP_BOOL_NOT && top != BC_LEX_NEG);
4795 bc_vec_pop(&p->ops); 4797 bc_vec_pop(&p->ops);
4796 } 4798 }
4797 4799