shell/math: rename TOK_NUM to TOK_VALUE, improve comments
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
c1c267fd36
commit
5d8f8570c0
1 changed files with 25 additions and 24 deletions
49
shell/math.c
49
shell/math.c
|
@ -94,7 +94,6 @@
|
||||||
*
|
*
|
||||||
* Merge in Aaron's comments previously posted to the busybox list,
|
* Merge in Aaron's comments previously posted to the busybox list,
|
||||||
* modified slightly to take account of my changes to the code.
|
* modified slightly to take account of my changes to the code.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
|
* (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
|
||||||
|
@ -212,18 +211,18 @@ typedef unsigned char operator;
|
||||||
#define TOK_UPLUS tok_decl(UNARYPREC+1,1)
|
#define TOK_UPLUS tok_decl(UNARYPREC+1,1)
|
||||||
|
|
||||||
#define PREC_PRE (UNARYPREC+2)
|
#define PREC_PRE (UNARYPREC+2)
|
||||||
|
|
||||||
#define TOK_PRE_INC tok_decl(PREC_PRE, 0)
|
#define TOK_PRE_INC tok_decl(PREC_PRE, 0)
|
||||||
#define TOK_PRE_DEC tok_decl(PREC_PRE, 1)
|
#define TOK_PRE_DEC tok_decl(PREC_PRE, 1)
|
||||||
|
|
||||||
#define PREC_POST (UNARYPREC+3)
|
#define PREC_POST (UNARYPREC+3)
|
||||||
|
|
||||||
#define TOK_POST_INC tok_decl(PREC_POST, 0)
|
#define TOK_POST_INC tok_decl(PREC_POST, 0)
|
||||||
#define TOK_POST_DEC tok_decl(PREC_POST, 1)
|
#define TOK_POST_DEC tok_decl(PREC_POST, 1)
|
||||||
|
|
||||||
#define SPEC_PREC (UNARYPREC+4)
|
/* TOK_VALUE marks a number, name, name++/name--, or (EXPR):
|
||||||
|
* IOW: something which can be used as the left side of a binary op.
|
||||||
#define TOK_NUM tok_decl(SPEC_PREC, 0)
|
* Since it's never pushed to opstack, its precedence does not matter.
|
||||||
|
*/
|
||||||
|
#define TOK_VALUE tok_decl(PREC_POST, 2)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
is_assign_op(operator op)
|
is_assign_op(operator op)
|
||||||
|
@ -625,7 +624,9 @@ evaluate_string(arith_state_t *math_state, const char *expr)
|
||||||
var_or_num_t *numstack, *numstackptr;
|
var_or_num_t *numstack, *numstackptr;
|
||||||
/* Stack of operator tokens */
|
/* Stack of operator tokens */
|
||||||
operator *opstack, *opstackptr;
|
operator *opstack, *opstackptr;
|
||||||
|
/* To detect whether we are after a "value": */
|
||||||
operator lasttok;
|
operator lasttok;
|
||||||
|
/* To insert implicit () in ?: ternary op: */
|
||||||
operator insert_op = 0xff;
|
operator insert_op = 0xff;
|
||||||
unsigned ternary_level = 0;
|
unsigned ternary_level = 0;
|
||||||
const char *errmsg;
|
const char *errmsg;
|
||||||
|
@ -720,12 +721,12 @@ evaluate_string(arith_state_t *math_state, const char *expr)
|
||||||
} else {
|
} else {
|
||||||
dbg("[%d] var:IGNORED", (int)(numstackptr - numstack));
|
dbg("[%d] var:IGNORED", (int)(numstackptr - numstack));
|
||||||
expr = p;
|
expr = p;
|
||||||
numstackptr->var_name = NULL;
|
numstackptr->var_name = NULL; /* not needed, paranoia */
|
||||||
numstackptr->val = 0;
|
numstackptr->val = 0; /* not needed, paranoia */
|
||||||
}
|
}
|
||||||
push_num:
|
push_value:
|
||||||
numstackptr++;
|
numstackptr++;
|
||||||
lasttok = TOK_NUM;
|
lasttok = TOK_VALUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +748,7 @@ evaluate_string(arith_state_t *math_state, const char *expr)
|
||||||
*/
|
*/
|
||||||
if (isalnum(*expr) || *expr == '_')
|
if (isalnum(*expr) || *expr == '_')
|
||||||
goto syntax_err;
|
goto syntax_err;
|
||||||
goto push_num;
|
goto push_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Should be an operator */
|
/* Should be an operator */
|
||||||
|
@ -818,15 +819,14 @@ evaluate_string(arith_state_t *math_state, const char *expr)
|
||||||
dbg("insert_op=%02x op=%02x", insert_op, op);
|
dbg("insert_op=%02x op=%02x", insert_op, op);
|
||||||
}
|
}
|
||||||
tok_found1:
|
tok_found1:
|
||||||
/* post grammar: a++ reduce to num */
|
/* NAME++ is a "value" (something suitable for a binop) */
|
||||||
if (lasttok == TOK_POST_INC || lasttok == TOK_POST_DEC)
|
if (PREC(lasttok) == PREC_POST)
|
||||||
lasttok = TOK_NUM;
|
lasttok = TOK_VALUE;
|
||||||
|
|
||||||
/* Plus and minus are binary (not unary) _only_ if the last
|
/* Plus and minus are binary (not unary) _only_ if the last
|
||||||
* token was a number, or a right paren (which pretends to be
|
* token was a "value". Think about it. It makes sense.
|
||||||
* a number, since it evaluates to one). Think about it.
|
*/
|
||||||
* It makes sense. */
|
if (lasttok != TOK_VALUE) {
|
||||||
if (lasttok != TOK_NUM) {
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case TOK_ADD:
|
case TOK_ADD:
|
||||||
//op = TOK_UPLUS;
|
//op = TOK_UPLUS;
|
||||||
|
@ -857,8 +857,8 @@ evaluate_string(arith_state_t *math_state, const char *expr)
|
||||||
prec = PREC(op);
|
prec = PREC(op);
|
||||||
if (prec != PREC_LPAREN && prec < UNARYPREC) {
|
if (prec != PREC_LPAREN && prec < UNARYPREC) {
|
||||||
/* binary, ternary or RPAREN */
|
/* binary, ternary or RPAREN */
|
||||||
if (lasttok != TOK_NUM) {
|
if (lasttok != TOK_VALUE) {
|
||||||
/* must be preceded by a num */
|
/* must be preceded by a num (example?) */
|
||||||
goto syntax_err;
|
goto syntax_err;
|
||||||
}
|
}
|
||||||
/* if op is RPAREN:
|
/* if op is RPAREN:
|
||||||
|
@ -883,11 +883,12 @@ evaluate_string(arith_state_t *math_state, const char *expr)
|
||||||
operator prev_op = *--opstackptr;
|
operator prev_op = *--opstackptr;
|
||||||
if (op == TOK_RPAREN) {
|
if (op == TOK_RPAREN) {
|
||||||
if (prev_op == TOK_LPAREN) {
|
if (prev_op == TOK_LPAREN) {
|
||||||
/* Erase var name: (var) is just a number, for example, (var) = 1 is not valid */
|
/* Erase var name: for example, (VAR) = 1 is not valid */
|
||||||
numstackptr[-1].var_name = NULL;
|
numstackptr[-1].var_name = NULL;
|
||||||
/* Any operator directly after a
|
/* (EXPR) is a "value": next operator directly after
|
||||||
* close paren should consider itself binary */
|
* close paren should be considered binary
|
||||||
lasttok = TOK_NUM;
|
*/
|
||||||
|
lasttok = TOK_VALUE;
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
/* Not (y), but ...x~y). Fall through to evaluate x~y */
|
/* Not (y), but ...x~y). Fall through to evaluate x~y */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue