[git commit] bc: code shrink

Denys Vlasenko vda.linux at googlemail.com
Wed Dec 5 19:17:48 UTC 2018


commit: https://git.busybox.net/busybox/commit/?id=bcb62a7f119173f57104ed353d9718c2f9424049
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
bc_parse_expr                                       2151    2178     +27
bc_parse_exprs                                        60       -     -60
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 2/0 up/down: 27/-60)            Total: -33 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 miscutils/bc.c | 54 ++++++++++++++++++++++++++++++++++++------------------
 1 file 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);
 
 #if ENABLE_BC
 
-// This is an array that corresponds to token types. An entry is
+// This is a bit array that corresponds to token types. An entry is
 // true if the token is valid in an expression, false otherwise.
-static const bool bc_parse_exprs[] = {
-	false, false, true, true, true, true, true, true, true, true, true, true,
-	true, true, true, true, true, true, true, true, true, true, true, true,
-	true, true, true, false, false, true, true, false, false, false, false,
-	false, false, false, true, true, false, false, false, false, false, false,
-	false, true, false, true, true, true, true, false, false, true, false, true,
-	true, false,
+enum {
+	BC_PARSE_EXPRS_BITS = 0
+	+ ((uint64_t)((0 << 0)+(0 << 1)+(1 << 2)+(1 << 3)+(1 << 4)+(1 << 5)+(1 << 6)+(1 << 7)) << (0*8))
+	+ ((uint64_t)((1 << 0)+(1 << 1)+(1 << 2)+(1 << 3)+(1 << 4)+(1 << 5)+(1 << 6)+(1 << 7)) << (1*8))
+	+ ((uint64_t)((1 << 0)+(1 << 1)+(1 << 2)+(1 << 3)+(1 << 4)+(1 << 5)+(1 << 6)+(1 << 7)) << (2*8))
+	+ ((uint64_t)((1 << 0)+(1 << 1)+(1 << 2)+(0 << 3)+(0 << 4)+(1 << 5)+(1 << 6)+(0 << 7)) << (3*8))
+	+ ((uint64_t)((0 << 0)+(0 << 1)+(0 << 2)+(0 << 3)+(0 << 4)+(0 << 5)+(1 << 6)+(1 << 7)) << (4*8))
+	+ ((uint64_t)((0 << 0)+(0 << 1)+(0 << 2)+(0 << 3)+(0 << 4)+(0 << 5)+(0 << 6)+(1 << 7)) << (5*8))
+	+ ((uint64_t)((0 << 0)+(1 << 1)+(1 << 2)+(1 << 3)+(1 << 4)+(0 << 5)+(0 << 6)+(1 << 7)) << (6*8))
+	+ ((uint64_t)((0 << 0)+(1 << 1)+(1 << 2)+(0 << 3)                                    ) << (7*8))
 };
+static ALWAYS_INLINE long bc_parse_exprs(unsigned i)
+{
+#if ULONG_MAX > 0xffffffff
+	// 64-bit version (will not work correctly for 32-bit longs!)
+	return BC_PARSE_EXPRS_BITS & (1UL << i);
+#else
+	// 32-bit version
+	unsigned long m = (uint32_t)BC_PARSE_EXPRS_BITS;
+	if (i >= 32) {
+		m = (uint32_t)(BC_PARSE_EXPRS_BITS >> 32);
+		i &= 31;
+	}
+	return m & (1UL << i);
+#endif
+}
 
 // This is an array of data for operators that correspond to token types.
 static const uint8_t bc_parse_ops[] = {
 #define OP(p,l) ((int)(l) * 0x10 + (p))
-	OP(0, false), OP( 0, false ),
-	OP(1, false),
+	OP(0, false), OP( 0, false ), // inc dec
+	OP(1, false), // neg
 	OP(2, false),
-	OP(3, true ), OP( 3, true  ), OP( 3, true  ),
-	OP(4, true ), OP( 4, true  ),
-	OP(6, true ), OP( 6, true  ), OP( 6, true  ), OP( 6, true  ), OP( 6, true  ), OP( 6, true ),
-	OP(1, false),
-	OP(7, true ), OP( 7, true  ),
-	OP(5, false), OP( 5, false ), OP( 5, false ), OP( 5, false ), OP( 5, false ),
-	OP(5, false), OP( 5, false ),
+	OP(3, true ), OP( 3, true  ), OP( 3, true  ), // pow mul div
+	OP(4, true ), OP( 4, true  ), // mod + -
+	OP(6, true ), OP( 6, true  ), OP( 6, true  ), OP( 6, true  ), OP( 6, true  ), OP( 6, true ), // == <= >= != < >
+	OP(1, false), // not
+	OP(7, true ), OP( 7, true  ), // or and
+	OP(5, false), OP( 5, false ), OP( 5, false ), OP( 5, false ), OP( 5, false ), // ^= *= /= %= +=
+	OP(5, false), OP( 5, false ), // -= =
 #undef OP
 };
 #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)
 	paren_expr = rprn = done = get_token = assign = false;
 	bin_last = true;
 
-	for (; !G_interrupt && !s && !done && bc_parse_exprs[t]; t = p->l.t.t) {
+	for (; !G_interrupt && !s && !done && bc_parse_exprs(t); t = p->l.t.t) {
 		switch (t) {
 
 			case BC_LEX_OP_INC:


More information about the busybox-cvs mailing list