| 771 | /* Handle *, /, % operators. */ |
| 772 | |
| 773 | static VALUE * |
| 774 | eval4 (bool evaluate) |
| 775 | { |
| 776 | #ifdef EVAL_TRACE |
| 777 | trace ("eval4"); |
| 778 | #endif |
| 779 | VALUE *l = eval5 (evaluate); |
| 780 | while (true) |
| 781 | { |
| 782 | enum { multiply, divide, mod } fxn; |
| 783 | |
| 784 | if (nextarg ("*")) |
| 785 | fxn = multiply; |
| 786 | else if (nextarg ("/")) |
| 787 | fxn = divide; |
| 788 | else if (nextarg ("%")) |
| 789 | fxn = mod; |
| 790 | else |
| 791 | return l; |
| 792 | VALUE *r = eval5 (evaluate); |
| 793 | if (evaluate) |
| 794 | { |
| 795 | if (!toarith (l) || !toarith (r)) |
| 796 | error (EXPR_INVALID, 0, _("non-integer argument")); |
| 797 | if (fxn != multiply && mpz_sgn (r->u.i) == 0) |
| 798 | error (EXPR_INVALID, 0, _("division by zero")); |
| 799 | ((fxn == multiply ? mpz_mul |
| 800 | : fxn == divide ? mpz_tdiv_q |
| 801 | : mpz_tdiv_r) |
| 802 | (l->u.i, l->u.i, r->u.i)); |
| 803 | } |
| 804 | freev (r); |
| 805 | } |
| 806 | } |
| 807 | |
| 808 | /* Handle +, - operators. */ |
| 809 | |