aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2023-06-26 09:59:56 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2023-06-26 10:02:54 +0200
commit5d8f8570c0c4220bfadb6d24d4fbc3e722d44802 (patch)
treeda5bb43110d253f9b111e0e7efedec3f616efcb7
parentc1c267fd36b0fcac8c8871232eecc1e360173990 (diff)
downloadbusybox-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.c49
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
228static int 227static int
229is_assign_op(operator op) 228is_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 */