mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-27 16:50:58 +01:00
Merge of 23553: retrieving array as number.
This commit is contained in:
parent
3ea0ed6cfe
commit
5cceac415d
4 changed files with 193 additions and 73 deletions
|
|
@ -22,7 +22,7 @@ matching `tt(RPAR()RPAR())' are treated as a quoted expression and
|
||||||
arithmetic expansion performed as for an argument of tt(let). More
|
arithmetic expansion performed as for an argument of tt(let). More
|
||||||
precisely, `tt(LPAR()LPAR())var(...)tt(RPAR()RPAR())' is equivalent to
|
precisely, `tt(LPAR()LPAR())var(...)tt(RPAR()RPAR())' is equivalent to
|
||||||
`tt(let ")var(...)tt(")'. The return status is 0 if the arithmetic value
|
`tt(let ")var(...)tt(")'. The return status is 0 if the arithmetic value
|
||||||
of the expression is non-zero, and 1 otherwise.
|
of the expression is non-zero, 1 if it is zero, and 2 if an error occurred.
|
||||||
|
|
||||||
For example, the following statement
|
For example, the following statement
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -652,9 +652,12 @@ tt(kill -IO) and tt(kill -POLL) have the same effect.
|
||||||
findex(let)
|
findex(let)
|
||||||
item(tt(let) var(arg) ...)(
|
item(tt(let) var(arg) ...)(
|
||||||
Evaluate each var(arg) as an arithmetic expression.
|
Evaluate each var(arg) as an arithmetic expression.
|
||||||
See noderef(Arithmetic Evaluation) for a description
|
See
|
||||||
of arithmetic expressions. The exit status is 0 if the
|
ifzman(the section `Arithmetic Evaluation' in zmanref(zshmisc))\
|
||||||
value of the last expression is nonzero, and 1 otherwise.
|
ifnzman(noderef(Arithmetic Evaluation))
|
||||||
|
for a description of arithmetic expressions. The exit status is 0 if the
|
||||||
|
value of the last expression is nonzero, 1 if it is zero, and 2 if
|
||||||
|
an error occurred.
|
||||||
)
|
)
|
||||||
findex(limit)
|
findex(limit)
|
||||||
cindex(resource limits)
|
cindex(resource limits)
|
||||||
|
|
|
||||||
|
|
@ -3323,7 +3323,10 @@ execarith(Estate state, UNUSED(int do_exec))
|
||||||
fprintf(xtrerr, " ))\n");
|
fprintf(xtrerr, " ))\n");
|
||||||
fflush(xtrerr);
|
fflush(xtrerr);
|
||||||
}
|
}
|
||||||
errflag = 0;
|
if (errflag) {
|
||||||
|
errflag = 0;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
/* should test for fabs(val.u.d) < epsilon? */
|
/* should test for fabs(val.u.d) < epsilon? */
|
||||||
return (val.type == MN_INTEGER) ? val.u.l == 0 : val.u.d == 0.0;
|
return (val.type == MN_INTEGER) ? val.u.l == 0 : val.u.d == 0.0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
250
Src/math.c
250
Src/math.c
|
|
@ -40,7 +40,7 @@ int noeval;
|
||||||
/* integer zero */
|
/* integer zero */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
mnumber zero_mnumber;
|
mod_export mnumber zero_mnumber;
|
||||||
|
|
||||||
/* last input base we used */
|
/* last input base we used */
|
||||||
|
|
||||||
|
|
@ -168,8 +168,8 @@ static int prec[TOKCOUNT] =
|
||||||
0, 16, 0
|
0, 16, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TOPPREC 17
|
#define TOPPREC 18
|
||||||
#define ARGPREC (TOPPREC-1)
|
#define ARGPREC 16
|
||||||
|
|
||||||
static int type[TOKCOUNT] =
|
static int type[TOKCOUNT] =
|
||||||
{
|
{
|
||||||
|
|
@ -186,14 +186,75 @@ static int type[TOKCOUNT] =
|
||||||
/* 50 */ LR|OP_OPF, RL|OP_E2, LR|OP_OPF
|
/* 50 */ LR|OP_OPF, RL|OP_E2, LR|OP_OPF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
lexconstant(void)
|
||||||
|
{
|
||||||
|
#ifdef USE_LOCALE
|
||||||
|
char *prev_locale;
|
||||||
|
#endif
|
||||||
|
char *nptr;
|
||||||
|
|
||||||
|
nptr = ptr;
|
||||||
|
if (*nptr == '-')
|
||||||
|
nptr++;
|
||||||
|
|
||||||
|
if (*nptr == '0')
|
||||||
|
{
|
||||||
|
nptr++;
|
||||||
|
if (*nptr == 'x' || *nptr == 'X') {
|
||||||
|
/* Let zstrtol parse number with base */
|
||||||
|
yyval.u.l = zstrtol(ptr, &ptr, 0);
|
||||||
|
/* Should we set lastbase here? */
|
||||||
|
lastbase = 16;
|
||||||
|
return NUM;
|
||||||
|
}
|
||||||
|
else if (isset(OCTALZEROES) &&
|
||||||
|
(memchr(nptr, '.', strlen(nptr)) == NULL) &&
|
||||||
|
idigit(*nptr)) {
|
||||||
|
yyval.u.l = zstrtol(ptr, &ptr, 0);
|
||||||
|
lastbase = 8;
|
||||||
|
return NUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (idigit(*nptr))
|
||||||
|
nptr++;
|
||||||
|
|
||||||
|
if (*nptr == '.' || *nptr == 'e' || *nptr == 'E') {
|
||||||
|
/* it's a float */
|
||||||
|
yyval.type = MN_FLOAT;
|
||||||
|
#ifdef USE_LOCALE
|
||||||
|
prev_locale = dupstring(setlocale(LC_NUMERIC, NULL));
|
||||||
|
setlocale(LC_NUMERIC, "POSIX");
|
||||||
|
#endif
|
||||||
|
yyval.u.d = strtod(ptr, &nptr);
|
||||||
|
#ifdef USE_LOCALE
|
||||||
|
if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
|
||||||
|
#endif
|
||||||
|
if (ptr == nptr || *nptr == '.') {
|
||||||
|
zerr("bad floating point constant", NULL, 0);
|
||||||
|
return EOI;
|
||||||
|
}
|
||||||
|
ptr = nptr;
|
||||||
|
} else {
|
||||||
|
/* it's an integer */
|
||||||
|
yyval.u.l = zstrtol(ptr, &ptr, 10);
|
||||||
|
|
||||||
|
if (*ptr == '#') {
|
||||||
|
ptr++;
|
||||||
|
yyval.u.l = zstrtol(ptr, &ptr, lastbase = yyval.u.l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int outputradix;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
zzlex(void)
|
zzlex(void)
|
||||||
{
|
{
|
||||||
#ifdef USE_LOCALE
|
|
||||||
char *prev_locale;
|
|
||||||
#endif
|
|
||||||
int cct = 0;
|
int cct = 0;
|
||||||
yyval.type = MN_INTEGER;
|
yyval.type = MN_INTEGER;
|
||||||
|
|
||||||
|
|
@ -218,7 +279,14 @@ zzlex(void)
|
||||||
ptr++;
|
ptr++;
|
||||||
return MINUSEQ;
|
return MINUSEQ;
|
||||||
}
|
}
|
||||||
return (unary) ? UMINUS : MINUS;
|
if (unary) {
|
||||||
|
if (idigit(*ptr) || *ptr == '.') {
|
||||||
|
ptr--;
|
||||||
|
return lexconstant();
|
||||||
|
} else
|
||||||
|
return UMINUS;
|
||||||
|
} else
|
||||||
|
return MINUS;
|
||||||
case '(':
|
case '(':
|
||||||
return M_INPAR;
|
return M_INPAR;
|
||||||
case ')':
|
case ')':
|
||||||
|
|
@ -340,61 +408,53 @@ zzlex(void)
|
||||||
return EOI;
|
return EOI;
|
||||||
case '[':
|
case '[':
|
||||||
{
|
{
|
||||||
int base = zstrtol(ptr, &ptr, 10);
|
int n;
|
||||||
|
|
||||||
if (*ptr == ']')
|
if (idigit(*ptr)) {
|
||||||
ptr++;
|
n = zstrtol(ptr, &ptr, 10);
|
||||||
yyval.u.l = zstrtol(ptr, &ptr, lastbase = base);
|
if (*ptr != ']' || !idigit(*++ptr)) {
|
||||||
return NUM;
|
zerr("bad base syntax", NULL, 0);
|
||||||
|
return EOI;
|
||||||
|
}
|
||||||
|
yyval.u.l = zstrtol(ptr, &ptr, lastbase = n);
|
||||||
|
return NUM;
|
||||||
|
}
|
||||||
|
if (*ptr == '#') {
|
||||||
|
n = 1;
|
||||||
|
if (*++ptr == '#') {
|
||||||
|
n = -1;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
if (!idigit(*ptr))
|
||||||
|
goto bofs;
|
||||||
|
outputradix = n * zstrtol(ptr, &ptr, 10);
|
||||||
|
} else {
|
||||||
|
bofs:
|
||||||
|
zerr("bad output format specification", NULL, 0);
|
||||||
|
return EOI;
|
||||||
|
}
|
||||||
|
if(*ptr != ']')
|
||||||
|
goto bofs;
|
||||||
|
ptr++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\t':
|
case '\t':
|
||||||
case '\n':
|
case '\n':
|
||||||
break;
|
break;
|
||||||
case '0':
|
|
||||||
if (*ptr == 'x' || *ptr == 'X') {
|
|
||||||
/* Should we set lastbase here? */
|
|
||||||
yyval.u.l = zstrtol(++ptr, &ptr, lastbase = 16);
|
|
||||||
return NUM;
|
|
||||||
}
|
|
||||||
/* Fall through! */
|
/* Fall through! */
|
||||||
default:
|
default:
|
||||||
if (idigit(*--ptr) || *ptr == '.') {
|
if (idigit(*--ptr) || *ptr == '.')
|
||||||
char *nptr;
|
return lexconstant();
|
||||||
for (nptr = ptr; idigit(*nptr); nptr++);
|
|
||||||
|
|
||||||
if (*nptr == '.' || *nptr == 'e' || *nptr == 'E') {
|
|
||||||
/* it's a float */
|
|
||||||
yyval.type = MN_FLOAT;
|
|
||||||
#ifdef USE_LOCALE
|
|
||||||
prev_locale = setlocale(LC_NUMERIC, NULL);
|
|
||||||
setlocale(LC_NUMERIC, "POSIX");
|
|
||||||
#endif
|
|
||||||
yyval.u.d = strtod(ptr, &nptr);
|
|
||||||
#ifdef USE_LOCALE
|
|
||||||
setlocale(LC_NUMERIC, prev_locale);
|
|
||||||
#endif
|
|
||||||
if (ptr == nptr || *nptr == '.') {
|
|
||||||
zerr("bad floating point constant", NULL, 0);
|
|
||||||
return EOI;
|
|
||||||
}
|
|
||||||
ptr = nptr;
|
|
||||||
} else {
|
|
||||||
/* it's an integer */
|
|
||||||
yyval.u.l = zstrtol(ptr, &ptr, 10);
|
|
||||||
|
|
||||||
if (*ptr == '#') {
|
|
||||||
ptr++;
|
|
||||||
yyval.u.l = zstrtol(ptr, &ptr, lastbase = yyval.u.l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NUM;
|
|
||||||
}
|
|
||||||
if (*ptr == '#') {
|
if (*ptr == '#') {
|
||||||
if (*++ptr == '\\' || *ptr == '#') {
|
if (*++ptr == '\\' || *ptr == '#') {
|
||||||
int v;
|
int v;
|
||||||
|
|
||||||
ptr++;
|
ptr++;
|
||||||
|
if (!*ptr) {
|
||||||
|
zerr("character missing after ##", NULL, 0);
|
||||||
|
return EOI;
|
||||||
|
}
|
||||||
ptr = getkeystring(ptr, NULL, 6, &v);
|
ptr = getkeystring(ptr, NULL, 6, &v);
|
||||||
yyval.u.l = v;
|
yyval.u.l = v;
|
||||||
return NUM;
|
return NUM;
|
||||||
|
|
@ -446,7 +506,7 @@ static struct mathvalue *stack;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static void
|
static void
|
||||||
push(mnumber val, char *lval)
|
push(mnumber val, char *lval, int getme)
|
||||||
{
|
{
|
||||||
if (sp == STACKSZ - 1)
|
if (sp == STACKSZ - 1)
|
||||||
zerr("stack overflow", NULL, 0);
|
zerr("stack overflow", NULL, 0);
|
||||||
|
|
@ -454,8 +514,21 @@ push(mnumber val, char *lval)
|
||||||
sp++;
|
sp++;
|
||||||
stack[sp].val = val;
|
stack[sp].val = val;
|
||||||
stack[sp].lval = lval;
|
stack[sp].lval = lval;
|
||||||
|
if (getme)
|
||||||
|
stack[sp].val.type = MN_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static mnumber
|
||||||
|
pop(int noget)
|
||||||
|
{
|
||||||
|
struct mathvalue *mv = stack+sp;
|
||||||
|
|
||||||
|
if (mv->val.type == MN_UNSET && !noget)
|
||||||
|
mv->val = getnparam(mv->lval);
|
||||||
|
sp--;
|
||||||
|
return errflag ? zero_mnumber : mv->val;
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static mnumber
|
static mnumber
|
||||||
|
|
@ -465,10 +538,12 @@ getcvar(char *s)
|
||||||
mnumber mn;
|
mnumber mn;
|
||||||
mn.type = MN_INTEGER;
|
mn.type = MN_INTEGER;
|
||||||
|
|
||||||
|
queue_signals();
|
||||||
if (!(t = getsparam(s)))
|
if (!(t = getsparam(s)))
|
||||||
mn.u.l = 0;
|
mn.u.l = 0;
|
||||||
else
|
else
|
||||||
mn.u.l = STOUC(*t == Meta ? t[1] ^ 32 : *t);
|
mn.u.l = STOUC(*t == Meta ? t[1] ^ 32 : *t);
|
||||||
|
unqueue_signals();
|
||||||
return mn;
|
return mn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -485,6 +560,7 @@ setvar(char *s, mnumber v)
|
||||||
}
|
}
|
||||||
if (noeval)
|
if (noeval)
|
||||||
return v;
|
return v;
|
||||||
|
untokenize(s);
|
||||||
setnparam(s, v);
|
setnparam(s, v);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
@ -582,8 +658,10 @@ op(int what)
|
||||||
if (tp & (OP_A2|OP_A2IR|OP_A2IO|OP_E2|OP_E2IO)) {
|
if (tp & (OP_A2|OP_A2IR|OP_A2IO|OP_E2|OP_E2IO)) {
|
||||||
/* Make sure anyone seeing this message reports it. */
|
/* Make sure anyone seeing this message reports it. */
|
||||||
DPUTS(sp < 1, "BUG: math: not enough wallabies in outback.");
|
DPUTS(sp < 1, "BUG: math: not enough wallabies in outback.");
|
||||||
b = stack[sp--].val;
|
b = pop(0);
|
||||||
a = stack[sp--].val;
|
a = pop(what == EQ);
|
||||||
|
if (errflag)
|
||||||
|
return;
|
||||||
|
|
||||||
if (tp & (OP_A2IO|OP_E2IO)) {
|
if (tp & (OP_A2IO|OP_E2IO)) {
|
||||||
/* coerce to integers */
|
/* coerce to integers */
|
||||||
|
|
@ -595,10 +673,11 @@ op(int what)
|
||||||
b.type = MN_INTEGER;
|
b.type = MN_INTEGER;
|
||||||
b.u.l = (zlong)b.u.d;
|
b.u.l = (zlong)b.u.d;
|
||||||
}
|
}
|
||||||
} else if (a.type != b.type && what != COMMA) {
|
} else if (a.type != b.type && what != COMMA &&
|
||||||
|
(a.type != MN_UNSET || what != EQ)) {
|
||||||
/*
|
/*
|
||||||
* Different types, so coerce to float.
|
* Different types, so coerce to float.
|
||||||
* It may happen during an assigment that the LHS
|
* It may happen during an assignment that the LHS
|
||||||
* variable is actually an integer, but there's still
|
* variable is actually an integer, but there's still
|
||||||
* no harm in doing the arithmetic in floating point;
|
* no harm in doing the arithmetic in floating point;
|
||||||
* the assignment will do the correct conversion.
|
* the assignment will do the correct conversion.
|
||||||
|
|
@ -752,13 +831,15 @@ op(int what)
|
||||||
}
|
}
|
||||||
if (tp & (OP_E2|OP_E2IO)) {
|
if (tp & (OP_E2|OP_E2IO)) {
|
||||||
lv = stack[sp+1].lval;
|
lv = stack[sp+1].lval;
|
||||||
push(setvar(lv,c), lv);
|
push(setvar(lv,c), lv, 0);
|
||||||
} else
|
} else
|
||||||
push(c,NULL);
|
push(c,NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spval = &stack[sp].val;
|
spval = &stack[sp].val;
|
||||||
|
if (stack[sp].val.type == MN_UNSET)
|
||||||
|
*spval = getnparam(stack[sp].lval);
|
||||||
switch (what) {
|
switch (what) {
|
||||||
case NOT:
|
case NOT:
|
||||||
if (spval->type & MN_FLOAT) {
|
if (spval->type & MN_FLOAT) {
|
||||||
|
|
@ -804,11 +885,13 @@ op(int what)
|
||||||
break;
|
break;
|
||||||
case QUEST:
|
case QUEST:
|
||||||
DPUTS(sp < 2, "BUG: math: three shall be the number of the counting.");
|
DPUTS(sp < 2, "BUG: math: three shall be the number of the counting.");
|
||||||
c = stack[sp--].val;
|
c = pop(0);
|
||||||
b = stack[sp--].val;
|
b = pop(0);
|
||||||
a = stack[sp--].val;
|
a = pop(0);
|
||||||
|
if (errflag)
|
||||||
|
return;
|
||||||
/* b and c can stay different types in this case. */
|
/* b and c can stay different types in this case. */
|
||||||
push(((a.type & MN_FLOAT) ? a.u.d : a.u.l) ? b : c, NULL);
|
push(((a.type & MN_FLOAT) ? a.u.d : a.u.l) ? b : c, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case COLON:
|
case COLON:
|
||||||
zerr("':' without '?'", NULL, 0);
|
zerr("':' without '?'", NULL, 0);
|
||||||
|
|
@ -839,7 +922,11 @@ static void
|
||||||
bop(int tk)
|
bop(int tk)
|
||||||
{
|
{
|
||||||
mnumber *spval = &stack[sp].val;
|
mnumber *spval = &stack[sp].val;
|
||||||
int tst = (spval->type & MN_FLOAT) ? (zlong)spval->u.d : spval->u.l;
|
int tst;
|
||||||
|
|
||||||
|
if (stack[sp].val.type == MN_UNSET)
|
||||||
|
*spval = getnparam(stack[sp].lval);
|
||||||
|
tst = (spval->type & MN_FLOAT) ? (zlong)spval->u.d : spval->u.l;
|
||||||
|
|
||||||
switch (tk) {
|
switch (tk) {
|
||||||
case DAND:
|
case DAND:
|
||||||
|
|
@ -902,10 +989,29 @@ mathevall(char *s, int prek, char **ep)
|
||||||
stack[0].val.u.l = 0;
|
stack[0].val.u.l = 0;
|
||||||
mathparse(prek);
|
mathparse(prek);
|
||||||
*ep = ptr;
|
*ep = ptr;
|
||||||
DPUTS(!errflag && sp,
|
DPUTS(!errflag && sp > 0,
|
||||||
"BUG: math: wallabies roaming too freely in outback");
|
"BUG: math: wallabies roaming too freely in outback");
|
||||||
|
|
||||||
ret = stack[0].val;
|
if (errflag) {
|
||||||
|
/*
|
||||||
|
* This used to set the return value to errflag.
|
||||||
|
* I don't understand how that could be useful; the
|
||||||
|
* caller doesn't know that's what's happened and
|
||||||
|
* may not get a value at all.
|
||||||
|
* Worse, we reset errflag in execarith() and setting
|
||||||
|
* this explicitly non-zero means a (( ... )) returns
|
||||||
|
* status 0 if there's an error. That surely can't
|
||||||
|
* be right. execarith() now detects an error and returns
|
||||||
|
* status 2.
|
||||||
|
*/
|
||||||
|
ret.type = MN_INTEGER;
|
||||||
|
ret.u.l = 0;
|
||||||
|
} else {
|
||||||
|
if (stack[0].val.type == MN_UNSET)
|
||||||
|
ret = getnparam(stack[0].lval);
|
||||||
|
else
|
||||||
|
ret = stack[0].val;
|
||||||
|
}
|
||||||
|
|
||||||
if (--mlevel) {
|
if (--mlevel) {
|
||||||
lastbase = xlastbase;
|
lastbase = xlastbase;
|
||||||
|
|
@ -929,6 +1035,9 @@ matheval(char *s)
|
||||||
char *junk;
|
char *junk;
|
||||||
mnumber x;
|
mnumber x;
|
||||||
int xmtok = mtok;
|
int xmtok = mtok;
|
||||||
|
/* maintain outputradix across levels of evaluation */
|
||||||
|
if (!mlevel)
|
||||||
|
outputradix = 0;
|
||||||
|
|
||||||
if (!*s) {
|
if (!*s) {
|
||||||
x.type = MN_INTEGER;
|
x.type = MN_INTEGER;
|
||||||
|
|
@ -943,7 +1052,7 @@ matheval(char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
zlong
|
mod_export zlong
|
||||||
mathevali(char *s)
|
mathevali(char *s)
|
||||||
{
|
{
|
||||||
mnumber x = matheval(s);
|
mnumber x = matheval(s);
|
||||||
|
|
@ -1014,22 +1123,25 @@ mathparse(int pc)
|
||||||
if (errflag)
|
if (errflag)
|
||||||
return;
|
return;
|
||||||
mtok = zzlex();
|
mtok = zzlex();
|
||||||
|
/* Handle empty input */
|
||||||
|
if (pc == TOPPREC && mtok == EOI)
|
||||||
|
return;
|
||||||
checkunary(mtok, optr);
|
checkunary(mtok, optr);
|
||||||
while (prec[mtok] <= pc) {
|
while (prec[mtok] <= pc) {
|
||||||
if (errflag)
|
if (errflag)
|
||||||
return;
|
return;
|
||||||
switch (mtok) {
|
switch (mtok) {
|
||||||
case NUM:
|
case NUM:
|
||||||
push(yyval, NULL);
|
push(yyval, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case ID:
|
case ID:
|
||||||
push((noeval ? zero_mnumber : getnparam(yylval)), yylval);
|
push(zero_mnumber, yylval, !noeval);
|
||||||
break;
|
break;
|
||||||
case CID:
|
case CID:
|
||||||
push((noeval ? zero_mnumber : getcvar(yylval)), yylval);
|
push((noeval ? zero_mnumber : getcvar(yylval)), yylval, 0);
|
||||||
break;
|
break;
|
||||||
case FUNC:
|
case FUNC:
|
||||||
push((noeval ? zero_mnumber : callmathfunc(yylval)), yylval);
|
push((noeval ? zero_mnumber : callmathfunc(yylval)), yylval, 0);
|
||||||
break;
|
break;
|
||||||
case M_INPAR:
|
case M_INPAR:
|
||||||
mathparse(TOPPREC);
|
mathparse(TOPPREC);
|
||||||
|
|
@ -1040,6 +1152,8 @@ mathparse(int pc)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QUEST:
|
case QUEST:
|
||||||
|
if (stack[sp].val.type == MN_UNSET)
|
||||||
|
stack[sp].val = getnparam(stack[sp].lval);
|
||||||
q = (stack[sp].val.type == MN_FLOAT) ? (zlong)stack[sp].val.u.d :
|
q = (stack[sp].val.type == MN_FLOAT) ? (zlong)stack[sp].val.u.d :
|
||||||
stack[sp].val.u.l;
|
stack[sp].val.u.l;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue