1/* 2 * math.c - mathematical expression evaluation 3 * 4 * This file is part of zsh, the Z shell. 5 * 6 * Copyright (c) 1992-1997 Paul Falstad 7 * All rights reserved. 8 * 9 * Permission is hereby granted, without written agreement and without 10 * license or royalty fees, to use, copy, modify, and distribute this 11 * software and to distribute modified versions of this software for any 12 * purpose, provided that the above copyright notice and the following 13 * two paragraphs appear in all copies of this software. 14 * 15 * In no event shall Paul Falstad or the Zsh Development Group be liable 16 * to any party for direct, indirect, special, incidental, or consequential 17 * damages arising out of the use of this software and its documentation, 18 * even if Paul Falstad and the Zsh Development Group have been advised of 19 * the possibility of such damage. 20 * 21 * Paul Falstad and the Zsh Development Group specifically disclaim any 22 * warranties, including, but not limited to, the implied warranties of 23 * merchantability and fitness for a particular purpose. The software 24 * provided hereunder is on an "as is" basis, and Paul Falstad and the 25 * Zsh Development Group have no obligation to provide maintenance, 26 * support, updates, enhancements, or modifications. 27 * 28 */ 29 30struct mathvalue; 31 32#include "zsh.mdh" 33#include "math.pro" 34 35#include <math.h> 36 37/* nonzero means we are not evaluating, just parsing */ 38 39/**/ 40int noeval; 41 42/* integer zero */ 43 44/**/ 45mod_export mnumber zero_mnumber; 46 47/* 48 * The last value we computed: note this isn't cleared 49 * until the next computation, unlike yyval. 50 * Everything else is saved and returned to allow recursive calls. 51 */ 52/**/ 53mnumber lastmathval; 54 55/* last input base we used */ 56 57/**/ 58int lastbase; 59 60static char *ptr; 61 62static mnumber yyval; 63static char *yylval; 64 65#define MAX_MLEVEL 256 66 67static int mlevel = 0; 68 69/* != 0 means recognize unary plus, minus, etc. */ 70 71static int unary = 1; 72 73/* LR = left-to-right associativity * 74 * RL = right-to-left associativity * 75 * BOOL = short-circuiting boolean */ 76 77#define LR 0x0000 78#define RL 0x0001 79#define BOOL 0x0002 80 81#define MTYPE(x) ((x) & 3) 82 83/* 84 * OP_A2 2 arguments 85 * OP_A2IR 2 arguments, return integer 86 * OP_A2IO 2 arguments, must be integer, return integer 87 * OP_E2 2 arguments with assignment 88 * OP_E2IO 2 arguments with assignment, must be integer, return integer 89 * OP_OP None of the above, but occurs where we are expecting an operator 90 * rather than an operand. 91 * OP_OPF Followed by an operator, not an operand. 92 * 93 * OP_A2*, OP_E2*, OP_OP*: 94 * Occur when we need an operator; the next object must be an operand, 95 * unless OP_OPF is also supplied. 96 * 97 * Others: 98 * Occur when we need an operand; the next object must also be an operand, 99 * unless OP_OPF is also supplied. 100 */ 101#define OP_A2 0x0004 102#define OP_A2IR 0x0008 103#define OP_A2IO 0x0010 104#define OP_E2 0x0020 105#define OP_E2IO 0x0040 106#define OP_OP 0x0080 107#define OP_OPF 0x0100 108 109#define M_INPAR 0 110#define M_OUTPAR 1 111#define NOT 2 112#define COMP 3 113#define POSTPLUS 4 114#define POSTMINUS 5 115#define UPLUS 6 116#define UMINUS 7 117#define AND 8 118#define XOR 9 119#define OR 10 120#define MUL 11 121#define DIV 12 122#define MOD 13 123#define PLUS 14 124#define MINUS 15 125#define SHLEFT 16 126#define SHRIGHT 17 127#define LES 18 128#define LEQ 19 129#define GRE 20 130#define GEQ 21 131#define DEQ 22 132#define NEQ 23 133#define DAND 24 134#define DOR 25 135#define DXOR 26 136#define QUEST 27 137#define COLON 28 138#define EQ 29 139#define PLUSEQ 30 140#define MINUSEQ 31 141#define MULEQ 32 142#define DIVEQ 33 143#define MODEQ 34 144#define ANDEQ 35 145#define XOREQ 36 146#define OREQ 37 147#define SHLEFTEQ 38 148#define SHRIGHTEQ 39 149#define DANDEQ 40 150#define DOREQ 41 151#define DXOREQ 42 152#define COMMA 43 153#define EOI 44 154#define PREPLUS 45 155#define PREMINUS 46 156#define NUM 47 157#define ID 48 158#define POWER 49 159#define CID 50 160#define POWEREQ 51 161#define FUNC 52 162#define TOKCOUNT 53 163 164/* 165 * Opeator recedences: in reverse order, i.e. lower number, high precedence. 166 * These are the C precedences. 167 * 168 * 0 Non-operators: NUM (numeric constant), ID (identifier), 169 * CID (identifier with '#'), FUNC (math function) 170 * 1 Opening parenthesis: M_INPAR '(' (for convenience, not an operator) 171 * 2 Unary operators: PREPLUS/POSTPLUS '++', PREMINUS/POSTMINUS '--', 172 * NOT '!', COMP '~', UPLUS '+', UMINUS '-' 173 * 3 POWER '**' (not in C but at high precedence in Perl) 174 * 4 MUL '*', DIV '/', MOD '%' 175 * 5 PLUS '+', MINUS '-' 176 * 6 SHLEFT '<<', SHRIGHT '>>' 177 * 7 GRE '>', 'GEQ' '>=', LES '<', LEQ '<=' 178 * 8 DEQ '==', NEQ '!=' 179 * 9 AND '&' 180 * 10 XOR '^' 181 * 11 OR '|' 182 * 12 DAND '&&' 183 * 13 DXOR '^^' (not in C) 184 * 14 DOR '||' 185 * 15 QUEST '?' 186 * 16 COLON ':' 187 * 17 EQ '=', PLUSEQ '+=', MINUSEQ '-=', MULEQ '*=', DIVEQ '/=', 188 * MODEQ '%=', ANDEQ '&=', XOREQ '^=', OREQ '|=', 189 * SHFLEFTEQ '<<=', SHRIGHTEQ '>>=', DANDEQ '&&=', DOREQ '||=', 190 * DXOREQ '^^=' 191 * 18 COMMA ',' 192 * 137 M_OUTPAR ')' (for convenience, not an operator) 193 * 200 EOI (end of input: for convenience, not an operator) 194 */ 195static int c_prec[TOKCOUNT] = 196{ 197/* M_INPAR M_OUTPAR NOT COMP POSTPLUS */ 198/* 0 */ 1, 137, 2, 2, 2, 199/* POSTMINUS UPLUS UMINUS AND XOR */ 200/* 5 */ 2, 2, 2, 9, 10, 201/* OR MUL DIV MOD PLUS */ 202/* 10 */ 11, 4, 4, 4, 5, 203/* MINUS SHLEFT SHRIGHT LES LEQ */ 204/* 15 */ 5, 6, 6, 7, 7, 205/* GRE GEQ DEQ NEQ DAND */ 206/* 20 */ 7, 7, 8, 8, 12, 207/* DOR DXOR QUEST COLON EQ */ 208/* 25 */ 14, 13, 15, 16, 17, 209/* PLUSEQ MINUSEQ MULEQ DIVEQ MODEQ */ 210/* 30 */ 17, 17, 17, 17, 17, 211/* ANDEQ XOREQ OREQ SHLEFTEQ SHRIGHTEQ */ 212/* 35 */ 17, 17, 17, 17, 17, 213/* DANDEQ DOREQ DXOREQ COMMA EOI */ 214/* 40 */ 17, 17, 17, 18, 200, 215/* PREPLUS PREMINUS NUM ID POWER */ 216/* 45 */ 2, 2, 0, 0, 3, 217/* CID POWEREQ FUNC */ 218/* 50 */ 0, 17, 0 219}; 220 221/* 222 * Opeator recedences: in reverse order, i.e. lower number, high precedence. 223 * These are the default zsh precedences. 224 * 225 * 0 Non-operators: NUM (numeric constant), ID (identifier), 226 * CID (identifier with '#'), FUNC (math function) 227 * 1 Opening parenthesis: M_INPAR '(' (for convenience, not an operator) 228 * 2 Unary operators: PREPLUS/POSTPLUS '++', PREMINUS/POSTMINUS '--', 229 * NOT '!', COMP '~', UPLUS '+', UMINUS '-' 230 * 3 SHLEFT '<<', SHRIGHT '>>' 231 * 4 AND '&' 232 * 5 XOR '^' 233 * 6 OR '|' 234 * 7 POWER '**' (not in C but at high precedence in Perl) 235 * 8 MUL '*', DIV '/', MOD '%' 236 * 9 PLUS '+', MINUS '-' 237 * 10 GRE '>', 'GEQ' '>=', LES '<', LEQ '<=' 238 * 11 DEQ '==', NEQ '!=' 239 * 12 DAND '&&' 240 * 13 DOR '||', DXOR '^^' (not in C) 241 * 14 QUEST '?' 242 * 15 COLON ':' 243 * 16 EQ '=', PLUSEQ '+=', MINUSEQ '-=', MULEQ '*=', DIVEQ '/=', 244 * MODEQ '%=', ANDEQ '&=', XOREQ '^=', OREQ '|=', 245 * SHFLEFTEQ '<<=', SHRIGHTEQ '>>=', DANDEQ '&&=', DOREQ '||=', 246 * DXOREQ '^^=' 247 * 17 COMMA ',' 248 * 137 M_OUTPAR ')' (for convenience, not an operator) 249 * 200 EOI (end of input: for convenience, not an operator) 250 */ 251static int z_prec[TOKCOUNT] = 252{ 253/* M_INPAR M_OUTPAR NOT COMP POSTPLUS */ 254/* 0 */ 1, 137, 2, 2, 2, 255/* POSTMINUS UPLUS UMINUS AND XOR */ 256/* 5 */ 2, 2, 2, 4, 5, 257/* OR MUL DIV MOD PLUS */ 258/* 10 */ 6, 8, 8, 8, 9, 259/* MINUS SHLEFT SHRIGHT LES LEQ */ 260/* 15 */ 9, 3, 3, 10, 10, 261/* GRE GEQ DEQ NEQ DAND */ 262/* 20 */ 10, 10, 11, 11, 12, 263/* DOR DXOR QUEST COLON EQ */ 264/* 25 */ 13, 13, 14, 15, 16, 265/* PLUSEQ MINUSEQ MULEQ DIVEQ MODEQ */ 266/* 30 */ 16, 16, 16, 16, 16, 267/* ANDEQ XOREQ OREQ SHLEFTEQ SHRIGHTEQ */ 268/* 35 */ 16, 16, 16, 16, 16, 269/* DANDEQ DOREQ DXOREQ COMMA EOI */ 270/* 40 */ 16, 16, 16, 17, 200, 271/* PREPLUS PREMINUS NUM ID POWER */ 272/* 45 */ 2, 2, 0, 0, 7, 273/* CID POWEREQ FUNC */ 274/* 50 */ 0, 16, 0 275}; 276 277/* Option-selectable preference table */ 278static int *prec; 279 280/* 281 * Precedences for top and argument evaluation. Careful: 282 * prec needs to be set before we use these. 283 */ 284#define TOPPREC (prec[COMMA]+1) 285#define ARGPREC (prec[COMMA]-1) 286 287static int type[TOKCOUNT] = 288{ 289/* 0 */ LR, LR|OP_OP|OP_OPF, RL, RL, RL|OP_OP|OP_OPF, 290/* 5 */ RL|OP_OP|OP_OPF, RL, RL, LR|OP_A2IO, LR|OP_A2IO, 291/* 10 */ LR|OP_A2IO, LR|OP_A2, LR|OP_A2, LR|OP_A2IO, LR|OP_A2, 292/* 15 */ LR|OP_A2, LR|OP_A2IO, LR|OP_A2IO, LR|OP_A2IR, LR|OP_A2IR, 293/* 20 */ LR|OP_A2IR, LR|OP_A2IR, LR|OP_A2IR, LR|OP_A2IR, BOOL|OP_A2IO, 294/* 25 */ BOOL|OP_A2IO, LR|OP_A2IO, RL|OP_OP, RL|OP_OP, RL|OP_E2, 295/* 30 */ RL|OP_E2, RL|OP_E2, RL|OP_E2, RL|OP_E2, RL|OP_E2IO, 296/* 35 */ RL|OP_E2IO, RL|OP_E2IO, RL|OP_E2IO, RL|OP_E2IO, RL|OP_E2IO, 297/* 40 */ BOOL|OP_E2IO, BOOL|OP_E2IO, RL|OP_A2IO, RL|OP_A2, RL|OP_OP, 298/* 45 */ RL, RL, LR|OP_OPF, LR|OP_OPF, RL|OP_A2, 299/* 50 */ LR|OP_OPF, RL|OP_E2, LR|OP_OPF 300}; 301 302/* the value stack */ 303 304#define STACKSZ 100 305static int mtok; /* last token */ 306static int sp = -1; /* stack pointer */ 307 308struct mathvalue { 309 /* 310 * If we need to get a variable, this is the string to be passed 311 * to the parameter code. It may include a subscript. 312 */ 313 char *lval; 314 /* 315 * If this is not zero, we've retrieved a variable and this 316 * stores a reference to it. 317 */ 318 Value pval; 319 mnumber val; 320}; 321 322static struct mathvalue *stack; 323 324enum prec_type { 325 /* Evaluating a top-level expression */ 326 MPREC_TOP, 327 /* Evaluating a function argument */ 328 MPREC_ARG 329}; 330 331 332/* 333 * Get a number from a variable. 334 * Try to be clever about reusing subscripts by caching the Value structure. 335 */ 336static mnumber 337getmathparam(struct mathvalue *mptr) 338{ 339 if (!mptr->pval) { 340 char *s = mptr->lval; 341 mptr->pval = (Value)zhalloc(sizeof(struct value)); 342 if (!getvalue(mptr->pval, &s, 1)) 343 { 344 mptr->pval = NULL; 345 return zero_mnumber; 346 } 347 } 348 return getnumvalue(mptr->pval); 349} 350 351static mnumber 352mathevall(char *s, enum prec_type prec_tp, char **ep) 353{ 354 int xlastbase, xnoeval, xunary, *xprec; 355 char *xptr; 356 mnumber xyyval; 357 char *xyylval; 358 int xsp; 359 struct mathvalue *xstack = 0, nstack[STACKSZ]; 360 mnumber ret; 361 362 if (mlevel >= MAX_MLEVEL) { 363 xyyval.type = MN_INTEGER; 364 xyyval.u.l = 0; 365 366 zerr("math recursion limit exceeded"); 367 368 return xyyval; 369 } 370 if (mlevel++) { 371 xlastbase = lastbase; 372 xnoeval = noeval; 373 xunary = unary; 374 xptr = ptr; 375 xyyval = yyval; 376 xyylval = yylval; 377 378 xsp = sp; 379 xstack = stack; 380 xprec = prec; 381 } else { 382 xlastbase = xnoeval = xunary = xsp = 0; 383 xyyval.type = MN_INTEGER; 384 xyyval.u.l = 0; 385 xyylval = NULL; 386 xptr = NULL; 387 xprec = NULL; 388 } 389 prec = isset(CPRECEDENCES) ? c_prec : z_prec; 390 stack = nstack; 391 lastbase = -1; 392 ptr = s; 393 sp = -1; 394 unary = 1; 395 stack[0].val.type = MN_INTEGER; 396 stack[0].val.u.l = 0; 397 mathparse(prec_tp == MPREC_TOP ? TOPPREC : ARGPREC); 398 *ep = ptr; 399 DPUTS(!errflag && sp > 0, 400 "BUG: math: wallabies roaming too freely in outback"); 401 402 if (errflag) { 403 /* 404 * This used to set the return value to errflag. 405 * I don't understand how that could be useful; the 406 * caller doesn't know that's what's happened and 407 * may not get a value at all. 408 * Worse, we reset errflag in execarith() and setting 409 * this explicitly non-zero means a (( ... )) returns 410 * status 0 if there's an error. That surely can't 411 * be right. execarith() now detects an error and returns 412 * status 2. 413 */ 414 ret.type = MN_INTEGER; 415 ret.u.l = 0; 416 } else { 417 if (stack[0].val.type == MN_UNSET) 418 ret = getmathparam(stack); 419 else 420 ret = stack[0].val; 421 } 422 423 if (--mlevel) { 424 lastbase = xlastbase; 425 noeval = xnoeval; 426 unary = xunary; 427 ptr = xptr; 428 yyval = xyyval; 429 yylval = xyylval; 430 431 sp = xsp; 432 stack = xstack; 433 prec = xprec; 434 } 435 return lastmathval = ret; 436} 437 438static int 439lexconstant(void) 440{ 441#ifdef USE_LOCALE 442 char *prev_locale; 443#endif 444 char *nptr; 445 446 nptr = ptr; 447 if (*nptr == '-') 448 nptr++; 449 450 if (*nptr == '0' && 451 (memchr(nptr, '.', strlen(nptr)) == NULL)) 452 { 453 nptr++; 454 if (*nptr == 'x' || *nptr == 'X') { 455 /* Let zstrtol parse number with base */ 456 yyval.u.l = zstrtol_underscore(ptr, &ptr, 0, 1); 457 /* Should we set lastbase here? */ 458 lastbase = 16; 459 return NUM; 460 } 461 else if (isset(OCTALZEROES)) 462 { 463 char *ptr2; 464 465 /* 466 * Make sure this is a real octal constant; 467 * it can't be a base indication (always decimal) 468 * or a floating point number. 469 */ 470 for (ptr2 = nptr; idigit(*ptr2) || *ptr2 == '_'; ptr2++) 471 ; 472 473 if (ptr2 > nptr && *ptr2 != '.' && *ptr2 != 'e' && 474 *ptr2 != 'E' && *ptr2 != '#') 475 { 476 yyval.u.l = zstrtol_underscore(ptr, &ptr, 0, 1); 477 lastbase = 8; 478 return NUM; 479 } 480 nptr = ptr2; 481 } 482 } 483 else 484 { 485 while (idigit(*nptr) || *nptr == '_') 486 nptr++; 487 } 488 489 if (*nptr == '.' || *nptr == 'e' || *nptr == 'E') { 490 char *ptr2; 491 /* it's a float */ 492 yyval.type = MN_FLOAT; 493#ifdef USE_LOCALE 494 prev_locale = dupstring(setlocale(LC_NUMERIC, NULL)); 495 setlocale(LC_NUMERIC, "POSIX"); 496#endif 497 if (*nptr == '.') { 498 nptr++; 499 while (idigit(*nptr) || *nptr == '_') 500 nptr++; 501 } 502 if (*nptr == 'e' || *nptr == 'E') { 503 nptr++; 504 if (*nptr == '+' || *nptr == '-') 505 nptr++; 506 while (idigit(*nptr) || *nptr == '_') 507 nptr++; 508 } 509 for (ptr2 = ptr; ptr2 < nptr; ptr2++) { 510 if (*ptr2 == '_') { 511 int len = nptr - ptr; 512 ptr = strdup(ptr); 513 for (ptr2 = ptr; len; len--) { 514 if (*ptr2 == '_') 515 chuck(ptr2); 516 else 517 ptr2++; 518 } 519 break; 520 } 521 } 522 yyval.u.d = strtod(ptr, &nptr); 523#ifdef USE_LOCALE 524 if (prev_locale) setlocale(LC_NUMERIC, prev_locale); 525#endif 526 if (ptr == nptr || *nptr == '.') { 527 zerr("bad floating point constant"); 528 return EOI; 529 } 530 ptr = nptr; 531 } else { 532 /* it's an integer */ 533 yyval.u.l = zstrtol_underscore(ptr, &ptr, 10, 1); 534 535 if (*ptr == '#') { 536 ptr++; 537 lastbase = yyval.u.l; 538 yyval.u.l = zstrtol_underscore(ptr, &ptr, lastbase, 1); 539 } 540 } 541 return NUM; 542} 543 544/**/ 545int outputradix; 546 547/**/ 548static int 549zzlex(void) 550{ 551 int cct = 0; 552 char *ie; 553 yyval.type = MN_INTEGER; 554 555 for (;; cct = 0) 556 switch (*ptr++) { 557 case '+': 558 if (*ptr == '+') { 559 ptr++; 560 return (unary) ? PREPLUS : POSTPLUS; 561 } 562 if (*ptr == '=') { 563 ptr++; 564 return PLUSEQ; 565 } 566 return (unary) ? UPLUS : PLUS; 567 case '-': 568 if (*ptr == '-') { 569 ptr++; 570 return (unary) ? PREMINUS : POSTMINUS; 571 } 572 if (*ptr == '=') { 573 ptr++; 574 return MINUSEQ; 575 } 576 if (unary) { 577 if (idigit(*ptr) || *ptr == '.') { 578 ptr--; 579 return lexconstant(); 580 } else 581 return UMINUS; 582 } else 583 return MINUS; 584 case '(': 585 return M_INPAR; 586 case ')': 587 return M_OUTPAR; 588 case '!': 589 if (*ptr == '=') { 590 ptr++; 591 return NEQ; 592 } 593 return NOT; 594 case '~': 595 return COMP; 596 case '&': 597 if (*ptr == '&') { 598 if (*++ptr == '=') { 599 ptr++; 600 return DANDEQ; 601 } 602 return DAND; 603 } else if (*ptr == '=') { 604 ptr++; 605 return ANDEQ; 606 } 607 return AND; 608 case '|': 609 if (*ptr == '|') { 610 if (*++ptr == '=') { 611 ptr++; 612 return DOREQ; 613 } 614 return DOR; 615 } else if (*ptr == '=') { 616 ptr++; 617 return OREQ; 618 } 619 return OR; 620 case '^': 621 if (*ptr == '^') { 622 if (*++ptr == '=') { 623 ptr++; 624 return DXOREQ; 625 } 626 return DXOR; 627 } else if (*ptr == '=') { 628 ptr++; 629 return XOREQ; 630 } 631 return XOR; 632 case '*': 633 if (*ptr == '*') { 634 if (*++ptr == '=') { 635 ptr++; 636 return POWEREQ; 637 } 638 return POWER; 639 } 640 if (*ptr == '=') { 641 ptr++; 642 return MULEQ; 643 } 644 return MUL; 645 case '/': 646 if (*ptr == '=') { 647 ptr++; 648 return DIVEQ; 649 } 650 return DIV; 651 case '%': 652 if (*ptr == '=') { 653 ptr++; 654 return MODEQ; 655 } 656 return MOD; 657 case '<': 658 if (*ptr == '<') { 659 if (*++ptr == '=') { 660 ptr++; 661 return SHLEFTEQ; 662 } 663 return SHLEFT; 664 } else if (*ptr == '=') { 665 ptr++; 666 return LEQ; 667 } 668 return LES; 669 case '>': 670 if (*ptr == '>') { 671 if (*++ptr == '=') { 672 ptr++; 673 return SHRIGHTEQ; 674 } 675 return SHRIGHT; 676 } else if (*ptr == '=') { 677 ptr++; 678 return GEQ; 679 } 680 return GRE; 681 case '=': 682 if (*ptr == '=') { 683 ptr++; 684 return DEQ; 685 } 686 return EQ; 687 case '$': 688 yyval.u.l = mypid; 689 return NUM; 690 case '?': 691 if (unary) { 692 yyval.u.l = lastval; 693 return NUM; 694 } 695 return QUEST; 696 case ':': 697 return COLON; 698 case ',': 699 return COMMA; 700 case '\0': 701 ptr--; 702 return EOI; 703 case '[': 704 { 705 int n; 706 707 if (idigit(*ptr)) { 708 n = zstrtol(ptr, &ptr, 10); 709 if (*ptr != ']' || !idigit(*++ptr)) { 710 zerr("bad base syntax"); 711 return EOI; 712 } 713 yyval.u.l = zstrtol(ptr, &ptr, lastbase = n); 714 return NUM; 715 } 716 if (*ptr == '#') { 717 n = 1; 718 if (*++ptr == '#') { 719 n = -1; 720 ptr++; 721 } 722 if (!idigit(*ptr)) 723 goto bofs; 724 outputradix = n * zstrtol(ptr, &ptr, 10); 725 } else { 726 bofs: 727 zerr("bad output format specification"); 728 return EOI; 729 } 730 if(*ptr != ']') 731 goto bofs; 732 n = (outputradix < 0) ? -outputradix : outputradix; 733 if (n < 2 || n > 36) { 734 zerr("invalid base (must be 2 to 36 inclusive): %d", 735 outputradix); 736 return EOI; 737 } 738 ptr++; 739 break; 740 } 741 case ' ': 742 case '\t': 743 case '\n': 744 break; 745 /* Fall through! */ 746 default: 747 if (idigit(*--ptr) || *ptr == '.') 748 return lexconstant(); 749 if (*ptr == '#') { 750 if (*++ptr == '\\' || *ptr == '#') { 751 int v; 752 753 ptr++; 754 if (!*ptr) { 755 zerr("character missing after ##"); 756 return EOI; 757 } 758 ptr = getkeystring(ptr, NULL, GETKEYS_MATH, &v); 759 yyval.u.l = v; 760 return NUM; 761 } 762 cct = 1; 763 } 764 if ((ie = itype_end(ptr, IIDENT, 0)) != ptr) { 765 int func = 0; 766 char *p; 767 768 p = ptr; 769 ptr = ie; 770 if (*ptr == '[' || (!cct && *ptr == '(')) { 771 char op = *ptr, cp = ((*ptr == '[') ? ']' : ')'); 772 int l; 773 func = (op == '('); 774 for (ptr++, l = 1; *ptr && l; ptr++) { 775 if (*ptr == op) 776 l++; 777 if (*ptr == cp) 778 l--; 779 if (*ptr == '\\' && ptr[1]) 780 ptr++; 781 } 782 } 783 yylval = dupstrpfx(p, ptr - p); 784 return (func ? FUNC : (cct ? CID : ID)); 785 } 786 else if (cct) { 787 yyval.u.l = poundgetfn(NULL); 788 return NUM; 789 } 790 return EOI; 791 } 792} 793 794/**/ 795static void 796push(mnumber val, char *lval, int getme) 797{ 798 if (sp == STACKSZ - 1) 799 zerr("stack overflow"); 800 else 801 sp++; 802 stack[sp].val = val; 803 stack[sp].lval = lval; 804 stack[sp].pval = NULL; 805 if (getme) 806 stack[sp].val.type = MN_UNSET; 807} 808 809/**/ 810static mnumber 811pop(int noget) 812{ 813 struct mathvalue *mv = stack+sp; 814 815 if (mv->val.type == MN_UNSET && !noget) 816 mv->val = getmathparam(mv); 817 sp--; 818 return errflag ? zero_mnumber : mv->val; 819} 820 821/**/ 822static mnumber 823getcvar(char *s) 824{ 825 char *t; 826 mnumber mn; 827 mn.type = MN_INTEGER; 828 829 queue_signals(); 830 if (!(t = getsparam(s))) 831 mn.u.l = 0; 832 else { 833#ifdef MULTIBYTE_SUPPORT 834 if (isset(MULTIBYTE)) { 835 wint_t wc; 836 (void)mb_metacharlenconv(t, &wc); 837 if (wc != WEOF) { 838 mn.u.l = (zlong)wc; 839 unqueue_signals(); 840 return mn; 841 } 842 } 843#endif 844 mn.u.l = STOUC(*t == Meta ? t[1] ^ 32 : *t); 845 } 846 unqueue_signals(); 847 return mn; 848} 849 850 851/**/ 852static mnumber 853setmathvar(struct mathvalue *mvp, mnumber v) 854{ 855 if (mvp->pval) { 856 /* 857 * This value may have been hanging around for a while. 858 * Be ultra-paranoid in checking the variable is still valid. 859 */ 860 char *s = mvp->lval, *ptr; 861 Param pm; 862 DPUTS(!mvp->lval, "no variable name but variable value in math"); 863 if ((ptr = strchr(s, '['))) 864 s = dupstrpfx(s, ptr - s); 865 pm = (Param) paramtab->getnode(paramtab, s); 866 if (pm == mvp->pval->pm) { 867 if (noeval) 868 return v; 869 setnumvalue(mvp->pval, v); 870 return v; 871 } 872 /* Different parameter, start again from scratch */ 873 mvp->pval = NULL; 874 } 875 if (!mvp->lval) { 876 zerr("lvalue required"); 877 v.type = MN_INTEGER; 878 v.u.l = 0; 879 return v; 880 } 881 if (noeval) 882 return v; 883 untokenize(mvp->lval); 884 setnparam(mvp->lval, v); 885 return v; 886} 887 888 889/**/ 890static mnumber 891callmathfunc(char *o) 892{ 893 MathFunc f; 894 char *a, *n; 895 static mnumber dummy; 896 897 n = a = dupstring(o); 898 899 while (*a != '(') 900 a++; 901 *a++ = '\0'; 902 a[strlen(a) - 1] = '\0'; 903 904 if ((f = getmathfunc(n, 1))) { 905 if (f->flags & MFF_STR) { 906 return f->sfunc(n, a, f->funcid); 907 } else { 908 int argc = 0; 909 mnumber *argv = NULL, *q, marg; 910 LinkList l = newlinklist(); 911 LinkNode node; 912 913 if (f->flags & MFF_USERFUNC) { 914 /* first argument is function name: always use mathfunc */ 915 addlinknode(l, n); 916 } 917 918 while (iblank(*a)) 919 a++; 920 while (*a) { 921 if (*a) { 922 argc++; 923 if (f->flags & MFF_USERFUNC) { 924 /* need to pass strings */ 925 char *str; 926 marg = mathevall(a, MPREC_ARG, &a); 927 if (marg.type & MN_FLOAT) { 928 /* convfloat is off the heap */ 929 str = convfloat(marg.u.d, 0, 0, NULL); 930 } else { 931 char buf[BDIGBUFSIZE]; 932 convbase(buf, marg.u.l, 10); 933 str = dupstring(buf); 934 } 935 addlinknode(l, str); 936 } else { 937 q = (mnumber *) zhalloc(sizeof(mnumber)); 938 *q = mathevall(a, MPREC_ARG, &a); 939 addlinknode(l, q); 940 } 941 if (errflag || mtok != COMMA) 942 break; 943 } 944 } 945 if (*a && !errflag) 946 zerr("bad math expression: illegal character: %c", *a); 947 if (!errflag) { 948 if (argc >= f->minargs && (f->maxargs < 0 || 949 argc <= f->maxargs)) { 950 if (f->flags & MFF_USERFUNC) { 951 char *shfnam = f->module ? f->module : n; 952 Shfunc shfunc = getshfunc(shfnam); 953 if (!shfunc) 954 zerr("no such function: %s", shfnam); 955 else { 956 doshfunc(shfunc, l, 1); 957 return lastmathval; 958 } 959 } else { 960 if (argc) { 961 q = argv = 962 (mnumber *)zhalloc(argc * sizeof(mnumber)); 963 for (node = firstnode(l); node; incnode(node)) 964 *q++ = *(mnumber *)getdata(node); 965 } 966 return f->nfunc(n, argc, argv, f->funcid); 967 } 968 } else 969 zerr("wrong number of arguments: %s", o); 970 } 971 } 972 } else { 973 zerr("unknown function: %s", n); 974 } 975 976 dummy.type = MN_INTEGER; 977 dummy.u.l = 0; 978 979 return dummy; 980} 981 982/**/ 983static int 984notzero(mnumber a) 985{ 986 if ((a.type & MN_INTEGER) ? a.u.l == 0 : a.u.d == 0.0) { 987 zerr("division by zero"); 988 return 0; 989 } 990 return 1; 991} 992 993/* macro to pop three values off the value stack */ 994 995/**/ 996void 997op(int what) 998{ 999 mnumber a, b, c, *spval; 1000 int tp = type[what]; 1001 1002 if (errflag) 1003 return; 1004 if (sp < 0) { 1005 zerr("bad math expression: stack empty"); 1006 return; 1007 } 1008 1009 if (tp & (OP_A2|OP_A2IR|OP_A2IO|OP_E2|OP_E2IO)) { 1010 /* Make sure anyone seeing this message reports it. */ 1011 DPUTS(sp < 1, "BUG: math: not enough wallabies in outback."); 1012 b = pop(0); 1013 a = pop(what == EQ); 1014 if (errflag) 1015 return; 1016 1017 if (tp & (OP_A2IO|OP_E2IO)) { 1018 /* coerce to integers */ 1019 if (a.type & MN_FLOAT) { 1020 a.type = MN_INTEGER; 1021 a.u.l = (zlong)a.u.d; 1022 } 1023 if (b.type & MN_FLOAT) { 1024 b.type = MN_INTEGER; 1025 b.u.l = (zlong)b.u.d; 1026 } 1027 } else if (a.type != b.type && what != COMMA && 1028 (a.type != MN_UNSET || what != EQ)) { 1029 /* 1030 * Different types, so coerce to float. 1031 * It may happen during an assignment that the LHS 1032 * variable is actually an integer, but there's still 1033 * no harm in doing the arithmetic in floating point; 1034 * the assignment will do the correct conversion. 1035 * This way, if the parameter is actually a scalar, but 1036 * used to contain an integer, we can write a float into it. 1037 */ 1038 if (a.type & MN_INTEGER) { 1039 a.type = MN_FLOAT; 1040 a.u.d = (double)a.u.l; 1041 } 1042 if (b.type & MN_INTEGER) { 1043 b.type = MN_FLOAT; 1044 b.u.d = (double)b.u.l; 1045 } 1046 } 1047 1048 if (noeval) { 1049 c.type = MN_INTEGER; 1050 c.u.l = 0; 1051 } else { 1052 /* 1053 * type for operation: usually same as operands, but e.g. 1054 * (a == b) returns int. 1055 */ 1056 c.type = (tp & OP_A2IR) ? MN_INTEGER : a.type; 1057 1058 switch(what) { 1059 case AND: 1060 case ANDEQ: 1061 c.u.l = a.u.l & b.u.l; 1062 break; 1063 case XOR: 1064 case XOREQ: 1065 c.u.l = a.u.l ^ b.u.l; 1066 break; 1067 case OR: 1068 case OREQ: 1069 c.u.l = a.u.l | b.u.l; 1070 break; 1071 case MUL: 1072 case MULEQ: 1073 if (c.type == MN_FLOAT) 1074 c.u.d = a.u.d * b.u.d; 1075 else 1076 c.u.l = a.u.l * b.u.l; 1077 break; 1078 case DIV: 1079 case DIVEQ: 1080 if (!notzero(b)) 1081 return; 1082 if (c.type == MN_FLOAT) 1083 c.u.d = a.u.d / b.u.d; 1084 else { 1085 /* 1086 * Avoid exception when dividing the smallest 1087 * negative integer by -1. Always treat it the 1088 * same as multiplication. This still doesn't give 1089 * numerically the right answer in two's complement, 1090 * but treating both these in the same way seems 1091 * reasonable. 1092 */ 1093 if (b.u.l == -1) 1094 c.u.l = - a.u.l; 1095 else 1096 c.u.l = a.u.l / b.u.l; 1097 } 1098 break; 1099 case MOD: 1100 case MODEQ: 1101 if (!notzero(b)) 1102 return; 1103 /* 1104 * Avoid exception as above. 1105 * Any integer mod -1 is the same as any integer mod 1 1106 * i.e. zero. 1107 */ 1108 if (b.u.l == -1) 1109 c.u.l = 0; 1110 else 1111 c.u.l = a.u.l % b.u.l; 1112 break; 1113 case PLUS: 1114 case PLUSEQ: 1115 if (c.type == MN_FLOAT) 1116 c.u.d = a.u.d + b.u.d; 1117 else 1118 c.u.l = a.u.l + b.u.l; 1119 break; 1120 case MINUS: 1121 case MINUSEQ: 1122 if (c.type == MN_FLOAT) 1123 c.u.d = a.u.d - b.u.d; 1124 else 1125 c.u.l = a.u.l - b.u.l; 1126 break; 1127 case SHLEFT: 1128 case SHLEFTEQ: 1129 c.u.l = a.u.l << b.u.l; 1130 break; 1131 case SHRIGHT: 1132 case SHRIGHTEQ: 1133 c.u.l = a.u.l >> b.u.l; 1134 break; 1135 case LES: 1136 c.u.l = (zlong) 1137 (a.type == MN_FLOAT ? (a.u.d < b.u.d) : (a.u.l < b.u.l)); 1138 break; 1139 case LEQ: 1140 c.u.l = (zlong) 1141 (a.type == MN_FLOAT ? (a.u.d <= b.u.d) : (a.u.l <= b.u.l)); 1142 break; 1143 case GRE: 1144 c.u.l = (zlong) 1145 (a.type == MN_FLOAT ? (a.u.d > b.u.d) : (a.u.l > b.u.l)); 1146 break; 1147 case GEQ: 1148 c.u.l = (zlong) 1149 (a.type == MN_FLOAT ? (a.u.d >= b.u.d) : (a.u.l >= b.u.l)); 1150 break; 1151 case DEQ: 1152 c.u.l = (zlong) 1153 (a.type == MN_FLOAT ? (a.u.d == b.u.d) : (a.u.l == b.u.l)); 1154 break; 1155 case NEQ: 1156 c.u.l = (zlong) 1157 (a.type == MN_FLOAT ? (a.u.d != b.u.d) : (a.u.l != b.u.l)); 1158 break; 1159 case DAND: 1160 case DANDEQ: 1161 c.u.l = (zlong)(a.u.l && b.u.l); 1162 break; 1163 case DOR: 1164 case DOREQ: 1165 c.u.l = (zlong)(a.u.l || b.u.l); 1166 break; 1167 case DXOR: 1168 case DXOREQ: 1169 c.u.l = (zlong)((a.u.l && !b.u.l) || (!a.u.l && b.u.l)); 1170 break; 1171 case COMMA: 1172 c = b; 1173 break; 1174 case POWER: 1175 case POWEREQ: 1176 if (c.type == MN_INTEGER && b.u.l < 0) { 1177 /* produces a real result, so cast to real. */ 1178 a.type = b.type = c.type = MN_FLOAT; 1179 a.u.d = (double) a.u.l; 1180 b.u.d = (double) b.u.l; 1181 } 1182 if (c.type == MN_INTEGER) { 1183 for (c.u.l = 1; b.u.l--; c.u.l *= a.u.l); 1184 } else { 1185 if (b.u.d <= 0 && !notzero(a)) 1186 return; 1187 if (a.u.d < 0) { 1188 /* Error if (-num ** b) and b is not an integer */ 1189 double tst = (double)(zlong)b.u.d; 1190 if (tst != b.u.d) { 1191 zerr("imaginary power"); 1192 return; 1193 } 1194 } 1195 c.u.d = pow(a.u.d, b.u.d); 1196 } 1197 break; 1198 case EQ: 1199 c = b; 1200 break; 1201 } 1202 } 1203 if (tp & (OP_E2|OP_E2IO)) { 1204 struct mathvalue *mvp = stack + sp + 1; 1205 c = setmathvar(mvp, c); 1206 push(c, mvp->lval, 0); 1207 } else 1208 push(c,NULL, 0); 1209 return; 1210 } 1211 1212 spval = &stack[sp].val; 1213 if (stack[sp].val.type == MN_UNSET) 1214 *spval = getmathparam(stack + sp); 1215 switch (what) { 1216 case NOT: 1217 if (spval->type & MN_FLOAT) { 1218 spval->u.l = !spval->u.d; 1219 spval->type = MN_INTEGER; 1220 } else 1221 spval->u.l = !spval->u.l; 1222 stack[sp].lval = NULL; 1223 stack[sp].pval = NULL; 1224 break; 1225 case COMP: 1226 if (spval->type & MN_FLOAT) { 1227 spval->u.l = ~((zlong)spval->u.d); 1228 spval->type = MN_INTEGER; 1229 } else 1230 spval->u.l = ~spval->u.l; 1231 stack[sp].lval = NULL; 1232 stack[sp].pval = NULL; 1233 break; 1234 case POSTPLUS: 1235 a = *spval; 1236 if (spval->type & MN_FLOAT) 1237 a.u.d++; 1238 else 1239 a.u.l++; 1240 (void)setmathvar(stack + sp, a); 1241 break; 1242 case POSTMINUS: 1243 a = *spval; 1244 if (spval->type & MN_FLOAT) 1245 a.u.d--; 1246 else 1247 a.u.l--; 1248 (void)setmathvar(stack + sp, a); 1249 break; 1250 case UPLUS: 1251 stack[sp].lval = NULL; 1252 stack[sp].pval = NULL; 1253 break; 1254 case UMINUS: 1255 if (spval->type & MN_FLOAT) 1256 spval->u.d = -spval->u.d; 1257 else 1258 spval->u.l = -spval->u.l; 1259 stack[sp].lval = NULL; 1260 stack[sp].pval = NULL; 1261 break; 1262 case QUEST: 1263 DPUTS(sp < 2, "BUG: math: three shall be the number of the counting."); 1264 c = pop(0); 1265 b = pop(0); 1266 a = pop(0); 1267 if (errflag) 1268 return; 1269 /* b and c can stay different types in this case. */ 1270 push(((a.type & MN_FLOAT) ? a.u.d : a.u.l) ? b : c, NULL, 0); 1271 break; 1272 case COLON: 1273 zerr("':' without '?'"); 1274 break; 1275 case PREPLUS: 1276 if (spval->type & MN_FLOAT) 1277 spval->u.d++; 1278 else 1279 spval->u.l++; 1280 setmathvar(stack + sp, *spval); 1281 break; 1282 case PREMINUS: 1283 if (spval->type & MN_FLOAT) 1284 spval->u.d--; 1285 else 1286 spval->u.l--; 1287 setmathvar(stack + sp, *spval); 1288 break; 1289 default: 1290 zerr("out of integers"); 1291 return; 1292 } 1293} 1294 1295 1296/**/ 1297static void 1298bop(int tk) 1299{ 1300 mnumber *spval = &stack[sp].val; 1301 int tst; 1302 1303 if (stack[sp].val.type == MN_UNSET) 1304 *spval = getmathparam(stack + sp); 1305 tst = (spval->type & MN_FLOAT) ? (zlong)spval->u.d : spval->u.l; 1306 1307 switch (tk) { 1308 case DAND: 1309 case DANDEQ: 1310 if (!tst) 1311 noeval++; 1312 break; 1313 case DOR: 1314 case DOREQ: 1315 if (tst) 1316 noeval++; 1317 break; 1318 }; 1319} 1320 1321 1322/**/ 1323mod_export mnumber 1324matheval(char *s) 1325{ 1326 char *junk; 1327 mnumber x; 1328 int xmtok = mtok; 1329 /* maintain outputradix across levels of evaluation */ 1330 if (!mlevel) 1331 outputradix = 0; 1332 1333 if (!*s) { 1334 x.type = MN_INTEGER; 1335 x.u.l = 0; 1336 return x; 1337 } 1338 x = mathevall(s, MPREC_TOP, &junk); 1339 mtok = xmtok; 1340 if (*junk) 1341 zerr("bad math expression: illegal character: %c", *junk); 1342 return x; 1343} 1344 1345/**/ 1346mod_export zlong 1347mathevali(char *s) 1348{ 1349 mnumber x = matheval(s); 1350 return (x.type & MN_FLOAT) ? (zlong)x.u.d : x.u.l; 1351} 1352 1353 1354/**/ 1355zlong 1356mathevalarg(char *s, char **ss) 1357{ 1358 mnumber x; 1359 int xmtok = mtok; 1360 1361 x = mathevall(s, MPREC_ARG, ss); 1362 if (mtok == COMMA) 1363 (*ss)--; 1364 mtok = xmtok; 1365 return (x.type & MN_FLOAT) ? (zlong)x.u.d : x.u.l; 1366} 1367 1368/* 1369 * Make sure we have an operator or an operand, whatever is expected. 1370 * For this purpose, unary operators constitute part of an operand. 1371 */ 1372 1373/**/ 1374static void 1375checkunary(int mtokc, char *mptr) 1376{ 1377 int errmsg = 0; 1378 int tp = type[mtokc]; 1379 if (tp & (OP_A2|OP_A2IR|OP_A2IO|OP_E2|OP_E2IO|OP_OP)) { 1380 if (unary) 1381 errmsg = 1; 1382 } else { 1383 if (!unary) 1384 errmsg = 2; 1385 } 1386 if (errmsg) { 1387 int len, over = 0; 1388 while (inblank(*mptr)) 1389 mptr++; 1390 len = ztrlen(mptr); 1391 if (len > 10) { 1392 len = 10; 1393 over = 1; 1394 } 1395 zerr("bad math expression: %s expected at `%l%s'", 1396 errmsg == 2 ? "operator" : "operand", 1397 mptr, len, over ? "..." : ""); 1398 } 1399 unary = !(tp & OP_OPF); 1400} 1401 1402/* operator-precedence parse the string and execute */ 1403 1404/**/ 1405static void 1406mathparse(int pc) 1407{ 1408 zlong q; 1409 int otok, onoeval; 1410 char *optr = ptr; 1411 1412 if (errflag) 1413 return; 1414 mtok = zzlex(); 1415 /* Handle empty input */ 1416 if (pc == TOPPREC && mtok == EOI) 1417 return; 1418 checkunary(mtok, optr); 1419 while (prec[mtok] <= pc) { 1420 if (errflag) 1421 return; 1422 switch (mtok) { 1423 case NUM: 1424 push(yyval, NULL, 0); 1425 break; 1426 case ID: 1427 push(zero_mnumber, yylval, !noeval); 1428 break; 1429 case CID: 1430 push((noeval ? zero_mnumber : getcvar(yylval)), yylval, 0); 1431 break; 1432 case FUNC: 1433 push((noeval ? zero_mnumber : callmathfunc(yylval)), yylval, 0); 1434 break; 1435 case M_INPAR: 1436 mathparse(TOPPREC); 1437 if (mtok != M_OUTPAR) { 1438 if (!errflag) 1439 zerr("')' expected"); 1440 return; 1441 } 1442 break; 1443 case QUEST: 1444 if (stack[sp].val.type == MN_UNSET) 1445 stack[sp].val = getmathparam(stack + sp); 1446 q = (stack[sp].val.type == MN_FLOAT) ? (zlong)stack[sp].val.u.d : 1447 stack[sp].val.u.l; 1448 1449 if (!q) 1450 noeval++; 1451 mathparse(prec[COLON] - 1); 1452 if (!q) 1453 noeval--; 1454 if (mtok != COLON) { 1455 if (!errflag) 1456 zerr("':' expected"); 1457 return; 1458 } 1459 if (q) 1460 noeval++; 1461 mathparse(prec[QUEST]); 1462 if (q) 1463 noeval--; 1464 op(QUEST); 1465 continue; 1466 default: 1467 otok = mtok; 1468 onoeval = noeval; 1469 if (MTYPE(type[otok]) == BOOL) 1470 bop(otok); 1471 mathparse(prec[otok] - (MTYPE(type[otok]) != RL)); 1472 noeval = onoeval; 1473 op(otok); 1474 continue; 1475 } 1476 optr = ptr; 1477 mtok = zzlex(); 1478 checkunary(mtok, optr); 1479 } 1480} 1481