diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2023-06-26 09:59:56 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-06-26 10:02:54 +0200 |
commit | 5d8f8570c0c4220bfadb6d24d4fbc3e722d44802 (patch) | |
tree | da5bb43110d253f9b111e0e7efedec3f616efcb7 | |
parent | c1c267fd36b0fcac8c8871232eecc1e360173990 (diff) | |
download | busybox-w32-5d8f8570c0c4220bfadb6d24d4fbc3e722d44802.tar.gz busybox-w32-5d8f8570c0c4220bfadb6d24d4fbc3e722d44802.tar.bz2 busybox-w32-5d8f8570c0c4220bfadb6d24d4fbc3e722d44802.zip |
shell/math: rename TOK_NUM to TOK_VALUE, improve comments
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/math.c | 49 |
1 files changed, 25 insertions, 24 deletions
diff --git a/shell/math.c b/shell/math.c index fbf5c587e..0426e2daa 100644 --- a/shell/math.c +++ b/shell/math.c | |||
@@ -94,7 +94,6 @@ | |||
94 | * | 94 | * |
95 | * Merge in Aaron's comments previously posted to the busybox list, | 95 | * Merge in Aaron's comments previously posted to the busybox list, |
96 | * modified slightly to take account of my changes to the code. | 96 | * modified slightly to take account of my changes to the code. |
97 | * | ||
98 | */ | 97 | */ |
99 | /* | 98 | /* |
100 | * (C) 2003 Vladimir Oleynik <dzo@simtreas.ru> | 99 | * (C) 2003 Vladimir Oleynik <dzo@simtreas.ru> |
@@ -212,18 +211,18 @@ typedef unsigned char operator; | |||
212 | #define TOK_UPLUS tok_decl(UNARYPREC+1,1) | 211 | #define TOK_UPLUS tok_decl(UNARYPREC+1,1) |
213 | 212 | ||
214 | #define PREC_PRE (UNARYPREC+2) | 213 | #define PREC_PRE (UNARYPREC+2) |
215 | |||
216 | #define TOK_PRE_INC tok_decl(PREC_PRE, 0) | 214 | #define TOK_PRE_INC tok_decl(PREC_PRE, 0) |
217 | #define TOK_PRE_DEC tok_decl(PREC_PRE, 1) | 215 | #define TOK_PRE_DEC tok_decl(PREC_PRE, 1) |
218 | 216 | ||
219 | #define PREC_POST (UNARYPREC+3) | 217 | #define PREC_POST (UNARYPREC+3) |
220 | |||
221 | #define TOK_POST_INC tok_decl(PREC_POST, 0) | 218 | #define TOK_POST_INC tok_decl(PREC_POST, 0) |
222 | #define TOK_POST_DEC tok_decl(PREC_POST, 1) | 219 | #define TOK_POST_DEC tok_decl(PREC_POST, 1) |
223 | 220 | ||
224 | #define SPEC_PREC (UNARYPREC+4) | 221 | /* TOK_VALUE marks a number, name, name++/name--, or (EXPR): |
225 | 222 | * IOW: something which can be used as the left side of a binary op. | |
226 | #define TOK_NUM tok_decl(SPEC_PREC, 0) | 223 | * Since it's never pushed to opstack, its precedence does not matter. |
224 | */ | ||
225 | #define TOK_VALUE tok_decl(PREC_POST, 2) | ||
227 | 226 | ||
228 | static int | 227 | static int |
229 | is_assign_op(operator op) | 228 | is_assign_op(operator op) |
@@ -625,7 +624,9 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
625 | var_or_num_t *numstack, *numstackptr; | 624 | var_or_num_t *numstack, *numstackptr; |
626 | /* Stack of operator tokens */ | 625 | /* Stack of operator tokens */ |
627 | operator *opstack, *opstackptr; | 626 | operator *opstack, *opstackptr; |
627 | /* To detect whether we are after a "value": */ | ||
628 | operator lasttok; | 628 | operator lasttok; |
629 | /* To insert implicit () in ?: ternary op: */ | ||
629 | operator insert_op = 0xff; | 630 | operator insert_op = 0xff; |
630 | unsigned ternary_level = 0; | 631 | unsigned ternary_level = 0; |
631 | const char *errmsg; | 632 | const char *errmsg; |
@@ -720,12 +721,12 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
720 | } else { | 721 | } else { |
721 | dbg("[%d] var:IGNORED", (int)(numstackptr - numstack)); | 722 | dbg("[%d] var:IGNORED", (int)(numstackptr - numstack)); |
722 | expr = p; | 723 | expr = p; |
723 | numstackptr->var_name = NULL; | 724 | numstackptr->var_name = NULL; /* not needed, paranoia */ |
724 | numstackptr->val = 0; | 725 | numstackptr->val = 0; /* not needed, paranoia */ |
725 | } | 726 | } |
726 | push_num: | 727 | push_value: |
727 | numstackptr++; | 728 | numstackptr++; |
728 | lasttok = TOK_NUM; | 729 | lasttok = TOK_VALUE; |
729 | continue; | 730 | continue; |
730 | } | 731 | } |
731 | 732 | ||
@@ -747,7 +748,7 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
747 | */ | 748 | */ |
748 | if (isalnum(*expr) || *expr == '_') | 749 | if (isalnum(*expr) || *expr == '_') |
749 | goto syntax_err; | 750 | goto syntax_err; |
750 | goto push_num; | 751 | goto push_value; |
751 | } | 752 | } |
752 | 753 | ||
753 | /* Should be an operator */ | 754 | /* Should be an operator */ |
@@ -818,15 +819,14 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
818 | dbg("insert_op=%02x op=%02x", insert_op, op); | 819 | dbg("insert_op=%02x op=%02x", insert_op, op); |
819 | } | 820 | } |
820 | tok_found1: | 821 | tok_found1: |
821 | /* post grammar: a++ reduce to num */ | 822 | /* NAME++ is a "value" (something suitable for a binop) */ |
822 | if (lasttok == TOK_POST_INC || lasttok == TOK_POST_DEC) | 823 | if (PREC(lasttok) == PREC_POST) |
823 | lasttok = TOK_NUM; | 824 | lasttok = TOK_VALUE; |
824 | 825 | ||
825 | /* Plus and minus are binary (not unary) _only_ if the last | 826 | /* Plus and minus are binary (not unary) _only_ if the last |
826 | * token was a number, or a right paren (which pretends to be | 827 | * token was a "value". Think about it. It makes sense. |
827 | * a number, since it evaluates to one). Think about it. | 828 | */ |
828 | * It makes sense. */ | 829 | if (lasttok != TOK_VALUE) { |
829 | if (lasttok != TOK_NUM) { | ||
830 | switch (op) { | 830 | switch (op) { |
831 | case TOK_ADD: | 831 | case TOK_ADD: |
832 | //op = TOK_UPLUS; | 832 | //op = TOK_UPLUS; |
@@ -857,8 +857,8 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
857 | prec = PREC(op); | 857 | prec = PREC(op); |
858 | if (prec != PREC_LPAREN && prec < UNARYPREC) { | 858 | if (prec != PREC_LPAREN && prec < UNARYPREC) { |
859 | /* binary, ternary or RPAREN */ | 859 | /* binary, ternary or RPAREN */ |
860 | if (lasttok != TOK_NUM) { | 860 | if (lasttok != TOK_VALUE) { |
861 | /* must be preceded by a num */ | 861 | /* must be preceded by a num (example?) */ |
862 | goto syntax_err; | 862 | goto syntax_err; |
863 | } | 863 | } |
864 | /* if op is RPAREN: | 864 | /* if op is RPAREN: |
@@ -883,11 +883,12 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
883 | operator prev_op = *--opstackptr; | 883 | operator prev_op = *--opstackptr; |
884 | if (op == TOK_RPAREN) { | 884 | if (op == TOK_RPAREN) { |
885 | if (prev_op == TOK_LPAREN) { | 885 | if (prev_op == TOK_LPAREN) { |
886 | /* Erase var name: (var) is just a number, for example, (var) = 1 is not valid */ | 886 | /* Erase var name: for example, (VAR) = 1 is not valid */ |
887 | numstackptr[-1].var_name = NULL; | 887 | numstackptr[-1].var_name = NULL; |
888 | /* Any operator directly after a | 888 | /* (EXPR) is a "value": next operator directly after |
889 | * close paren should consider itself binary */ | 889 | * close paren should be considered binary |
890 | lasttok = TOK_NUM; | 890 | */ |
891 | lasttok = TOK_VALUE; | ||
891 | goto next; | 892 | goto next; |
892 | } | 893 | } |
893 | /* Not (y), but ...x~y). Fall through to evaluate x~y */ | 894 | /* Not (y), but ...x~y). Fall through to evaluate x~y */ |