CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Views: 418385
1
/* mpz expression evaluation, simple part
2
3
Copyright 2000-2002 Free Software Foundation, Inc.
4
5
This file is part of the GNU MP Library.
6
7
The GNU MP Library is free software; you can redistribute it and/or modify
8
it under the terms of either:
9
10
* the GNU Lesser General Public License as published by the Free
11
Software Foundation; either version 3 of the License, or (at your
12
option) any later version.
13
14
or
15
16
* the GNU General Public License as published by the Free Software
17
Foundation; either version 2 of the License, or (at your option) any
18
later version.
19
20
or both in parallel, as here.
21
22
The GNU MP Library is distributed in the hope that it will be useful, but
23
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25
for more details.
26
27
You should have received copies of the GNU General Public License and the
28
GNU Lesser General Public License along with the GNU MP Library. If not,
29
see https://www.gnu.org/licenses/. */
30
31
#include <ctype.h>
32
#include <stdio.h>
33
#include <string.h>
34
#include "gmp.h"
35
#include "expr-impl.h"
36
37
38
/* Change this to "#define TRACE(x) x" to get some traces. */
39
#define TRACE(x)
40
41
42
/* These are macros, so need function wrappers. */
43
static int
44
e_mpz_sgn (mpz_srcptr x)
45
{
46
return mpz_sgn (x);
47
}
48
static int
49
e_mpz_odd_p (mpz_srcptr x)
50
{
51
return mpz_odd_p (x);
52
}
53
static int
54
e_mpz_even_p (mpz_srcptr x)
55
{
56
return mpz_even_p (x);
57
}
58
59
/* These wrapped because MPEXPR_TYPE_I_ functions are expected to return
60
"int" whereas these return "unsigned long". */
61
static void
62
e_mpz_hamdist (mpz_ptr w, mpz_srcptr x, mpz_srcptr y)
63
{
64
mpz_set_ui (w, mpz_hamdist (x, y));
65
}
66
static void
67
e_mpz_popcount (mpz_ptr w, mpz_srcptr x)
68
{
69
mpz_set_ui (w, mpz_popcount (x));
70
}
71
static void
72
e_mpz_scan0 (mpz_ptr w, mpz_srcptr x, unsigned long start)
73
{
74
mpz_set_ui (w, mpz_scan0 (x, start));
75
}
76
static void
77
e_mpz_scan1 (mpz_ptr w, mpz_srcptr x, unsigned long start)
78
{
79
mpz_set_ui (w, mpz_scan1 (x, start));
80
}
81
82
/* These wrapped because they're in-place whereas MPEXPR_TYPE_BINARY_UI
83
expects a separate source and destination. Actually the parser will
84
normally pass w==x anyway. */
85
static void
86
e_mpz_setbit (mpz_ptr w, mpz_srcptr x, unsigned long n)
87
{
88
if (w != x)
89
mpz_set (w, x);
90
mpz_setbit (w, n);
91
}
92
static void
93
e_mpz_clrbit (mpz_ptr w, mpz_srcptr x, unsigned long n)
94
{
95
if (w != x)
96
mpz_set (w, x);
97
mpz_clrbit (w, n);
98
}
99
100
static const struct mpexpr_operator_t _mpz_expr_standard_table[] = {
101
102
{ "**", (mpexpr_fun_t) mpz_pow_ui,
103
MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 220 },
104
105
{ "~", (mpexpr_fun_t) mpz_com,
106
MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
107
{ "!", (mpexpr_fun_t) e_mpz_sgn,
108
MPEXPR_TYPE_LOGICAL_NOT | MPEXPR_TYPE_PREFIX, 210 },
109
{ "-", (mpexpr_fun_t) mpz_neg,
110
MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
111
112
{ "*", (mpexpr_fun_t) mpz_mul, MPEXPR_TYPE_BINARY, 200 },
113
{ "/", (mpexpr_fun_t) mpz_tdiv_q, MPEXPR_TYPE_BINARY, 200 },
114
{ "%", (mpexpr_fun_t) mpz_tdiv_r, MPEXPR_TYPE_BINARY, 200 },
115
116
{ "+", (mpexpr_fun_t) mpz_add, MPEXPR_TYPE_BINARY, 190 },
117
{ "-", (mpexpr_fun_t) mpz_sub, MPEXPR_TYPE_BINARY, 190 },
118
119
{ "<<", (mpexpr_fun_t) mpz_mul_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
120
{ ">>", (mpexpr_fun_t) mpz_tdiv_q_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
121
122
{ "<=", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_LE, 170 },
123
{ "<", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_LT, 170 },
124
{ ">=", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_GE, 170 },
125
{ ">", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_GT, 170 },
126
127
{ "==", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_EQ, 160 },
128
{ "!=", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_NE, 160 },
129
130
{ "&", (mpexpr_fun_t) mpz_and, MPEXPR_TYPE_BINARY, 150 },
131
{ "^", (mpexpr_fun_t) mpz_xor, MPEXPR_TYPE_BINARY, 140 },
132
{ "|", (mpexpr_fun_t) mpz_ior, MPEXPR_TYPE_BINARY, 130 },
133
{ "&&", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_LOGICAL_AND, 120 },
134
{ "||", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_LOGICAL_OR, 110 },
135
136
{ ":", NULL, MPEXPR_TYPE_COLON, 101 },
137
{ "?", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_QUESTION, 100 },
138
139
{ ")", NULL, MPEXPR_TYPE_CLOSEPAREN, 4 },
140
{ "(", NULL, MPEXPR_TYPE_OPENPAREN, 3 },
141
{ ",", NULL, MPEXPR_TYPE_ARGSEP, 2 },
142
{ "$", NULL, MPEXPR_TYPE_VARIABLE, 1 },
143
144
{ "abs", (mpexpr_fun_t) mpz_abs, MPEXPR_TYPE_UNARY },
145
{ "bin", (mpexpr_fun_t) mpz_bin_ui, MPEXPR_TYPE_BINARY_UI },
146
{ "clrbit", (mpexpr_fun_t) e_mpz_clrbit, MPEXPR_TYPE_BINARY_UI },
147
{ "cmp", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_I_BINARY },
148
{ "cmpabs", (mpexpr_fun_t) mpz_cmpabs, MPEXPR_TYPE_I_BINARY },
149
{ "congruent_p",(mpexpr_fun_t)mpz_congruent_p, MPEXPR_TYPE_I_TERNARY },
150
{ "divisible_p",(mpexpr_fun_t)mpz_divisible_p, MPEXPR_TYPE_I_BINARY },
151
{ "even_p", (mpexpr_fun_t) e_mpz_even_p, MPEXPR_TYPE_I_UNARY },
152
{ "fib", (mpexpr_fun_t) mpz_fib_ui, MPEXPR_TYPE_UNARY_UI },
153
{ "fac", (mpexpr_fun_t) mpz_fac_ui, MPEXPR_TYPE_UNARY_UI },
154
{ "gcd", (mpexpr_fun_t) mpz_gcd, MPEXPR_TYPE_BINARY
155
| MPEXPR_TYPE_PAIRWISE },
156
{ "hamdist", (mpexpr_fun_t) e_mpz_hamdist, MPEXPR_TYPE_BINARY },
157
{ "invert", (mpexpr_fun_t) mpz_invert, MPEXPR_TYPE_BINARY },
158
{ "jacobi", (mpexpr_fun_t) mpz_jacobi, MPEXPR_TYPE_I_BINARY },
159
{ "kronecker", (mpexpr_fun_t) mpz_kronecker, MPEXPR_TYPE_I_BINARY },
160
{ "lcm", (mpexpr_fun_t) mpz_lcm, MPEXPR_TYPE_BINARY
161
| MPEXPR_TYPE_PAIRWISE },
162
{ "lucnum", (mpexpr_fun_t) mpz_lucnum_ui, MPEXPR_TYPE_UNARY_UI },
163
{ "max", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_MAX
164
| MPEXPR_TYPE_PAIRWISE },
165
{ "min", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_MIN
166
| MPEXPR_TYPE_PAIRWISE },
167
{ "nextprime", (mpexpr_fun_t) mpz_nextprime, MPEXPR_TYPE_UNARY },
168
{ "odd_p", (mpexpr_fun_t) e_mpz_odd_p, MPEXPR_TYPE_I_UNARY },
169
{ "perfect_power_p", (mpexpr_fun_t)mpz_perfect_power_p, MPEXPR_TYPE_I_UNARY},
170
{ "perfect_square_p",(mpexpr_fun_t)mpz_perfect_square_p,MPEXPR_TYPE_I_UNARY},
171
{ "popcount", (mpexpr_fun_t) e_mpz_popcount, MPEXPR_TYPE_UNARY },
172
{ "powm", (mpexpr_fun_t) mpz_powm, MPEXPR_TYPE_TERNARY },
173
{ "probab_prime_p", (mpexpr_fun_t)mpz_probab_prime_p, MPEXPR_TYPE_I_UNARY},
174
{ "root", (mpexpr_fun_t) mpz_root, MPEXPR_TYPE_BINARY_UI },
175
{ "scan0", (mpexpr_fun_t) e_mpz_scan0, MPEXPR_TYPE_BINARY_UI },
176
{ "scan1", (mpexpr_fun_t) e_mpz_scan1, MPEXPR_TYPE_BINARY_UI },
177
{ "setbit", (mpexpr_fun_t) e_mpz_setbit, MPEXPR_TYPE_BINARY_UI },
178
{ "tstbit", (mpexpr_fun_t) mpz_tstbit, MPEXPR_TYPE_I_BINARY_UI },
179
{ "sgn", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_I_UNARY },
180
{ "sqrt", (mpexpr_fun_t) mpz_sqrt, MPEXPR_TYPE_UNARY },
181
{ NULL }
182
};
183
184
/* The table is available globally only through a pointer, so the table size
185
can change without breaking binary compatibility. */
186
const struct mpexpr_operator_t * const mpz_expr_standard_table
187
= _mpz_expr_standard_table;
188
189
190
int
191
mpz_expr (mpz_ptr res, int base, const char *e, ...)
192
{
193
mpz_srcptr var[MPEXPR_VARIABLES];
194
va_list ap;
195
int ret;
196
va_start (ap, e);
197
198
TRACE (printf ("mpz_expr(): base %d, %s\n", base, e));
199
ret = mpexpr_va_to_var ((void **) var, ap);
200
va_end (ap);
201
202
if (ret != MPEXPR_RESULT_OK)
203
return ret;
204
205
return mpz_expr_a (mpz_expr_standard_table, res, base, e, strlen(e), var);
206
}
207
208