diff options
-rw-r--r-- | miscutils/bc.c | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 9a3bc2743..fbe671fd3 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -805,30 +805,48 @@ static void bc_vm_info(void); | |||
805 | 805 | ||
806 | #if ENABLE_BC | 806 | #if ENABLE_BC |
807 | 807 | ||
808 | // This is an array that corresponds to token types. An entry is | 808 | // This is a bit array that corresponds to token types. An entry is |
809 | // true if the token is valid in an expression, false otherwise. | 809 | // true if the token is valid in an expression, false otherwise. |
810 | static const bool bc_parse_exprs[] = { | 810 | enum { |
811 | false, false, true, true, true, true, true, true, true, true, true, true, | 811 | BC_PARSE_EXPRS_BITS = 0 |
812 | true, true, true, true, true, true, true, true, true, true, true, true, | 812 | + ((uint64_t)((0 << 0)+(0 << 1)+(1 << 2)+(1 << 3)+(1 << 4)+(1 << 5)+(1 << 6)+(1 << 7)) << (0*8)) |
813 | true, true, true, false, false, true, true, false, false, false, false, | 813 | + ((uint64_t)((1 << 0)+(1 << 1)+(1 << 2)+(1 << 3)+(1 << 4)+(1 << 5)+(1 << 6)+(1 << 7)) << (1*8)) |
814 | false, false, false, true, true, false, false, false, false, false, false, | 814 | + ((uint64_t)((1 << 0)+(1 << 1)+(1 << 2)+(1 << 3)+(1 << 4)+(1 << 5)+(1 << 6)+(1 << 7)) << (2*8)) |
815 | false, true, false, true, true, true, true, false, false, true, false, true, | 815 | + ((uint64_t)((1 << 0)+(1 << 1)+(1 << 2)+(0 << 3)+(0 << 4)+(1 << 5)+(1 << 6)+(0 << 7)) << (3*8)) |
816 | true, false, | 816 | + ((uint64_t)((0 << 0)+(0 << 1)+(0 << 2)+(0 << 3)+(0 << 4)+(0 << 5)+(1 << 6)+(1 << 7)) << (4*8)) |
817 | + ((uint64_t)((0 << 0)+(0 << 1)+(0 << 2)+(0 << 3)+(0 << 4)+(0 << 5)+(0 << 6)+(1 << 7)) << (5*8)) | ||
818 | + ((uint64_t)((0 << 0)+(1 << 1)+(1 << 2)+(1 << 3)+(1 << 4)+(0 << 5)+(0 << 6)+(1 << 7)) << (6*8)) | ||
819 | + ((uint64_t)((0 << 0)+(1 << 1)+(1 << 2)+(0 << 3) ) << (7*8)) | ||
817 | }; | 820 | }; |
821 | static ALWAYS_INLINE long bc_parse_exprs(unsigned i) | ||
822 | { | ||
823 | #if ULONG_MAX > 0xffffffff | ||
824 | // 64-bit version (will not work correctly for 32-bit longs!) | ||
825 | return BC_PARSE_EXPRS_BITS & (1UL << i); | ||
826 | #else | ||
827 | // 32-bit version | ||
828 | unsigned long m = (uint32_t)BC_PARSE_EXPRS_BITS; | ||
829 | if (i >= 32) { | ||
830 | m = (uint32_t)(BC_PARSE_EXPRS_BITS >> 32); | ||
831 | i &= 31; | ||
832 | } | ||
833 | return m & (1UL << i); | ||
834 | #endif | ||
835 | } | ||
818 | 836 | ||
819 | // This is an array of data for operators that correspond to token types. | 837 | // This is an array of data for operators that correspond to token types. |
820 | static const uint8_t bc_parse_ops[] = { | 838 | static const uint8_t bc_parse_ops[] = { |
821 | #define OP(p,l) ((int)(l) * 0x10 + (p)) | 839 | #define OP(p,l) ((int)(l) * 0x10 + (p)) |
822 | OP(0, false), OP( 0, false ), | 840 | OP(0, false), OP( 0, false ), // inc dec |
823 | OP(1, false), | 841 | OP(1, false), // neg |
824 | OP(2, false), | 842 | OP(2, false), |
825 | OP(3, true ), OP( 3, true ), OP( 3, true ), | 843 | OP(3, true ), OP( 3, true ), OP( 3, true ), // pow mul div |
826 | OP(4, true ), OP( 4, true ), | 844 | OP(4, true ), OP( 4, true ), // mod + - |
827 | OP(6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), | 845 | OP(6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), OP( 6, true ), // == <= >= != < > |
828 | OP(1, false), | 846 | OP(1, false), // not |
829 | OP(7, true ), OP( 7, true ), | 847 | OP(7, true ), OP( 7, true ), // or and |
830 | OP(5, false), OP( 5, false ), OP( 5, false ), OP( 5, false ), OP( 5, false ), | 848 | OP(5, false), OP( 5, false ), OP( 5, false ), OP( 5, false ), OP( 5, false ), // ^= *= /= %= += |
831 | OP(5, false), OP( 5, false ), | 849 | OP(5, false), OP( 5, false ), // -= = |
832 | #undef OP | 850 | #undef OP |
833 | }; | 851 | }; |
834 | #define bc_parse_op_PREC(i) (bc_parse_ops[i] & 0x0f) | 852 | #define bc_parse_op_PREC(i) (bc_parse_ops[i] & 0x0f) |
@@ -4708,7 +4726,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4708 | paren_expr = rprn = done = get_token = assign = false; | 4726 | paren_expr = rprn = done = get_token = assign = false; |
4709 | bin_last = true; | 4727 | bin_last = true; |
4710 | 4728 | ||
4711 | for (; !G_interrupt && !s && !done && bc_parse_exprs[t]; t = p->l.t.t) { | 4729 | for (; !G_interrupt && !s && !done && bc_parse_exprs(t); t = p->l.t.t) { |
4712 | switch (t) { | 4730 | switch (t) { |
4713 | 4731 | ||
4714 | case BC_LEX_OP_INC: | 4732 | case BC_LEX_OP_INC: |