1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-01 07:31:20 +02:00

zsh-workers/7981

This commit is contained in:
Tanaka Akira 1999-09-22 13:10:37 +00:00
parent f98b1581a4
commit 9878bf492b

View file

@ -45,7 +45,7 @@ int lastbase;
static char *ptr; static char *ptr;
static mnumber yyval; static mnumber yyval;
static LV yylval; static char *yylval;
static int mlevel = 0; static int mlevel = 0;
@ -153,12 +153,12 @@ static int prec[TOKCOUNT] =
6, 8, 8, 8, 9, 6, 8, 8, 8, 9,
9, 3, 3, 10, 10, 9, 3, 3, 10, 10,
10, 10, 11, 11, 12, 10, 10, 11, 11, 12,
13, 13, 14, 14, 15, 13, 13, 14, 15, 16,
15, 15, 15, 15, 15, 16, 16, 16, 16, 16,
15, 15, 15, 15, 15, 16, 16, 16, 16, 16,
15, 15, 15, 16, 200, 16, 16, 16, 17, 200,
2, 2, 0, 0, 7, 2, 2, 0, 0, 7,
0, 15, 0 0, 16, 0
}; };
#define TOPPREC 16 #define TOPPREC 16
@ -179,13 +179,6 @@ static int type[TOKCOUNT] =
/* 50 */ LR|OP_OPF, RL|OP_E2, LR|OP_OPF /* 50 */ LR|OP_OPF, RL|OP_E2, LR|OP_OPF
}; };
#define LVCOUNT 32
/* list of lvalues (variables) */
static int lvc;
static char **lvals;
/**/ /**/
static int static int
@ -325,7 +318,6 @@ zzlex(void)
case '?': case '?':
if (unary) { if (unary) {
yyval.u.l = lastval; yyval.u.l = lastval;
unary = 0;
return NUM; return NUM;
} }
return QUEST; return QUEST;
@ -397,10 +389,6 @@ zzlex(void)
char *p, q; char *p, q;
p = ptr; p = ptr;
if (lvc == LVCOUNT) {
zerr("too many identifiers (complain to author)", NULL, 0);
return EOI;
}
while (iident(*++ptr)); while (iident(*++ptr));
if (*ptr == '[' || (!cct && *ptr == '(')) { if (*ptr == '[' || (!cct && *ptr == '(')) {
char op = *ptr, cp = ((*ptr == '[') ? ']' : ')'); char op = *ptr, cp = ((*ptr == '[') ? ']' : ')');
@ -417,7 +405,7 @@ zzlex(void)
} }
q = *ptr; q = *ptr;
*ptr = '\0'; *ptr = '\0';
lvals[yylval = lvc++] = ztrdup(p); yylval = dupstring(p);
*ptr = q; *ptr = q;
return (func ? FUNC : (cct ? CID : ID)); return (func ? FUNC : (cct ? CID : ID));
} }
@ -436,7 +424,7 @@ static int mtok; /* last token */
static int sp = -1; /* stack pointer */ static int sp = -1; /* stack pointer */
struct mathvalue { struct mathvalue {
LV lval; char *lval;
mnumber val; mnumber val;
}; };
@ -444,7 +432,7 @@ static struct mathvalue *stack;
/**/ /**/
static void static void
push(mnumber val, LV lval) push(mnumber val, char *lval)
{ {
if (sp == STACKSZ - 1) if (sp == STACKSZ - 1)
zerr("stack overflow", NULL, 0); zerr("stack overflow", NULL, 0);
@ -457,13 +445,13 @@ push(mnumber val, LV lval)
/**/ /**/
static mnumber static mnumber
getcvar(LV s) getcvar(char *s)
{ {
char *t; char *t;
mnumber mn; mnumber mn;
mn.type = MN_INTEGER; mn.type = MN_INTEGER;
if (!(t = getsparam(lvals[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);
@ -473,16 +461,16 @@ getcvar(LV s)
/**/ /**/
static mnumber static mnumber
setvar(LV s, mnumber v) setvar(char *s, mnumber v)
{ {
if (s == -1 || s >= lvc) { if (!s) {
zerr("lvalue required", NULL, 0); zerr("lvalue required", NULL, 0);
v.type = MN_INTEGER; v.type = MN_INTEGER;
v.u.l = 0; v.u.l = 0;
} }
if (noeval) if (noeval)
return v; return v;
setnparam(lvals[s], v); setnparam(s, v);
return v; return v;
} }
@ -507,7 +495,7 @@ callmathfunc(char *o)
return f->sfunc(n, a, f->funcid); return f->sfunc(n, a, f->funcid);
else { else {
int argc = 0; int argc = 0;
mnumber *argv, *q; mnumber *argv = NULL, *q;
LinkList l = newlinklist(); LinkList l = newlinklist();
LinkNode node; LinkNode node;
char *p; char *p;
@ -563,7 +551,7 @@ void
op(int what) op(int what)
{ {
mnumber a, b, c, *spval; mnumber a, b, c, *spval;
LV lv; char *lv;
int tp = type[what]; int tp = type[what];
if (errflag) if (errflag)
@ -574,10 +562,8 @@ 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)) {
if (sp < 1) { /* Make sure anyone seeing this message reports it. */
zerr("bad math expression: unbalanced stack", NULL, 0); \ DPUTS(sp < 1, "BUG: math: not enough wallabies in outback.");
return;
}
b = stack[sp--].val; b = stack[sp--].val;
a = stack[sp--].val; a = stack[sp--].val;
@ -610,6 +596,11 @@ op(int what)
b.u.d = (double)b.u.l; b.u.d = (double)b.u.l;
} }
} }
if (noeval) {
c.type = MN_INTEGER;
c.u.l = 0;
} else {
/* /*
* type for operation: usually same as operands, but e.g. * type for operation: usually same as operands, but e.g.
* (a == b) returns int. * (a == b) returns int.
@ -740,11 +731,12 @@ op(int what)
c = b; c = b;
break; break;
} }
}
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);
} else } else
push(c,-1); push(c,NULL);
return; return;
} }
@ -756,7 +748,7 @@ op(int what)
spval->type = MN_INTEGER; spval->type = MN_INTEGER;
} else } else
spval->u.l = !spval->u.l; spval->u.l = !spval->u.l;
stack[sp].lval = -1; stack[sp].lval = NULL;
break; break;
case COMP: case COMP:
if (spval->type & MN_FLOAT) { if (spval->type & MN_FLOAT) {
@ -764,7 +756,7 @@ op(int what)
spval->type = MN_INTEGER; spval->type = MN_INTEGER;
} else } else
spval->u.l = ~spval->u.l; spval->u.l = ~spval->u.l;
stack[sp].lval = -1; stack[sp].lval = NULL;
break; break;
case POSTPLUS: case POSTPLUS:
a = *spval; a = *spval;
@ -783,25 +775,22 @@ op(int what)
(void)setvar(stack[sp].lval, a); (void)setvar(stack[sp].lval, a);
break; break;
case UPLUS: case UPLUS:
stack[sp].lval = -1; stack[sp].lval = NULL;
break; break;
case UMINUS: case UMINUS:
if (spval->type & MN_FLOAT) if (spval->type & MN_FLOAT)
spval->u.d = -spval->u.d; spval->u.d = -spval->u.d;
else else
spval->u.l = -spval->u.l; spval->u.l = -spval->u.l;
stack[sp].lval = -1; stack[sp].lval = NULL;
break; break;
case QUEST: case QUEST:
if (sp < 2) { DPUTS(sp < 2, "BUG: math: three shall be the number of the counting.");
zerr("bad math expression: unbalanced stack", NULL, 0);
return;
}
c = stack[sp--].val; c = stack[sp--].val;
b = stack[sp--].val; b = stack[sp--].val;
a = stack[sp--].val; a = stack[sp--].val;
/* 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, -1); push(((a.type & MN_FLOAT) ? a.u.d : a.u.l) ? b : c, NULL);
break; break;
case COLON: case COLON:
break; break;
@ -852,48 +841,41 @@ bop(int tk)
static mnumber static mnumber
mathevall(char *s, int prek, char **ep) mathevall(char *s, int prek, char **ep)
{ {
int t0; int xlastbase, xnoeval, xunary;
int xlastbase, xnoeval, xunary, xlvc;
char *xptr; char *xptr;
mnumber xyyval; mnumber xyyval;
LV xyylval; char *xyylval;
char **xlvals = 0, *nlvals[LVCOUNT];
int xsp; int xsp;
struct mathvalue *xstack = 0, nstack[STACKSZ]; struct mathvalue *xstack = 0, nstack[STACKSZ];
mnumber ret; mnumber ret;
MUSTUSEHEAP("mathevall");
if (mlevel++) { if (mlevel++) {
xlastbase = lastbase; xlastbase = lastbase;
xnoeval = noeval; xnoeval = noeval;
xunary = unary; xunary = unary;
xlvc = lvc;
xptr = ptr; xptr = ptr;
xyyval = yyval; xyyval = yyval;
xyylval = yylval; xyylval = yylval;
xlvals = lvals;
xsp = sp; xsp = sp;
xstack = stack; xstack = stack;
} else { } else {
xlastbase = xnoeval = xunary = xlvc = xyylval = xsp = 0; xlastbase = xnoeval = xunary = xsp = 0;
xyyval.type = MN_INTEGER; xyyval.type = MN_INTEGER;
xyyval.u.l = 0; xyyval.u.l = 0;
xyylval = NULL;
xptr = NULL; xptr = NULL;
} }
stack = nstack; stack = nstack;
lastbase = -1; lastbase = -1;
memset(nlvals, 0, LVCOUNT*sizeof(char *));
lvals = nlvals;
lvc = 0;
ptr = s; ptr = s;
sp = -1; sp = -1;
unary = 1; unary = 1;
mathparse(prek); mathparse(prek);
*ep = ptr; *ep = ptr;
if (sp) DPUTS(!errflag && sp,
zerr("bad math expression: unbalanced stack", NULL, 0); "BUG: math: wallabies roaming too freely in outback");
for (t0 = 0; t0 != lvc; t0++)
zsfree(lvals[t0]);
ret = stack[0].val; ret = stack[0].val;
@ -901,11 +883,9 @@ mathevall(char *s, int prek, char **ep)
lastbase = xlastbase; lastbase = xlastbase;
noeval = xnoeval; noeval = xnoeval;
unary = xunary; unary = xunary;
lvc = xlvc;
ptr = xptr; ptr = xptr;
yyval = xyyval; yyval = xyyval;
yylval = xyylval; yylval = xyylval;
lvals = xlvals;
sp = xsp; sp = xsp;
stack = xstack; stack = xstack;
@ -964,9 +944,10 @@ mathevalarg(char *s, char **ss)
/**/ /**/
static void static void
checkunary(int tp, char *ptr) checkunary(int mtokc, char *ptr)
{ {
int errmsg = 0; int errmsg = 0;
int tp = type[mtokc];
if (tp & (OP_A2|OP_A2IR|OP_A2IO|OP_E2|OP_E2IO|OP_OP)) { if (tp & (OP_A2|OP_A2IR|OP_A2IO|OP_E2|OP_E2IO|OP_OP)) {
if (unary) if (unary)
errmsg = 1; errmsg = 1;
@ -1005,22 +986,22 @@ mathparse(int pc)
if (errflag) if (errflag)
return; return;
mtok = zzlex(); mtok = zzlex();
checkunary(type[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, -1); push(yyval, NULL);
break; break;
case ID: case ID:
push(getnparam(lvals[yylval]), yylval); push(getnparam(yylval), yylval);
break; break;
case CID: case CID:
push(getcvar(yylval), yylval); push(getcvar(yylval), yylval);
break; break;
case FUNC: case FUNC:
push(callmathfunc(lvals[yylval]), yylval); push(callmathfunc(yylval), yylval);
break; break;
case M_INPAR: case M_INPAR:
mathparse(TOPPREC); mathparse(TOPPREC);
@ -1036,10 +1017,15 @@ mathparse(int pc)
if (!q) if (!q)
noeval++; noeval++;
mathparse(prec[QUEST] - 1); mathparse(prec[COLON] - 1);
if (!q) if (!q)
noeval--; noeval--;
else if (mtok != COLON) {
if (!errflag)
zerr("':' expected", NULL, 0);
return;
}
if (q)
noeval++; noeval++;
mathparse(prec[QUEST]); mathparse(prec[QUEST]);
if (q) if (q)
@ -1058,6 +1044,6 @@ mathparse(int pc)
} }
optr = ptr; optr = ptr;
mtok = zzlex(); mtok = zzlex();
checkunary(type[mtok], optr); checkunary(mtok, optr);
} }
} }