diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-07 12:57:32 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-07 12:57:32 +0100 |
commit | 18c6b54f820923549135724fee6cf66c26929b07 (patch) | |
tree | 60030a7234fd7e5d6eed7e1093a263bfe1c55e09 | |
parent | b9c321d6d94fc8bbae5fe657e141cbd9f2397037 (diff) | |
download | busybox-w32-18c6b54f820923549135724fee6cf66c26929b07.tar.gz busybox-w32-18c6b54f820923549135724fee6cf66c26929b07.tar.bz2 busybox-w32-18c6b54f820923549135724fee6cf66c26929b07.zip |
bc: use more compact parsing data structures
function old new delta
dc_lex_token 697 701 +4
bc_parse_next_rel 20 - -20
bc_parse_next_read 20 - -20
bc_parse_next_print 20 - -20
bc_parse_next_param 20 - -20
bc_parse_next_for 20 - -20
bc_parse_next_expr 20 - -20
bc_parse_next_elem 20 - -20
common_parse_expr 62 40 -22
bc_parse_expr 49 24 -25
dc_lex_regs 52 13 -39
bc_parse_name 581 539 -42
bc_parse_expr_empty_ok 2157 2108 -49
dc_parse_insts 332 83 -249
dc_lex_tokens 364 91 -273
bc_parse_stmt 2261 1868 -393
------------------------------------------------------------------------------
(add/remove: 0/7 grow/shrink: 1/8 up/down: 4/-1232) Total: -1228 bytes
text data bss dec hex filename
987037 485 7296 994818 f2e02 busybox_old
985814 485 7296 993595 f293b busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 0330c43e5..685427e58 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -632,11 +632,6 @@ typedef struct BcLex { | |||
632 | BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER | BC_PARSE_FLAG_IF | \ | 632 | BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER | BC_PARSE_FLAG_IF | \ |
633 | BC_PARSE_FLAG_ELSE | BC_PARSE_FLAG_IF_END))) | 633 | BC_PARSE_FLAG_ELSE | BC_PARSE_FLAG_IF_END))) |
634 | 634 | ||
635 | typedef struct BcParseNext { | ||
636 | uint32_t len; | ||
637 | BcLexType tokens[4]; | ||
638 | } BcParseNext; | ||
639 | |||
640 | struct BcParse; | 635 | struct BcParse; |
641 | 636 | ||
642 | struct BcProgram; | 637 | struct BcProgram; |
@@ -834,34 +829,40 @@ static const uint8_t bc_parse_ops[] = { | |||
834 | #define bc_parse_op_PREC(i) (bc_parse_ops[i] & 0x0f) | 829 | #define bc_parse_op_PREC(i) (bc_parse_ops[i] & 0x0f) |
835 | #define bc_parse_op_LEFT(i) (bc_parse_ops[i] & 0x10) | 830 | #define bc_parse_op_LEFT(i) (bc_parse_ops[i] & 0x10) |
836 | 831 | ||
832 | // Byte array of up to 4 BC_LEX's, packed into 32-bit word | ||
833 | typedef uint32_t BcParseNext; | ||
834 | |||
837 | // These identify what tokens can come after expressions in certain cases. | 835 | // These identify what tokens can come after expressions in certain cases. |
838 | #define BC_PARSE_NEXT_TOKENS(...) .tokens = { __VA_ARGS__ } | 836 | enum { |
839 | #define BC_PARSE_NEXT(a, ...) \ | 837 | #define BC_PARSE_NEXT4(a,b,c,d) ( (a) | ((b)<<8) | ((c)<<16) | ((((d)|0x80)<<24)) ) |
840 | { \ | 838 | #define BC_PARSE_NEXT2(a,b) BC_PARSE_NEXT4(a,b,0xff,0xff) |
841 | .len = (a), BC_PARSE_NEXT_TOKENS(__VA_ARGS__) \ | 839 | #define BC_PARSE_NEXT1(a) BC_PARSE_NEXT4(a,0xff,0xff,0xff) |
842 | } | 840 | bc_parse_next_expr = BC_PARSE_NEXT4(BC_LEX_NLINE, BC_LEX_SCOLON, BC_LEX_RBRACE, BC_LEX_EOF), |
843 | static const BcParseNext bc_parse_next_expr = | 841 | bc_parse_next_param = BC_PARSE_NEXT2(BC_LEX_RPAREN, BC_LEX_COMMA), |
844 | BC_PARSE_NEXT(4, BC_LEX_NLINE, BC_LEX_SCOLON, BC_LEX_RBRACE, BC_LEX_EOF); | 842 | bc_parse_next_print = BC_PARSE_NEXT4(BC_LEX_COMMA, BC_LEX_NLINE, BC_LEX_SCOLON, BC_LEX_EOF), |
845 | static const BcParseNext bc_parse_next_param = | 843 | bc_parse_next_rel = BC_PARSE_NEXT1(BC_LEX_RPAREN), |
846 | BC_PARSE_NEXT(2, BC_LEX_RPAREN, BC_LEX_COMMA); | 844 | bc_parse_next_elem = BC_PARSE_NEXT1(BC_LEX_RBRACKET), |
847 | static const BcParseNext bc_parse_next_print = | 845 | bc_parse_next_for = BC_PARSE_NEXT1(BC_LEX_SCOLON), |
848 | BC_PARSE_NEXT(4, BC_LEX_COMMA, BC_LEX_NLINE, BC_LEX_SCOLON, BC_LEX_EOF); | 846 | bc_parse_next_read = BC_PARSE_NEXT2(BC_LEX_NLINE, BC_LEX_EOF), |
849 | static const BcParseNext bc_parse_next_rel = BC_PARSE_NEXT(1, BC_LEX_RPAREN); | 847 | #undef BC_PARSE_NEXT4 |
850 | static const BcParseNext bc_parse_next_elem = BC_PARSE_NEXT(1, BC_LEX_RBRACKET); | 848 | #undef BC_PARSE_NEXT2 |
851 | static const BcParseNext bc_parse_next_for = BC_PARSE_NEXT(1, BC_LEX_SCOLON); | 849 | #undef BC_PARSE_NEXT1 |
852 | static const BcParseNext bc_parse_next_read = | 850 | }; |
853 | BC_PARSE_NEXT(2, BC_LEX_NLINE, BC_LEX_EOF); | ||
854 | #endif // ENABLE_BC | 851 | #endif // ENABLE_BC |
855 | 852 | ||
856 | #if ENABLE_DC | 853 | #if ENABLE_DC |
857 | static const BcLexType dc_lex_regs[] = { | 854 | static const //BcLexType - should be this type, but narrower type saves size: |
855 | uint8_t | ||
856 | dc_lex_regs[] = { | ||
858 | BC_LEX_OP_REL_EQ, BC_LEX_OP_REL_LE, BC_LEX_OP_REL_GE, BC_LEX_OP_REL_NE, | 857 | BC_LEX_OP_REL_EQ, BC_LEX_OP_REL_LE, BC_LEX_OP_REL_GE, BC_LEX_OP_REL_NE, |
859 | BC_LEX_OP_REL_LT, BC_LEX_OP_REL_GT, BC_LEX_SCOLON, BC_LEX_COLON, | 858 | BC_LEX_OP_REL_LT, BC_LEX_OP_REL_GT, BC_LEX_SCOLON, BC_LEX_COLON, |
860 | BC_LEX_ELSE, BC_LEX_LOAD, BC_LEX_LOAD_POP, BC_LEX_OP_ASSIGN, | 859 | BC_LEX_ELSE, BC_LEX_LOAD, BC_LEX_LOAD_POP, BC_LEX_OP_ASSIGN, |
861 | BC_LEX_STORE_PUSH, | 860 | BC_LEX_STORE_PUSH, |
862 | }; | 861 | }; |
863 | 862 | ||
864 | static const BcLexType dc_lex_tokens[] = { | 863 | static const //BcLexType - should be this type |
864 | uint8_t | ||
865 | dc_lex_tokens[] = { | ||
865 | BC_LEX_OP_MODULUS, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_LPAREN, | 866 | BC_LEX_OP_MODULUS, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_LPAREN, |
866 | BC_LEX_INVALID, BC_LEX_OP_MULTIPLY, BC_LEX_OP_PLUS, BC_LEX_INVALID, | 867 | BC_LEX_INVALID, BC_LEX_OP_MULTIPLY, BC_LEX_OP_PLUS, BC_LEX_INVALID, |
867 | BC_LEX_OP_MINUS, BC_LEX_INVALID, BC_LEX_OP_DIVIDE, | 868 | BC_LEX_OP_MINUS, BC_LEX_INVALID, BC_LEX_OP_DIVIDE, |
@@ -889,7 +890,9 @@ static const BcLexType dc_lex_tokens[] = { | |||
889 | BC_LEX_INVALID | 890 | BC_LEX_INVALID |
890 | }; | 891 | }; |
891 | 892 | ||
892 | static const BcInst dc_parse_insts[] = { | 893 | static const //BcInst - should be this type. Using signed narrow type since BC_INST_INVALID is -1 |
894 | int8_t | ||
895 | dc_parse_insts[] = { | ||
893 | BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_REL_GE, | 896 | BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_REL_GE, |
894 | BC_INST_INVALID, BC_INST_POWER, BC_INST_MULTIPLY, BC_INST_DIVIDE, | 897 | BC_INST_INVALID, BC_INST_POWER, BC_INST_MULTIPLY, BC_INST_DIVIDE, |
895 | BC_INST_MODULUS, BC_INST_PLUS, BC_INST_MINUS, | 898 | BC_INST_MODULUS, BC_INST_PLUS, BC_INST_MINUS, |
@@ -4768,7 +4771,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne | |||
4768 | BcInst prev = BC_INST_PRINT; | 4771 | BcInst prev = BC_INST_PRINT; |
4769 | BcLexType top, t = p->l.t.t; | 4772 | BcLexType top, t = p->l.t.t; |
4770 | size_t nexprs = 0, ops_bgn = p->ops.len; | 4773 | size_t nexprs = 0, ops_bgn = p->ops.len; |
4771 | uint32_t i, nparens, nrelops; | 4774 | unsigned nparens, nrelops; |
4772 | bool paren_first, paren_expr, rprn, done, get_token, assign, bin_last; | 4775 | bool paren_first, paren_expr, rprn, done, get_token, assign, bin_last; |
4773 | 4776 | ||
4774 | paren_first = p->l.t.t == BC_LEX_LPAREN; | 4777 | paren_first = p->l.t.t == BC_LEX_LPAREN; |
@@ -4993,9 +4996,14 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne | |||
4993 | if (prev == BC_INST_BOOL_NOT || nexprs != 1) | 4996 | if (prev == BC_INST_BOOL_NOT || nexprs != 1) |
4994 | return bc_error_bad_expression(); | 4997 | return bc_error_bad_expression(); |
4995 | 4998 | ||
4996 | for (i = 0; i < next.len; ++i) | 4999 | // next is BcParseNext, byte array of up to 4 BC_LEX's, packed into 32-bit word |
4997 | if (t == next.tokens[i]) | 5000 | for (;;) { |
5001 | if (t == (next & 0x7f)) | ||
4998 | goto ok; | 5002 | goto ok; |
5003 | if (next & 0x80) // last element? | ||
5004 | break; | ||
5005 | next >>= 8; | ||
5006 | } | ||
4999 | return bc_error_bad_expression(); | 5007 | return bc_error_bad_expression(); |
5000 | ok: | 5008 | ok: |
5001 | 5009 | ||