aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/bc.c37
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
630typedef struct BcOp {
631 char prec;
632 bool left;
633} BcOp;
634
635typedef struct BcParseNext { 630typedef 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.
825static const BcOp bc_parse_ops[] = { 820static 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.
839static const BcParseNext bc_parse_next_expr = 838static 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));