github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/demos/expr/exprfa.c (about) 1 /* mpf expression evaluation 2 3 Copyright 2000-2002, 2004 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 32 /* Future: Bitwise "&", "|" and "&" could be done, if desired. Not sure 33 those functions would be much value though. */ 34 35 36 #include <ctype.h> 37 #include <stdio.h> 38 #include <string.h> 39 40 #include "gmp.h" 41 #include "expr-impl.h" 42 43 44 /* Change this to "#define TRACE(x) x" to get some traces. */ 45 #define TRACE(x) 46 47 48 static size_t 49 e_mpf_number (mpf_ptr res, const char *e, size_t elen, int base) 50 { 51 char *edup; 52 size_t i, ret, extra=0; 53 int mant_base, exp_base; 54 void *(*allocate_func) (size_t); 55 void (*free_func) (void *, size_t); 56 57 TRACE (printf ("mpf_number base=%d \"%.*s\"\n", base, (int) elen, e)); 58 59 /* mpf_set_str doesn't currently accept 0x for hex in base==0, so do it 60 here instead. FIXME: Would prefer to let mpf_set_str handle this. */ 61 if (base == 0 && elen >= 2 && e[0] == '0' && (e[1] == 'x' || e[1] == 'X')) 62 { 63 base = 16; 64 extra = 2; 65 e += extra; 66 elen -= extra; 67 } 68 69 if (base == 0) 70 mant_base = 10; 71 else if (base < 0) 72 mant_base = -base; 73 else 74 mant_base = base; 75 76 /* exponent in decimal if base is negative */ 77 if (base < 0) 78 exp_base = 10; 79 else if (base == 0) 80 exp_base = 10; 81 else 82 exp_base = base; 83 84 #define IS_EXPONENT(c) \ 85 (c == '@' || (base <= 10 && base >= -10 && (e[i] == 'e' || e[i] == 'E'))) 86 87 i = 0; 88 for (;;) 89 { 90 if (i >= elen) 91 goto parsed; 92 if (e[i] == '.') 93 break; 94 if (IS_EXPONENT (e[i])) 95 goto exponent; 96 if (! isasciidigit_in_base (e[i], mant_base)) 97 goto parsed; 98 i++; 99 } 100 101 /* fraction */ 102 i++; 103 for (;;) 104 { 105 if (i >= elen) 106 goto parsed; 107 if (IS_EXPONENT (e[i])) 108 goto exponent; 109 if (! isasciidigit_in_base (e[i], mant_base)) 110 goto parsed; 111 i++; 112 } 113 114 exponent: 115 i++; 116 if (i >= elen) 117 goto parsed; 118 if (e[i] == '-') 119 i++; 120 for (;;) 121 { 122 if (i >= elen) 123 goto parsed; 124 if (! isasciidigit_in_base (e[i], exp_base)) 125 break; 126 i++; 127 } 128 129 parsed: 130 TRACE (printf (" parsed i=%u \"%.*s\"\n", i, (int) i, e)); 131 132 mp_get_memory_functions (&allocate_func, NULL, &free_func); 133 edup = (*allocate_func) (i+1); 134 memcpy (edup, e, i); 135 edup[i] = '\0'; 136 137 if (mpf_set_str (res, edup, base) == 0) 138 ret = i + extra; 139 else 140 ret = 0; 141 142 (*free_func) (edup, i+1); 143 return ret; 144 } 145 146 static int 147 e_mpf_ulong_p (mpf_srcptr f) 148 { 149 return mpf_integer_p (f) && mpf_fits_ulong_p (f); 150 } 151 152 /* Don't want to change the precision of w, can only do an actual swap when 153 w and x have the same precision. */ 154 static void 155 e_mpf_set_or_swap (mpf_ptr w, mpf_ptr x) 156 { 157 if (mpf_get_prec (w) == mpf_get_prec (x)) 158 mpf_swap (w, x); 159 else 160 mpf_set (w, x); 161 } 162 163 164 int 165 mpf_expr_a (const struct mpexpr_operator_t *table, 166 mpf_ptr res, int base, unsigned long prec, 167 const char *e, size_t elen, 168 mpf_srcptr var[26]) 169 { 170 struct mpexpr_parse_t p; 171 172 p.table = table; 173 p.res = (mpX_ptr) res; 174 p.base = base; 175 p.prec = prec; 176 p.e = e; 177 p.elen = elen; 178 p.var = (mpX_srcptr *) var; 179 180 p.mpX_clear = (mpexpr_fun_one_t) mpf_clear; 181 p.mpX_ulong_p = (mpexpr_fun_i_unary_t) e_mpf_ulong_p; 182 p.mpX_get_ui = (mpexpr_fun_get_ui_t) mpf_get_ui; 183 p.mpX_init = (mpexpr_fun_unary_ui_t) mpf_init2; 184 p.mpX_number = (mpexpr_fun_number_t) e_mpf_number; 185 p.mpX_set = (mpexpr_fun_unary_t) mpf_set; 186 p.mpX_set_or_swap = (mpexpr_fun_unary_t) e_mpf_set_or_swap; 187 p.mpX_set_si = (mpexpr_fun_set_si_t) mpf_set_si; 188 p.mpX_swap = (mpexpr_fun_swap_t) mpf_swap; 189 190 return mpexpr_evaluate (&p); 191 }