diff options
-rw-r--r-- | miscutils/bc.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 073a113fb..9a3bc2743 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -627,11 +627,6 @@ typedef struct BcLex { | |||
627 | BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER | BC_PARSE_FLAG_IF | \ | 627 | BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER | BC_PARSE_FLAG_IF | \ |
628 | BC_PARSE_FLAG_ELSE | BC_PARSE_FLAG_IF_END))) | 628 | BC_PARSE_FLAG_ELSE | BC_PARSE_FLAG_IF_END))) |
629 | 629 | ||
630 | typedef struct BcOp { | ||
631 | char prec; | ||
632 | bool left; | ||
633 | } BcOp; | ||
634 | |||
635 | typedef struct BcParseNext { | 630 | typedef struct BcParseNext { |
636 | uint32_t len; | 631 | uint32_t len; |
637 | BcLexType tokens[4]; | 632 | BcLexType tokens[4]; |
@@ -822,18 +817,22 @@ static const bool bc_parse_exprs[] = { | |||
822 | }; | 817 | }; |
823 | 818 | ||
824 | // This is an array of data for operators that correspond to token types. | 819 | // This is an array of data for operators that correspond to token types. |
825 | static const BcOp bc_parse_ops[] = { | 820 | static const uint8_t bc_parse_ops[] = { |
826 | { 0, false }, { 0, false }, | 821 | #define OP(p,l) ((int)(l) * 0x10 + (p)) |
827 | { 1, false }, | 822 | OP(0, false), OP( 0, false ), |
828 | { 2, false }, | 823 | OP(1, false), |
829 | { 3, true }, { 3, true }, { 3, true }, | 824 | OP(2, false), |
830 | { 4, true }, { 4, true }, | 825 | OP(3, true ), OP( 3, true ), OP( 3, true ), |
831 | { 6, true }, { 6, true }, { 6, true }, { 6, true }, { 6, true }, { 6, true }, | 826 | OP(4, true ), OP( 4, true ), |
832 | { 1, false }, | 827 | OP(6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), |
833 | { 7, true }, { 7, true }, | 828 | OP(1, false), |
834 | { 5, false }, { 5, false }, { 5, false }, { 5, false }, { 5, false }, | 829 | OP(7, true ), OP( 7, true ), |
835 | { 5, false }, { 5, false }, | 830 | OP(5, false), OP( 5, false ), OP( 5, false ), OP( 5, false ), OP( 5, false ), |
831 | OP(5, false), OP( 5, false ), | ||
832 | #undef OP | ||
836 | }; | 833 | }; |
834 | #define bc_parse_op_PREC(i) (bc_parse_ops[i] & 0x0f) | ||
835 | #define bc_parse_op_LEFT(i) (bc_parse_ops[i] & 0x10) | ||
837 | 836 | ||
838 | // These identify what tokens can come after expressions in certain cases. | 837 | // These identify what tokens can come after expressions in certain cases. |
839 | static const BcParseNext bc_parse_next_expr = | 838 | static const BcParseNext bc_parse_next_expr = |
@@ -3624,15 +3623,15 @@ static BcStatus bc_parse_operator(BcParse *p, BcLexType type, size_t start, | |||
3624 | { | 3623 | { |
3625 | BcStatus s = BC_STATUS_SUCCESS; | 3624 | BcStatus s = BC_STATUS_SUCCESS; |
3626 | BcLexType t; | 3625 | BcLexType t; |
3627 | char l, r = bc_parse_ops[type - BC_LEX_OP_INC].prec; | 3626 | char l, r = bc_parse_op_PREC(type - BC_LEX_OP_INC); |
3628 | bool left = bc_parse_ops[type - BC_LEX_OP_INC].left; | 3627 | bool left = bc_parse_op_LEFT(type - BC_LEX_OP_INC); |
3629 | 3628 | ||
3630 | while (p->ops.len > start) { | 3629 | while (p->ops.len > start) { |
3631 | 3630 | ||
3632 | t = BC_PARSE_TOP_OP(p); | 3631 | t = BC_PARSE_TOP_OP(p); |
3633 | if (t == BC_LEX_LPAREN) break; | 3632 | if (t == BC_LEX_LPAREN) break; |
3634 | 3633 | ||
3635 | l = bc_parse_ops[t - BC_LEX_OP_INC].prec; | 3634 | l = bc_parse_op_PREC(t - BC_LEX_OP_INC); |
3636 | if (l >= r && (l != r || !left)) break; | 3635 | if (l >= r && (l != r || !left)) break; |
3637 | 3636 | ||
3638 | bc_parse_push(p, BC_PARSE_TOKEN_INST(t)); | 3637 | bc_parse_push(p, BC_PARSE_TOKEN_INST(t)); |