Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Unified Diff: gcc/gmp/demos/pexpr.c

Issue 3050029: [gcc] GCC 4.5.0=>4.5.1 (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/nacl-toolchain.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gcc/gmp/demos/perl/typemap ('k') | gcc/gmp/doc/Makefile.in » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gcc/gmp/demos/pexpr.c
diff --git a/gcc/gmp/demos/pexpr.c b/gcc/gmp/demos/pexpr.c
deleted file mode 100644
index ec4eecbb2f693eefb9ec6907b1427bf3f3eea7b7..0000000000000000000000000000000000000000
--- a/gcc/gmp/demos/pexpr.c
+++ /dev/null
@@ -1,1378 +0,0 @@
-/* Program for computing integer expressions using the GNU Multiple Precision
- Arithmetic Library.
-
-Copyright 1997, 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; either version 3 of the License, or (at your option) any later
-version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program. If not, see http://www.gnu.org/licenses/. */
-
-
-/* This expressions evaluator works by building an expression tree (using a
- recursive descent parser) which is then evaluated. The expression tree is
- useful since we want to optimize certain expressions (like a^b % c).
-
- Usage: pexpr [options] expr ...
- (Assuming you called the executable `pexpr' of course.)
-
- Command line options:
-
- -b print output in binary
- -o print output in octal
- -d print output in decimal (the default)
- -x print output in hexadecimal
- -b<NUM> print output in base NUM
- -t print timing information
- -html output html
- -wml output wml
- -split split long lines each 80th digit
-*/
-
-/* Define LIMIT_RESOURCE_USAGE if you want to make sure the program doesn't
- use up extensive resources (cpu, memory). Useful for the GMP demo on the
- GMP web site, since we cannot load the server too much. */
-
-#include "pexpr-config.h"
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <ctype.h>
-
-#include <time.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#if HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-
-#include "gmp.h"
-
-/* SunOS 4 and HPUX 9 don't define a canonical SIGSTKSZ, use a default. */
-#ifndef SIGSTKSZ
-#define SIGSTKSZ 4096
-#endif
-
-
-#define TIME(t,func) \
- do { int __t0, __tmp; \
- __t0 = cputime (); \
- {func;} \
- __tmp = cputime () - __t0; \
- (t) = __tmp; \
- } while (0)
-
-/* GMP version 1.x compatibility. */
-#if ! (__GNU_MP_VERSION >= 2)
-typedef MP_INT __mpz_struct;
-typedef __mpz_struct mpz_t[1];
-typedef __mpz_struct *mpz_ptr;
-#define mpz_fdiv_q mpz_div
-#define mpz_fdiv_r mpz_mod
-#define mpz_tdiv_q_2exp mpz_div_2exp
-#define mpz_sgn(Z) ((Z)->size < 0 ? -1 : (Z)->size > 0)
-#endif
-
-/* GMP version 2.0 compatibility. */
-#if ! (__GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1)
-#define mpz_swap(a,b) \
- do { __mpz_struct __t; __t = *a; *a = *b; *b = __t;} while (0)
-#endif
-
-jmp_buf errjmpbuf;
-
-enum op_t {NOP, LIT, NEG, NOT, PLUS, MINUS, MULT, DIV, MOD, REM, INVMOD, POW,
- AND, IOR, XOR, SLL, SRA, POPCNT, HAMDIST, GCD, LCM, SQRT, ROOT, FAC,
- LOG, LOG2, FERMAT, MERSENNE, FIBONACCI, RANDOM, NEXTPRIME, BINOM,
- TIMING};
-
-/* Type for the expression tree. */
-struct expr
-{
- enum op_t op;
- union
- {
- struct {struct expr *lhs, *rhs;} ops;
- mpz_t val;
- } operands;
-};
-
-typedef struct expr *expr_t;
-
-void cleanup_and_exit __GMP_PROTO ((int));
-
-char *skipspace __GMP_PROTO ((char *));
-void makeexp __GMP_PROTO ((expr_t *, enum op_t, expr_t, expr_t));
-void free_expr __GMP_PROTO ((expr_t));
-char *expr __GMP_PROTO ((char *, expr_t *));
-char *term __GMP_PROTO ((char *, expr_t *));
-char *power __GMP_PROTO ((char *, expr_t *));
-char *factor __GMP_PROTO ((char *, expr_t *));
-int match __GMP_PROTO ((char *, char *));
-int matchp __GMP_PROTO ((char *, char *));
-int cputime __GMP_PROTO ((void));
-
-void mpz_eval_expr __GMP_PROTO ((mpz_ptr, expr_t));
-void mpz_eval_mod_expr __GMP_PROTO ((mpz_ptr, expr_t, mpz_ptr));
-
-char *error;
-int flag_print = 1;
-int print_timing = 0;
-int flag_html = 0;
-int flag_wml = 0;
-int flag_splitup_output = 0;
-char *newline = "";
-gmp_randstate_t rstate;
-
-
-
-/* cputime() returns user CPU time measured in milliseconds. */
-#if ! HAVE_CPUTIME
-#if HAVE_GETRUSAGE
-int
-cputime (void)
-{
- struct rusage rus;
-
- getrusage (0, &rus);
- return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
-}
-#else
-#if HAVE_CLOCK
-int
-cputime (void)
-{
- if (CLOCKS_PER_SEC < 100000)
- return clock () * 1000 / CLOCKS_PER_SEC;
- return clock () / (CLOCKS_PER_SEC / 1000);
-}
-#else
-int
-cputime (void)
-{
- return 0;
-}
-#endif
-#endif
-#endif
-
-
-int
-stack_downwards_helper (char *xp)
-{
- char y;
- return &y < xp;
-}
-int
-stack_downwards_p (void)
-{
- char x;
- return stack_downwards_helper (&x);
-}
-
-
-void
-setup_error_handler (void)
-{
-#if HAVE_SIGACTION
- struct sigaction act;
- act.sa_handler = cleanup_and_exit;
- sigemptyset (&(act.sa_mask));
-#define SIGNAL(sig) sigaction (sig, &act, NULL)
-#else
- struct { int sa_flags; } act;
-#define SIGNAL(sig) signal (sig, cleanup_and_exit)
-#endif
- act.sa_flags = 0;
-
- /* Set up a stack for signal handling. A typical cause of error is stack
- overflow, and in such situation a signal can not be delivered on the
- overflown stack. */
-#if HAVE_SIGALTSTACK
- {
- /* AIX uses stack_t, MacOS uses struct sigaltstack, various other
- systems have both. */
-#if HAVE_STACK_T
- stack_t s;
-#else
- struct sigaltstack s;
-#endif
- s.ss_sp = malloc (SIGSTKSZ);
- s.ss_size = SIGSTKSZ;
- s.ss_flags = 0;
- if (sigaltstack (&s, NULL) != 0)
- perror("sigaltstack");
- act.sa_flags = SA_ONSTACK;
- }
-#else
-#if HAVE_SIGSTACK
- {
- struct sigstack s;
- s.ss_sp = malloc (SIGSTKSZ);
- if (stack_downwards_p ())
- s.ss_sp += SIGSTKSZ;
- s.ss_onstack = 0;
- if (sigstack (&s, NULL) != 0)
- perror("sigstack");
- act.sa_flags = SA_ONSTACK;
- }
-#else
-#endif
-#endif
-
-#ifdef LIMIT_RESOURCE_USAGE
- {
- struct rlimit limit;
-
- limit.rlim_cur = limit.rlim_max = 0;
- setrlimit (RLIMIT_CORE, &limit);
-
- limit.rlim_cur = 3;
- limit.rlim_max = 4;
- setrlimit (RLIMIT_CPU, &limit);
-
- limit.rlim_cur = limit.rlim_max = 16 * 1024 * 1024;
- setrlimit (RLIMIT_DATA, &limit);
-
- getrlimit (RLIMIT_STACK, &limit);
- limit.rlim_cur = 4 * 1024 * 1024;
- setrlimit (RLIMIT_STACK, &limit);
-
- SIGNAL (SIGXCPU);
- }
-#endif /* LIMIT_RESOURCE_USAGE */
-
- SIGNAL (SIGILL);
- SIGNAL (SIGSEGV);
-#ifdef SIGBUS /* not in mingw */
- SIGNAL (SIGBUS);
-#endif
- SIGNAL (SIGFPE);
- SIGNAL (SIGABRT);
-}
-
-int
-main (int argc, char **argv)
-{
- struct expr *e;
- int i;
- mpz_t r;
- int errcode = 0;
- char *str;
- int base = 10;
-
- setup_error_handler ();
-
- gmp_randinit (rstate, GMP_RAND_ALG_LC, 128);
-
- {
-#if HAVE_GETTIMEOFDAY
- struct timeval tv;
- gettimeofday (&tv, NULL);
- gmp_randseed_ui (rstate, tv.tv_sec + tv.tv_usec);
-#else
- time_t t;
- time (&t);
- gmp_randseed_ui (rstate, t);
-#endif
- }
-
- mpz_init (r);
-
- while (argc > 1 && argv[1][0] == '-')
- {
- char *arg = argv[1];
-
- if (arg[1] >= '0' && arg[1] <= '9')
- break;
-
- if (arg[1] == 't')
- print_timing = 1;
- else if (arg[1] == 'b' && arg[2] >= '0' && arg[2] <= '9')
- {
- base = atoi (arg + 2);
- if (base < 2 || base > 62)
- {
- fprintf (stderr, "error: invalid output base\n");
- exit (-1);
- }
- }
- else if (arg[1] == 'b' && arg[2] == 0)
- base = 2;
- else if (arg[1] == 'x' && arg[2] == 0)
- base = 16;
- else if (arg[1] == 'X' && arg[2] == 0)
- base = -16;
- else if (arg[1] == 'o' && arg[2] == 0)
- base = 8;
- else if (arg[1] == 'd' && arg[2] == 0)
- base = 10;
- else if (arg[1] == 'v' && arg[2] == 0)
- {
- printf ("pexpr linked to gmp %s\n", __gmp_version);
- }
- else if (strcmp (arg, "-html") == 0)
- {
- flag_html = 1;
- newline = "<br>";
- }
- else if (strcmp (arg, "-wml") == 0)
- {
- flag_wml = 1;
- newline = "<br/>";
- }
- else if (strcmp (arg, "-split") == 0)
- {
- flag_splitup_output = 1;
- }
- else if (strcmp (arg, "-noprint") == 0)
- {
- flag_print = 0;
- }
- else
- {
- fprintf (stderr, "error: unknown option `%s'\n", arg);
- exit (-1);
- }
- argv++;
- argc--;
- }
-
- for (i = 1; i < argc; i++)
- {
- int s;
- int jmpval;
-
- /* Set up error handler for parsing expression. */
- jmpval = setjmp (errjmpbuf);
- if (jmpval != 0)
- {
- fprintf (stderr, "error: %s%s\n", error, newline);
- fprintf (stderr, " %s%s\n", argv[i], newline);
- if (! flag_html)
- {
- /* ??? Dunno how to align expression position with arrow in
- HTML ??? */
- fprintf (stderr, " ");
- for (s = jmpval - (long) argv[i]; --s >= 0; )
- putc (' ', stderr);
- fprintf (stderr, "^\n");
- }
-
- errcode |= 1;
- continue;
- }
-
- str = expr (argv[i], &e);
-
- if (str[0] != 0)
- {
- fprintf (stderr,
- "error: garbage where end of expression expected%s\n",
- newline);
- fprintf (stderr, " %s%s\n", argv[i], newline);
- if (! flag_html)
- {
- /* ??? Dunno how to align expression position with arrow in
- HTML ??? */
- fprintf (stderr, " ");
- for (s = str - argv[i]; --s; )
- putc (' ', stderr);
- fprintf (stderr, "^\n");
- }
-
- errcode |= 1;
- free_expr (e);
- continue;
- }
-
- /* Set up error handler for evaluating expression. */
- if (setjmp (errjmpbuf))
- {
- fprintf (stderr, "error: %s%s\n", error, newline);
- fprintf (stderr, " %s%s\n", argv[i], newline);
- if (! flag_html)
- {
- /* ??? Dunno how to align expression position with arrow in
- HTML ??? */
- fprintf (stderr, " ");
- for (s = str - argv[i]; --s >= 0; )
- putc (' ', stderr);
- fprintf (stderr, "^\n");
- }
-
- errcode |= 2;
- continue;
- }
-
- if (print_timing)
- {
- int t;
- TIME (t, mpz_eval_expr (r, e));
- printf ("computation took %d ms%s\n", t, newline);
- }
- else
- mpz_eval_expr (r, e);
-
- if (flag_print)
- {
- size_t out_len;
- char *tmp, *s;
-
- out_len = mpz_sizeinbase (r, base >= 0 ? base : -base) + 2;
-#ifdef LIMIT_RESOURCE_USAGE
- if (out_len > 100000)
- {
- printf ("result is about %ld digits, not printing it%s\n",
- (long) out_len - 3, newline);
- exit (-2);
- }
-#endif
- tmp = malloc (out_len);
-
- if (print_timing)
- {
- int t;
- printf ("output conversion ");
- TIME (t, mpz_get_str (tmp, base, r));
- printf ("took %d ms%s\n", t, newline);
- }
- else
- mpz_get_str (tmp, base, r);
-
- out_len = strlen (tmp);
- if (flag_splitup_output)
- {
- for (s = tmp; out_len > 80; s += 80)
- {
- fwrite (s, 1, 80, stdout);
- printf ("%s\n", newline);
- out_len -= 80;
- }
-
- fwrite (s, 1, out_len, stdout);
- }
- else
- {
- fwrite (tmp, 1, out_len, stdout);
- }
-
- free (tmp);
- printf ("%s\n", newline);
- }
- else
- {
- printf ("result is approximately %ld digits%s\n",
- (long) mpz_sizeinbase (r, base >= 0 ? base : -base),
- newline);
- }
-
- free_expr (e);
- }
-
- exit (errcode);
-}
-
-char *
-expr (char *str, expr_t *e)
-{
- expr_t e2;
-
- str = skipspace (str);
- if (str[0] == '+')
- {
- str = term (str + 1, e);
- }
- else if (str[0] == '-')
- {
- str = term (str + 1, e);
- makeexp (e, NEG, *e, NULL);
- }
- else if (str[0] == '~')
- {
- str = term (str + 1, e);
- makeexp (e, NOT, *e, NULL);
- }
- else
- {
- str = term (str, e);
- }
-
- for (;;)
- {
- str = skipspace (str);
- switch (str[0])
- {
- case 'p':
- if (match ("plus", str))
- {
- str = term (str + 4, &e2);
- makeexp (e, PLUS, *e, e2);
- }
- else
- return str;
- break;
- case 'm':
- if (match ("minus", str))
- {
- str = term (str + 5, &e2);
- makeexp (e, MINUS, *e, e2);
- }
- else
- return str;
- break;
- case '+':
- str = term (str + 1, &e2);
- makeexp (e, PLUS, *e, e2);
- break;
- case '-':
- str = term (str + 1, &e2);
- makeexp (e, MINUS, *e, e2);
- break;
- default:
- return str;
- }
- }
-}
-
-char *
-term (char *str, expr_t *e)
-{
- expr_t e2;
-
- str = power (str, e);
- for (;;)
- {
- str = skipspace (str);
- switch (str[0])
- {
- case 'm':
- if (match ("mul", str))
- {
- str = power (str + 3, &e2);
- makeexp (e, MULT, *e, e2);
- break;
- }
- if (match ("mod", str))
- {
- str = power (str + 3, &e2);
- makeexp (e, MOD, *e, e2);
- break;
- }
- return str;
- case 'd':
- if (match ("div", str))
- {
- str = power (str + 3, &e2);
- makeexp (e, DIV, *e, e2);
- break;
- }
- return str;
- case 'r':
- if (match ("rem", str))
- {
- str = power (str + 3, &e2);
- makeexp (e, REM, *e, e2);
- break;
- }
- return str;
- case 'i':
- if (match ("invmod", str))
- {
- str = power (str + 6, &e2);
- makeexp (e, REM, *e, e2);
- break;
- }
- return str;
- case 't':
- if (match ("times", str))
- {
- str = power (str + 5, &e2);
- makeexp (e, MULT, *e, e2);
- break;
- }
- if (match ("thru", str))
- {
- str = power (str + 4, &e2);
- makeexp (e, DIV, *e, e2);
- break;
- }
- if (match ("through", str))
- {
- str = power (str + 7, &e2);
- makeexp (e, DIV, *e, e2);
- break;
- }
- return str;
- case '*':
- str = power (str + 1, &e2);
- makeexp (e, MULT, *e, e2);
- break;
- case '/':
- str = power (str + 1, &e2);
- makeexp (e, DIV, *e, e2);
- break;
- case '%':
- str = power (str + 1, &e2);
- makeexp (e, MOD, *e, e2);
- break;
- default:
- return str;
- }
- }
-}
-
-char *
-power (char *str, expr_t *e)
-{
- expr_t e2;
-
- str = factor (str, e);
- while (str[0] == '!')
- {
- str++;
- makeexp (e, FAC, *e, NULL);
- }
- str = skipspace (str);
- if (str[0] == '^')
- {
- str = power (str + 1, &e2);
- makeexp (e, POW, *e, e2);
- }
- return str;
-}
-
-int
-match (char *s, char *str)
-{
- char *ostr = str;
- int i;
-
- for (i = 0; s[i] != 0; i++)
- {
- if (str[i] != s[i])
- return 0;
- }
- str = skipspace (str + i);
- return str - ostr;
-}
-
-int
-matchp (char *s, char *str)
-{
- char *ostr = str;
- int i;
-
- for (i = 0; s[i] != 0; i++)
- {
- if (str[i] != s[i])
- return 0;
- }
- str = skipspace (str + i);
- if (str[0] == '(')
- return str - ostr + 1;
- return 0;
-}
-
-struct functions
-{
- char *spelling;
- enum op_t op;
- int arity; /* 1 or 2 means real arity; 0 means arbitrary. */
-};
-
-struct functions fns[] =
-{
- {"sqrt", SQRT, 1},
-#if __GNU_MP_VERSION >= 2
- {"root", ROOT, 2},
- {"popc", POPCNT, 1},
- {"hamdist", HAMDIST, 2},
-#endif
- {"gcd", GCD, 0},
-#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
- {"lcm", LCM, 0},
-#endif
- {"and", AND, 0},
- {"ior", IOR, 0},
-#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
- {"xor", XOR, 0},
-#endif
- {"plus", PLUS, 0},
- {"pow", POW, 2},
- {"minus", MINUS, 2},
- {"mul", MULT, 0},
- {"div", DIV, 2},
- {"mod", MOD, 2},
- {"rem", REM, 2},
-#if __GNU_MP_VERSION >= 2
- {"invmod", INVMOD, 2},
-#endif
- {"log", LOG, 2},
- {"log2", LOG2, 1},
- {"F", FERMAT, 1},
- {"M", MERSENNE, 1},
- {"fib", FIBONACCI, 1},
- {"Fib", FIBONACCI, 1},
- {"random", RANDOM, 1},
- {"nextprime", NEXTPRIME, 1},
- {"binom", BINOM, 2},
- {"binomial", BINOM, 2},
- {"fac", FAC, 1},
- {"fact", FAC, 1},
- {"factorial", FAC, 1},
- {"time", TIMING, 1},
- {"", NOP, 0}
-};
-
-char *
-factor (char *str, expr_t *e)
-{
- expr_t e1, e2;
-
- str = skipspace (str);
-
- if (isalpha (str[0]))
- {
- int i;
- int cnt;
-
- for (i = 0; fns[i].op != NOP; i++)
- {
- if (fns[i].arity == 1)
- {
- cnt = matchp (fns[i].spelling, str);
- if (cnt != 0)
- {
- str = expr (str + cnt, &e1);
- str = skipspace (str);
- if (str[0] != ')')
- {
- error = "expected `)'";
- longjmp (errjmpbuf, (int) (long) str);
- }
- makeexp (e, fns[i].op, e1, NULL);
- return str + 1;
- }
- }
- }
-
- for (i = 0; fns[i].op != NOP; i++)
- {
- if (fns[i].arity != 1)
- {
- cnt = matchp (fns[i].spelling, str);
- if (cnt != 0)
- {
- str = expr (str + cnt, &e1);
- str = skipspace (str);
-
- if (str[0] != ',')
- {
- error = "expected `,' and another operand";
- longjmp (errjmpbuf, (int) (long) str);
- }
-
- str = skipspace (str + 1);
- str = expr (str, &e2);
- str = skipspace (str);
-
- if (fns[i].arity == 0)
- {
- while (str[0] == ',')
- {
- makeexp (&e1, fns[i].op, e1, e2);
- str = skipspace (str + 1);
- str = expr (str, &e2);
- str = skipspace (str);
- }
- }
-
- if (str[0] != ')')
- {
- error = "expected `)'";
- longjmp (errjmpbuf, (int) (long) str);
- }
-
- makeexp (e, fns[i].op, e1, e2);
- return str + 1;
- }
- }
- }
- }
-
- if (str[0] == '(')
- {
- str = expr (str + 1, e);
- str = skipspace (str);
- if (str[0] != ')')
- {
- error = "expected `)'";
- longjmp (errjmpbuf, (int) (long) str);
- }
- str++;
- }
- else if (str[0] >= '0' && str[0] <= '9')
- {
- expr_t res;
- char *s, *sc;
-
- res = malloc (sizeof (struct expr));
- res -> op = LIT;
- mpz_init (res->operands.val);
-
- s = str;
- while (isalnum (str[0]))
- str++;
- sc = malloc (str - s + 1);
- memcpy (sc, s, str - s);
- sc[str - s] = 0;
-
- mpz_set_str (res->operands.val, sc, 0);
- *e = res;
- free (sc);
- }
- else
- {
- error = "operand expected";
- longjmp (errjmpbuf, (int) (long) str);
- }
- return str;
-}
-
-char *
-skipspace (char *str)
-{
- while (str[0] == ' ')
- str++;
- return str;
-}
-
-/* Make a new expression with operation OP and right hand side
- RHS and left hand side lhs. Put the result in R. */
-void
-makeexp (expr_t *r, enum op_t op, expr_t lhs, expr_t rhs)
-{
- expr_t res;
- res = malloc (sizeof (struct expr));
- res -> op = op;
- res -> operands.ops.lhs = lhs;
- res -> operands.ops.rhs = rhs;
- *r = res;
- return;
-}
-
-/* Free the memory used by expression E. */
-void
-free_expr (expr_t e)
-{
- if (e->op != LIT)
- {
- free_expr (e->operands.ops.lhs);
- if (e->operands.ops.rhs != NULL)
- free_expr (e->operands.ops.rhs);
- }
- else
- {
- mpz_clear (e->operands.val);
- }
-}
-
-/* Evaluate the expression E and put the result in R. */
-void
-mpz_eval_expr (mpz_ptr r, expr_t e)
-{
- mpz_t lhs, rhs;
-
- switch (e->op)
- {
- case LIT:
- mpz_set (r, e->operands.val);
- return;
- case PLUS:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_add (r, lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
- case MINUS:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_sub (r, lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
- case MULT:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_mul (r, lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
- case DIV:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_fdiv_q (r, lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
- case MOD:
- mpz_init (rhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_abs (rhs, rhs);
- mpz_eval_mod_expr (r, e->operands.ops.lhs, rhs);
- mpz_clear (rhs);
- return;
- case REM:
- /* Check if lhs operand is POW expression and optimize for that case. */
- if (e->operands.ops.lhs->op == POW)
- {
- mpz_t powlhs, powrhs;
- mpz_init (powlhs);
- mpz_init (powrhs);
- mpz_init (rhs);
- mpz_eval_expr (powlhs, e->operands.ops.lhs->operands.ops.lhs);
- mpz_eval_expr (powrhs, e->operands.ops.lhs->operands.ops.rhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_powm (r, powlhs, powrhs, rhs);
- if (mpz_cmp_si (rhs, 0L) < 0)
- mpz_neg (r, r);
- mpz_clear (powlhs);
- mpz_clear (powrhs);
- mpz_clear (rhs);
- return;
- }
-
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_fdiv_r (r, lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
-#if __GNU_MP_VERSION >= 2
- case INVMOD:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_invert (r, lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
-#endif
- case POW:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- if (mpz_cmpabs_ui (lhs, 1) <= 0)
- {
- /* For 0^rhs and 1^rhs, we just need to verify that
- rhs is well-defined. For (-1)^rhs we need to
- determine (rhs mod 2). For simplicity, compute
- (rhs mod 2) for all three cases. */
- expr_t two, et;
- two = malloc (sizeof (struct expr));
- two -> op = LIT;
- mpz_init_set_ui (two->operands.val, 2L);
- makeexp (&et, MOD, e->operands.ops.rhs, two);
- e->operands.ops.rhs = et;
- }
-
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- if (mpz_cmp_si (rhs, 0L) == 0)
- /* x^0 is 1 */
- mpz_set_ui (r, 1L);
- else if (mpz_cmp_si (lhs, 0L) == 0)
- /* 0^y (where y != 0) is 0 */
- mpz_set_ui (r, 0L);
- else if (mpz_cmp_ui (lhs, 1L) == 0)
- /* 1^y is 1 */
- mpz_set_ui (r, 1L);
- else if (mpz_cmp_si (lhs, -1L) == 0)
- /* (-1)^y just depends on whether y is even or odd */
- mpz_set_si (r, (mpz_get_ui (rhs) & 1) ? -1L : 1L);
- else if (mpz_cmp_si (rhs, 0L) < 0)
- /* x^(-n) is 0 */
- mpz_set_ui (r, 0L);
- else
- {
- unsigned long int cnt;
- unsigned long int y;
- /* error if exponent does not fit into an unsigned long int. */
- if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
- goto pow_err;
-
- y = mpz_get_ui (rhs);
- /* x^y == (x/(2^c))^y * 2^(c*y) */
-#if __GNU_MP_VERSION >= 2
- cnt = mpz_scan1 (lhs, 0);
-#else
- cnt = 0;
-#endif
- if (cnt != 0)
- {
- if (y * cnt / cnt != y)
- goto pow_err;
- mpz_tdiv_q_2exp (lhs, lhs, cnt);
- mpz_pow_ui (r, lhs, y);
- mpz_mul_2exp (r, r, y * cnt);
- }
- else
- mpz_pow_ui (r, lhs, y);
- }
- mpz_clear (lhs); mpz_clear (rhs);
- return;
- pow_err:
- error = "result of `pow' operator too large";
- mpz_clear (lhs); mpz_clear (rhs);
- longjmp (errjmpbuf, 1);
- case GCD:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_gcd (r, lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
-#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
- case LCM:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_lcm (r, lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
-#endif
- case AND:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_and (r, lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
- case IOR:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_ior (r, lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
-#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
- case XOR:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_xor (r, lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
-#endif
- case NEG:
- mpz_eval_expr (r, e->operands.ops.lhs);
- mpz_neg (r, r);
- return;
- case NOT:
- mpz_eval_expr (r, e->operands.ops.lhs);
- mpz_com (r, r);
- return;
- case SQRT:
- mpz_init (lhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- if (mpz_sgn (lhs) < 0)
- {
- error = "cannot take square root of negative numbers";
- mpz_clear (lhs);
- longjmp (errjmpbuf, 1);
- }
- mpz_sqrt (r, lhs);
- return;
-#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
- case ROOT:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- if (mpz_sgn (rhs) <= 0)
- {
- error = "cannot take non-positive root orders";
- mpz_clear (lhs); mpz_clear (rhs);
- longjmp (errjmpbuf, 1);
- }
- if (mpz_sgn (lhs) < 0 && (mpz_get_ui (rhs) & 1) == 0)
- {
- error = "cannot take even root orders of negative numbers";
- mpz_clear (lhs); mpz_clear (rhs);
- longjmp (errjmpbuf, 1);
- }
-
- {
- unsigned long int nth = mpz_get_ui (rhs);
- if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
- {
- /* If we are asked to take an awfully large root order, cheat and
- ask for the largest order we can pass to mpz_root. This saves
- some error prone special cases. */
- nth = ~(unsigned long int) 0;
- }
- mpz_root (r, lhs, nth);
- }
- mpz_clear (lhs); mpz_clear (rhs);
- return;
-#endif
- case FAC:
- mpz_eval_expr (r, e->operands.ops.lhs);
- if (mpz_size (r) > 1)
- {
- error = "result of `!' operator too large";
- longjmp (errjmpbuf, 1);
- }
- mpz_fac_ui (r, mpz_get_ui (r));
- return;
-#if __GNU_MP_VERSION >= 2
- case POPCNT:
- mpz_eval_expr (r, e->operands.ops.lhs);
- { long int cnt;
- cnt = mpz_popcount (r);
- mpz_set_si (r, cnt);
- }
- return;
- case HAMDIST:
- { long int cnt;
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- cnt = mpz_hamdist (lhs, rhs);
- mpz_clear (lhs); mpz_clear (rhs);
- mpz_set_si (r, cnt);
- }
- return;
-#endif
- case LOG2:
- mpz_eval_expr (r, e->operands.ops.lhs);
- { unsigned long int cnt;
- if (mpz_sgn (r) <= 0)
- {
- error = "logarithm of non-positive number";
- longjmp (errjmpbuf, 1);
- }
- cnt = mpz_sizeinbase (r, 2);
- mpz_set_ui (r, cnt - 1);
- }
- return;
- case LOG:
- { unsigned long int cnt;
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- if (mpz_sgn (lhs) <= 0)
- {
- error = "logarithm of non-positive number";
- mpz_clear (lhs); mpz_clear (rhs);
- longjmp (errjmpbuf, 1);
- }
- if (mpz_cmp_ui (rhs, 256) >= 0)
- {
- error = "logarithm base too large";
- mpz_clear (lhs); mpz_clear (rhs);
- longjmp (errjmpbuf, 1);
- }
- cnt = mpz_sizeinbase (lhs, mpz_get_ui (rhs));
- mpz_set_ui (r, cnt - 1);
- mpz_clear (lhs); mpz_clear (rhs);
- }
- return;
- case FERMAT:
- {
- unsigned long int t;
- mpz_init (lhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- t = (unsigned long int) 1 << mpz_get_ui (lhs);
- if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0 || t == 0)
- {
- error = "too large Mersenne number index";
- mpz_clear (lhs);
- longjmp (errjmpbuf, 1);
- }
- mpz_set_ui (r, 1);
- mpz_mul_2exp (r, r, t);
- mpz_add_ui (r, r, 1);
- mpz_clear (lhs);
- }
- return;
- case MERSENNE:
- mpz_init (lhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0)
- {
- error = "too large Mersenne number index";
- mpz_clear (lhs);
- longjmp (errjmpbuf, 1);
- }
- mpz_set_ui (r, 1);
- mpz_mul_2exp (r, r, mpz_get_ui (lhs));
- mpz_sub_ui (r, r, 1);
- mpz_clear (lhs);
- return;
- case FIBONACCI:
- { mpz_t t;
- unsigned long int n, i;
- mpz_init (lhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
- {
- error = "Fibonacci index out of range";
- mpz_clear (lhs);
- longjmp (errjmpbuf, 1);
- }
- n = mpz_get_ui (lhs);
- mpz_clear (lhs);
-
-#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
- mpz_fib_ui (r, n);
-#else
- mpz_init_set_ui (t, 1);
- mpz_set_ui (r, 1);
-
- if (n <= 2)
- mpz_set_ui (r, 1);
- else
- {
- for (i = 3; i <= n; i++)
- {
- mpz_add (t, t, r);
- mpz_swap (t, r);
- }
- }
- mpz_clear (t);
-#endif
- }
- return;
- case RANDOM:
- {
- unsigned long int n;
- mpz_init (lhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
- {
- error = "random number size out of range";
- mpz_clear (lhs);
- longjmp (errjmpbuf, 1);
- }
- n = mpz_get_ui (lhs);
- mpz_clear (lhs);
- mpz_urandomb (r, rstate, n);
- }
- return;
- case NEXTPRIME:
- {
- mpz_eval_expr (r, e->operands.ops.lhs);
- mpz_nextprime (r, r);
- }
- return;
- case BINOM:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_expr (lhs, e->operands.ops.lhs);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- {
- unsigned long int k;
- if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
- {
- error = "k too large in (n over k) expression";
- mpz_clear (lhs); mpz_clear (rhs);
- longjmp (errjmpbuf, 1);
- }
- k = mpz_get_ui (rhs);
- mpz_bin_ui (r, lhs, k);
- }
- mpz_clear (lhs); mpz_clear (rhs);
- return;
- case TIMING:
- {
- int t0;
- t0 = cputime ();
- mpz_eval_expr (r, e->operands.ops.lhs);
- printf ("time: %d\n", cputime () - t0);
- }
- return;
- default:
- abort ();
- }
-}
-
-/* Evaluate the expression E modulo MOD and put the result in R. */
-void
-mpz_eval_mod_expr (mpz_ptr r, expr_t e, mpz_ptr mod)
-{
- mpz_t lhs, rhs;
-
- switch (e->op)
- {
- case POW:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
- mpz_eval_expr (rhs, e->operands.ops.rhs);
- mpz_powm (r, lhs, rhs, mod);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
- case PLUS:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
- mpz_eval_mod_expr (rhs, e->operands.ops.rhs, mod);
- mpz_add (r, lhs, rhs);
- if (mpz_cmp_si (r, 0L) < 0)
- mpz_add (r, r, mod);
- else if (mpz_cmp (r, mod) >= 0)
- mpz_sub (r, r, mod);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
- case MINUS:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
- mpz_eval_mod_expr (rhs, e->operands.ops.rhs, mod);
- mpz_sub (r, lhs, rhs);
- if (mpz_cmp_si (r, 0L) < 0)
- mpz_add (r, r, mod);
- else if (mpz_cmp (r, mod) >= 0)
- mpz_sub (r, r, mod);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
- case MULT:
- mpz_init (lhs); mpz_init (rhs);
- mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
- mpz_eval_mod_expr (rhs, e->operands.ops.rhs, mod);
- mpz_mul (r, lhs, rhs);
- mpz_mod (r, r, mod);
- mpz_clear (lhs); mpz_clear (rhs);
- return;
- default:
- mpz_init (lhs);
- mpz_eval_expr (lhs, e);
- mpz_mod (r, lhs, mod);
- mpz_clear (lhs);
- return;
- }
-}
-
-void
-cleanup_and_exit (int sig)
-{
- switch (sig) {
-#ifdef LIMIT_RESOURCE_USAGE
- case SIGXCPU:
- printf ("expression took too long to evaluate%s\n", newline);
- break;
-#endif
- case SIGFPE:
- printf ("divide by zero%s\n", newline);
- break;
- default:
- printf ("expression required too much memory to evaluate%s\n", newline);
- break;
- }
- exit (-2);
-}
« no previous file with comments | « gcc/gmp/demos/perl/typemap ('k') | gcc/gmp/doc/Makefile.in » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698