summaryrefslogtreecommitdiffstats
path: root/Src/math.c
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>1999-09-22 13:04:17 +0000
committerTanaka Akira <akr@users.sourceforge.net>1999-09-22 13:04:17 +0000
commit6f698f634a85d0b3d34b5566d1adb807de577e86 (patch)
tree72a9d25d8c311373ca2129b412f458864e76d68e /Src/math.c
parentzsh-workers/7974 (diff)
downloadzsh-6f698f634a85d0b3d34b5566d1adb807de577e86.tar
zsh-6f698f634a85d0b3d34b5566d1adb807de577e86.tar.gz
zsh-6f698f634a85d0b3d34b5566d1adb807de577e86.tar.bz2
zsh-6f698f634a85d0b3d34b5566d1adb807de577e86.tar.lz
zsh-6f698f634a85d0b3d34b5566d1adb807de577e86.tar.xz
zsh-6f698f634a85d0b3d34b5566d1adb807de577e86.tar.zst
zsh-6f698f634a85d0b3d34b5566d1adb807de577e86.zip
zsh-workers/7976
Diffstat (limited to 'Src/math.c')
-rw-r--r--Src/math.c79
1 files changed, 72 insertions, 7 deletions
diff --git a/Src/math.c b/Src/math.c
index e044cbd9f..3fb741854 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -141,7 +141,8 @@ static int unary = 1;
#define POWER 49
#define CID 50
#define POWEREQ 51
-#define TOKCOUNT 52
+#define FUNC 52
+#define TOKCOUNT 53
/* precedences */
@@ -157,7 +158,7 @@ static int prec[TOKCOUNT] =
15, 15, 15, 15, 15,
15, 15, 15, 16, 200,
2, 2, 0, 0, 7,
- 0, 15
+ 0, 15, 0
};
#define TOPPREC 16
@@ -175,7 +176,7 @@ static int type[TOKCOUNT] =
/* 35 */ RL|OP_E2IO, RL|OP_E2IO, RL|OP_E2IO, RL|OP_E2IO, RL|OP_E2IO,
/* 40 */ BOOL|OP_E2IO, BOOL|OP_E2IO, RL|OP_A2IO, RL|OP_A2, RL|OP_OP,
/* 45 */ RL, RL, LR|OP_OPF, LR|OP_OPF, RL|OP_A2,
-/* 50 */ LR|OP_OPF, RL|OP_E2
+/* 50 */ LR|OP_OPF, RL|OP_E2, LR|OP_OPF
};
#define LVCOUNT 32
@@ -392,6 +393,7 @@ zzlex(void)
cct = 1;
}
if (iident(*ptr)) {
+ int func = 0;
char *p, q;
p = ptr;
@@ -400,12 +402,14 @@ zzlex(void)
return EOI;
}
while (iident(*++ptr));
- if (*ptr == '[') {
+ if (*ptr == '[' || (!cct && *ptr == '(')) {
+ char op = *ptr, cp = ((*ptr == '[') ? ']' : ')');
int l;
+ func = (op == '(');
for (ptr++, l = 1; *ptr && l; ptr++) {
- if (*ptr == '[')
+ if (*ptr == op)
l++;
- if (*ptr == ']')
+ if (*ptr == cp)
l--;
if (*ptr == '\\' && ptr[1])
ptr++;
@@ -415,7 +419,7 @@ zzlex(void)
*ptr = '\0';
lvals[yylval = lvc++] = ztrdup(p);
*ptr = q;
- return cct ? CID : ID;
+ return (func ? FUNC : (cct ? CID : ID));
}
else if (cct) {
yyval.u.l = poundgetfn(NULL);
@@ -484,6 +488,64 @@ setvar(LV s, mnumber v)
/**/
+static mnumber
+callmathfunc(char *o)
+{
+ MathFunc f;
+ char *a, *n;
+ static mnumber dummy;
+
+ n = a = dupstring(o);
+
+ while (*a != '(')
+ a++;
+ *a++ = '\0';
+ a[strlen(a) - 1] = '\0';
+
+ if ((f = getmathfunc(n, 1))) {
+ if (f->flags & MFF_STR)
+ return f->sfunc(n, a, f->funcid);
+ else {
+ int argc = 0;
+ mnumber *argv, *q;
+ LinkList l = newlinklist();
+ LinkNode node;
+ char *p;
+
+ if (*a) {
+ for (p = a; *a; a++) {
+ if (*a == '\\' && a[1])
+ a++;
+ else if (*a == ',') {
+ *a = '\0';
+ addlinknode(l, p);
+ argc++;
+ p = a + 1;
+ }
+ }
+ addlinknode(l, p);
+ argc++;
+ }
+ if (argc >= f->minargs && (f->maxargs < 0 || argc <= f->maxargs)) {
+ if (argc) {
+ q = argv = (mnumber *) zhalloc(argc * sizeof(mnumber));
+ for (node = firstnode(l); node; incnode(node))
+ *q++ = matheval((char *) getdata(node));
+ }
+ return f->nfunc(n, argc, argv, f->funcid);
+ } else
+ zerr("wrong number of argument: %s", o, 0);
+ }
+ } else
+ zerr("unknown function: %s", n, 0);
+
+ dummy.type = MN_INTEGER;
+ dummy.u.l = 0;
+
+ return dummy;
+}
+
+/**/
static int
notzero(mnumber a)
{
@@ -957,6 +1019,9 @@ mathparse(int pc)
case CID:
push(getcvar(yylval), yylval);
break;
+ case FUNC:
+ push(callmathfunc(lvals[yylval]), yylval);
+ break;
case M_INPAR:
mathparse(TOPPREC);
if (mtok != M_OUTPAR) {