MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
mathp.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/libraries/libmbutil/mathp.cc,v 1.126 2017/04/28 17:59:55 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 /*
33  * With the contribution of Ankit Aggarwal <ankit.ankit.aggarwal@gmail.com>
34  * during Google Summer of Code 2015
35  */
36 
37 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
38 
39 #include <cerrno>
40 #include <cfloat>
41 #include <cstdlib>
42 #include <climits>
43 #include <limits>
44 #include <sstream>
45 
46 #include "mathp.h"
47 #include "parser.h"
48 
49 #ifdef USE_EE
50 #include "evaluator_impl.h"
51 #endif // USE_EE
52 
53 
54 /* helper per le funzioni built-in */
55 typedef double (*mp_f1_f)(double);
56 typedef double (*mp_f2_f)(double, double);
57 
58 template <class Tin, class Tout, mp_f1_f F>
59 static int
61 {
62  ASSERT(args.size() == 1 + 1);
63  ASSERT(args[0]->Type() == MathParser::AT_REAL);
64  ASSERT(args[1]->Type() == MathParser::AT_REAL);
65 
66  Tout *out = dynamic_cast<Tout *>(args[0]);
67  ASSERT(out != 0);
68 
69  Tin *arg1 = dynamic_cast<Tin *>(args[1]);
70  ASSERT(arg1 != 0);
71 
72  *out = F((*arg1)());
73 
74  return 0;
75 }
76 
77 template <class Tin, class Tout, mp_f2_f F>
78 static int
80 {
81  ASSERT(args.size() == 1 + 1);
82  ASSERT(args[0]->Type() == MathParser::AT_REAL);
83  ASSERT(args[1]->Type() == MathParser::AT_REAL);
84  ASSERT(args[2]->Type() == MathParser::AT_REAL);
85 
86  Tout *out = dynamic_cast<Tout *>(args[0]);
87  ASSERT(out != 0);
88 
89  Tin *arg1 = dynamic_cast<Tin *>(args[1]);
90  ASSERT(arg1 != 0);
91 
92  Tin *arg2 = dynamic_cast<Tin *>(args[2]);
93  ASSERT(arg2 != 0);
94 
95  Real a1 = (*arg1)();
96  Real a2 = (*arg2)();
97  *out = F(a1, a2);
98 
99  return 0;
100 }
101 
102 static int
104 {
105  ASSERT(args.size() == 1 + 1);
106  ASSERT(args[1]->Type() == MathParser::AT_REAL);
107 
108  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t *>(args[1]);
109  ASSERT(arg1 != 0);
110 
111  const Real a1 = (*arg1)();
112  if (a1 > 1. || a1 < -1.) {
113  return 1;
114  }
115 
116  return 0;
117 }
118 
119 static int
121 {
122  ASSERT(args.size() == 1 + 1);
123  ASSERT(args[1]->Type() == MathParser::AT_REAL);
124 
125  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t *>(args[1]);
126  ASSERT(arg1 != 0);
127 
128  const Real a1 = (*arg1)();
129  if (a1 > 1. || a1 < -1.) {
130  return 1;
131  }
132 
133  return 0;
134 }
135 
136 static int
138 {
139  ASSERT(args.size() == 1 + 1);
140  ASSERT(args[1]->Type() == MathParser::AT_REAL);
141 
142  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t *>(args[1]);
143  ASSERT(arg1 != 0);
144 
145  Real a1 = (*arg1)();
146  Real a = a1;
147  a -= int(a1/M_PI)*M_PI;
148  if (fabs(fabs(a) - M_PI_2) < std::numeric_limits<double>::epsilon()) {
149  return 1;
150  }
151 
152  return 0;
153 }
154 
155 static int
157 {
158  ASSERT(args.size() == 1 + 1);
159  ASSERT(args[1]->Type() == MathParser::AT_REAL);
160 
161  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t *>(args[1]);
162  ASSERT(arg1 != 0);
163 
164  if ((*arg1)() <= 1.) {
165  return 1;
166  }
167 
168  return 0;
169 }
170 
171 static int
173 {
174  ASSERT(args.size() == 1 + 1);
175  ASSERT(args[1]->Type() == MathParser::AT_REAL);
176 
177  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t *>(args[1]);
178  ASSERT(arg1 != 0);
179 
180  Real a1 = (*arg1)();
181  if (a1 >= 1. || a1 <= -1.) {
182  return 1;
183  }
184 
185  return 0;
186 }
187 
188 static int
190 {
191  ASSERT(args.size() == 1 + 1);
192  ASSERT(args[1]->Type() == MathParser::AT_REAL);
193 
194  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t *>(args[1]);
195  ASSERT(arg1 != 0);
196 
197  if ((*arg1)() <= 0.) {
198  return 1;
199  }
200 
201  return 0;
202 }
203 
204 static int
206 {
207  ASSERT(args.size() == 1 + 1);
208  ASSERT(args[1]->Type() == MathParser::AT_REAL);
209 
210  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t *>(args[1]);
211  ASSERT(arg1 != 0);
212 
213  if ((*arg1)() < 0.) {
214  return 1;
215  }
216 
217  return 0;
218 }
219 
220 static int
222 {
223  ASSERT(args.size() == 1 + 0);
224  ASSERT(args[0]->Type() == MathParser::AT_INT);
225 
226  MathParser::MathArgInt_t* out = dynamic_cast<MathParser::MathArgInt_t*>(args[0]);
227  ASSERT(out != 0);
228 
229  *out = rand();
230 
231  return 0;
232 }
233 
234 static int
236 {
237  ASSERT(args.size() == 1 + 0);
238  ASSERT(args[0]->Type() == MathParser::AT_REAL);
239 
240  MathParser::MathArgReal_t* out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
241  ASSERT(out != 0);
242 
243  *out = -1. + 2.*(Real(rand())/Real(RAND_MAX));
244 
245  return 0;
246 }
247 
248 static int
250 {
251  ASSERT(args.size() == 1 + 1);
252  ASSERT(args[0]->Type() == MathParser::AT_VOID);
253  ASSERT(args[1]->Type() == MathParser::AT_INT);
254 
255  MathParser::MathArgInt_t *arg1 = dynamic_cast<MathParser::MathArgInt_t *>(args[1]);
256  ASSERT(arg1 != 0);
257 
258  srand((unsigned int)(*arg1)());
259 
260  return 0;
261 }
262 
263 static int
265 {
266  ASSERT(args.size() == 1 + 2);
267  ASSERT(args[0]->Type() == MathParser::AT_STRING);
268  ASSERT(args[1]->Type() == MathParser::AT_STRING);
269  ASSERT(args[2]->Type() == MathParser::AT_ANY);
270 
271  MathParser::MathArgString_t *arg1 = dynamic_cast<MathParser::MathArgString_t *>(args[1]);
272  MathParser::MathArgAny_t *arg2 = dynamic_cast<MathParser::MathArgAny_t *>(args[2]);
273  ASSERT(arg1 != 0);
274 
275  char buf[BUFSIZ];
276  const char *fmt = ((std::string&)(*arg1)()).c_str();
277  int rc;
278 
279  switch ((*arg2)().GetType()) {
280  case TypedValue::VAR_BOOL: {
281  rc = snprintf(buf, sizeof(buf), fmt, (*arg2)().GetBool());
282  } break;
283 
284  case TypedValue::VAR_INT: {
285  rc = snprintf(buf, sizeof(buf), fmt, (*arg2)().GetInt());
286  } break;
287 
288  case TypedValue::VAR_REAL: {
289  rc = snprintf(buf, sizeof(buf), fmt, (*arg2)().GetReal());
290  } break;
291 
292  case TypedValue::VAR_STRING: {
293  rc = snprintf(buf, sizeof(buf), fmt, (*arg2)().GetString().c_str());
294  } break;
295 
296  default:
297  // impossible?
299  }
300 
301  if (rc < 0 || (unsigned long)rc >= sizeof(buf)) {
303  }
304 
305  MathParser::MathArgString_t* out = dynamic_cast<MathParser::MathArgString_t*>(args[0]);
306  ASSERT(out != 0);
307 
308  *out = std::string(buf);
309 
310  return 0;
311 }
312 
313 std::ostream&
314 operator << (std::ostream& out, const MathParser::MathArgVoid_t& /* v */ )
315 {
316  return out;
317 }
318 
319 std::ostream&
320 operator << (std::ostream& out, const MathParser::MathArgBool_t& v)
321 {
322  return out << v();
323 }
324 
325 std::ostream&
326 operator << (std::ostream& out, const MathParser::MathArgInt_t& v)
327 {
328  return out << v();
329 }
330 
331 std::ostream&
332 operator << (std::ostream& out, const MathParser::MathArgReal_t& v)
333 {
334  return out << v();
335 }
336 
337 std::ostream&
338 operator << (std::ostream& out, const MathParser::MathArgString_t& v)
339 {
340  return out << v();
341 }
342 
343 static int
345 {
346  ASSERT(args.size() == 1 + 1);
347 
348  switch (args[1]->Type()) {
349  case MathParser::AT_BOOL:
350  silent_cout((*dynamic_cast<MathParser::MathArgBool_t*>(args[1])) << std::endl);
351  break;
352 
353  case MathParser::AT_INT:
354  silent_cout((*dynamic_cast<MathParser::MathArgInt_t*>(args[1])) << std::endl);
355  break;
356 
357  case MathParser::AT_REAL:
358  silent_cout((*dynamic_cast<MathParser::MathArgReal_t*>(args[1])) << std::endl);
359  break;
360 
362  silent_cout((*dynamic_cast<MathParser::MathArgString_t*>(args[1])) << std::endl);
363  break;
364 
365  default:
367  }
368 
369  return 0;
370 }
371 
372 static int
374 {
375  ASSERT(args.size() == 1 + 2);
376  ASSERT(args[0]->Type() == MathParser::AT_VOID);
377  ASSERT(args[1]->Type() == MathParser::AT_INT);
378  ASSERT(args[2]->Type() == MathParser::AT_INT);
379 
380  MathParser::MathArgInt_t *s = dynamic_cast<MathParser::MathArgInt_t *>(args[1]);
381  ASSERT(s != 0);
382 
383  MathParser::MathArgInt_t *v = dynamic_cast<MathParser::MathArgInt_t *>(args[2]);
384  ASSERT(v != 0);
385 
386  if ((*s)() != 0) {
387  if ((*v)() == 0) {
388  silent_cout("mp_stop(SUCCESS)" << std::endl);
389  throw NoErr(MBDYN_EXCEPT_ARGS);
390 
391  } else {
392  silent_cout("mp_stop(FAILURE)" << std::endl);
394  }
395  }
396 
397  return 0;
398 }
399 
400 static int
402 {
403  ASSERT(args.size() == 1 + 1);
404  ASSERT(args[0]->Type() == MathParser::AT_REAL);
405  ASSERT(args[1]->Type() == MathParser::AT_REAL);
406 
407  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t *>(args[0]);
408  ASSERT(out != 0);
409 
410  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t *>(args[1]);
411  ASSERT(arg1 != 0);
412 
413  *out = 1./tan((*arg1)());
414 
415  return 0;
416 }
417 
418 static int
420 {
421  ASSERT(args.size() == 1 + 1);
422  ASSERT(args[1]->Type() == MathParser::AT_REAL);
423 
424  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t *>(args[1]);
425  ASSERT(arg1 != 0);
426 
427  Real a1 = (*arg1)();
428  Real a = a1;
429  a -= int(a1/M_PI)*M_PI;
430  if (fabs(a) < std::numeric_limits<double>::epsilon()) {
431  return 1;
432  }
433 
434  return 0;
435 }
436 
437 static int
439 {
440  ASSERT(args.size() == 1 + 1);
441  ASSERT(args[0]->Type() == MathParser::AT_REAL);
442  ASSERT(args[1]->Type() == MathParser::AT_REAL);
443 
444  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
445  ASSERT(out != 0);
446 
447  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
448  ASSERT(arg1 != 0);
449 
450  *out = atan2(1., (*arg1)());
451 
452  return 0;
453 }
454 
455 static int
457 {
458  ASSERT(args.size() == 1 + 2);
459  ASSERT(args[0]->Type() == MathParser::AT_REAL);
460  ASSERT(args[1]->Type() == MathParser::AT_REAL);
461  ASSERT(args[2]->Type() == MathParser::AT_REAL);
462 
463  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
464  ASSERT(out != 0);
465 
466  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
467  ASSERT(arg1 != 0);
468 
469  MathParser::MathArgReal_t *arg2 = dynamic_cast<MathParser::MathArgReal_t*>(args[2]);
470  ASSERT(arg2 != 0);
471 
472  Real a1 = (*arg1)();
473  Real a2 = (*arg2)();
474 
475  *out = atan2(a2, a1);
476 
477  return 0;
478 }
479 
480 static int
482 {
483  ASSERT(args.size() == 1 + 1);
484  ASSERT(args[0]->Type() == MathParser::AT_REAL);
485  ASSERT(args[1]->Type() == MathParser::AT_REAL);
486 
487  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
488  ASSERT(out != 0);
489 
490  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
491  ASSERT(arg1 != 0);
492 
493  *out = 1./tanh((*arg1)());
494 
495  return 0;
496 }
497 
498 static int
500 {
501  ASSERT(args.size() == 1 + 1);
502  ASSERT(args[1]->Type() == MathParser::AT_REAL);
503 
504  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
505  ASSERT(arg1 != 0);
506 
507  if (fabs((*arg1)()) < std::numeric_limits<double>::epsilon()) {
508  return 1;
509  }
510 
511  return 0;
512 }
513 
514 static int
516 {
517  ASSERT(args.size() == 1 + 1);
518  ASSERT(args[0]->Type() == MathParser::AT_REAL);
519  ASSERT(args[1]->Type() == MathParser::AT_REAL);
520 
521  MathParser::MathArgInt_t *out = dynamic_cast<MathParser::MathArgInt_t*>(args[0]);
522  ASSERT(out != 0);
523 
524  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
525  ASSERT(arg1 != 0);
526 
527  Real a1 = (*arg1)();
528  if (a1 == 0.) {
529  *out = 0;
530  } else {
531  *out = Int(copysign(1., a1));
532  }
533 
534  return 0;
535 }
536 
537 static int
539 {
540  ASSERT(args.size() == 1 + 2);
541  ASSERT(args[0]->Type() == MathParser::AT_REAL);
542  ASSERT(args[1]->Type() == MathParser::AT_REAL);
543  ASSERT(args[2]->Type() == MathParser::AT_REAL);
544 
545  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
546  ASSERT(out != 0);
547 
548  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
549  ASSERT(arg1 != 0);
550 
551  MathParser::MathArgReal_t *arg2 = dynamic_cast<MathParser::MathArgReal_t*>(args[2]);
552  ASSERT(arg2 != 0);
553 
554  Real a1 = (*arg1)();
555  Real a2 = (*arg2)();
556  *out = std::max(a1, a2);
557 
558  return 0;
559 }
560 
561 static int
563 {
564  ASSERT(args.size() == 1 + 2);
565  ASSERT(args[0]->Type() == MathParser::AT_REAL);
566  ASSERT(args[1]->Type() == MathParser::AT_REAL);
567  ASSERT(args[2]->Type() == MathParser::AT_REAL);
568 
569  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
570  ASSERT(out != 0);
571 
572  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
573  ASSERT(arg1 != 0);
574 
575  MathParser::MathArgReal_t *arg2 = dynamic_cast<MathParser::MathArgReal_t*>(args[2]);
576  ASSERT(arg2 != 0);
577 
578  Real a1 = (*arg1)();
579  Real a2 = (*arg2)();
580  *out = std::min(a1, a2);
581 
582  return 0;
583 }
584 
585 #ifdef __USE_XOPEN
586 static int
587 mp_actgh(const MathParser::MathArgs& args)
588 {
589  ASSERT(args.size() == 1 + 1);
590  ASSERT(args[0]->Type() == MathParser::AT_REAL);
591  ASSERT(args[1]->Type() == MathParser::AT_REAL);
592 
593  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
594  ASSERT(out != 0);
595 
596  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
597  ASSERT(arg1 != 0);
598 
599  *out = atanh(1./(*arg1)());
600 
601  return 0;
602 }
603 #endif
604 
605 static int
607 {
608  ASSERT(args.size() == 1 + 1);
609  ASSERT(args[0]->Type() == MathParser::AT_REAL);
610  ASSERT(args[1]->Type() == MathParser::AT_REAL);
611 
612  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
613  ASSERT(out != 0);
614 
615  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
616  ASSERT(arg1 != 0);
617 
618  Real a1 = (*arg1)();
619  if (a1 > 0.) {
620  *out = 1.;
621 
622  } else if (a1 < 0.) {
623  *out = 0.;
624 
625  } else {
626  *out = .5;
627  }
628 
629  return 0;
630 }
631 
632 static int
634 {
635  ASSERT(args.size() == 1 + 1);
636  ASSERT(args[0]->Type() == MathParser::AT_REAL);
637  ASSERT(args[1]->Type() == MathParser::AT_REAL);
638 
639  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
640  ASSERT(out != 0);
641 
642  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
643  ASSERT(arg1 != 0);
644 
645  Real a1 = (*arg1)();
646  if (a1 > 0.) {
647  *out = a1;
648 
649  } else {
650  *out = 0.;
651  }
652 
653  return 0;
654 }
655 
656 static int
658 {
659  ASSERT(args.size() == 1 + 2);
660  ASSERT(args[0]->Type() == MathParser::AT_REAL);
661  ASSERT(args[1]->Type() == MathParser::AT_REAL);
662  ASSERT(args[2]->Type() == MathParser::AT_REAL);
663 
664  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
665  ASSERT(out != 0);
666 
667  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
668  ASSERT(arg1 != 0);
669 
670  MathParser::MathArgReal_t *arg2 = dynamic_cast<MathParser::MathArgReal_t*>(args[2]);
671  ASSERT(arg2 != 0);
672 
673  Real a1 = (*arg1)();
674  Real a2 = (*arg2)();
675  if (a1 < 0.) {
676  *out = 0.;
677 
678  } else if (a1 > a2) {
679  *out = a2;
680 
681  } else {
682  *out = a1;
683  }
684 
685  return 0;
686 }
687 
688 static int
690 {
691  ASSERT(args.size() == 1 + 1);
692  ASSERT(args[0]->Type() == MathParser::AT_REAL);
693  ASSERT(args[1]->Type() == MathParser::AT_REAL);
694 
695  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
696  ASSERT(out != 0);
697 
698  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
699  ASSERT(arg1 != 0);
700 
701  Real a1 = (*arg1)();
702  if (a1 > 0.) {
703  *out = a1*a1;
704 
705  } else {
706  *out = 0.;
707  }
708 
709  return 0;
710 }
711 
712 enum mp_in_e {
717 };
718 
719 template<mp_in_e IN>
720 static int
722 {
723  ASSERT(args.size() == 1 + 3);
724  ASSERT(args[0]->Type() == MathParser::AT_REAL);
725  ASSERT(args[1]->Type() == MathParser::AT_REAL);
726  ASSERT(args[2]->Type() == MathParser::AT_REAL);
727  ASSERT(args[3]->Type() == MathParser::AT_REAL);
728 
729  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
730  ASSERT(out != 0);
731 
732  MathParser::MathArgReal_t *arg1 = dynamic_cast<MathParser::MathArgReal_t*>(args[1]);
733  ASSERT(arg1 != 0);
734 
735  MathParser::MathArgReal_t *arg2 = dynamic_cast<MathParser::MathArgReal_t*>(args[2]);
736  ASSERT(arg2 != 0);
737 
738  MathParser::MathArgReal_t *arg3 = dynamic_cast<MathParser::MathArgReal_t*>(args[3]);
739  ASSERT(arg3 != 0);
740 
741  Real l = (*arg1)();
742  Real x = (*arg2)();
743  Real u = (*arg3)();
744 
745  switch (IN) {
746  case IN_LL:
747  case IN_LE:
748  if (x <= l) {
749  *out = 0;
750  return 0;
751  }
752  break;
753 
754  case IN_EL:
755  case IN_EE:
756  if (x < l) {
757  *out = 0;
758  return 0;
759  }
760  break;
761  }
762 
763  switch (IN) {
764  case IN_LL:
765  case IN_EL:
766  if (x >= u) {
767  *out = 0;
768  return 0;
769  }
770  break;
771 
772  case IN_LE:
773  case IN_EE:
774  if (x > u) {
775  *out = 0;
776  return 0;
777  }
778  break;
779  }
780 
781  *out = 1;
782 
783  return 0;
784 }
785 
786 static int
788 {
789  ASSERT(args.size() == 1 + 1);
790  ASSERT(args[0]->Type() == MathParser::AT_ANY);
791 
792  MathParser::MathArgAny_t *arg1 = dynamic_cast<MathParser::MathArgAny_t*>(args[1]);
793  ASSERT(arg1 != 0);
794 
795  switch (args[0]->Type()) {
796  case MathParser::AT_BOOL: {
797  MathParser::MathArgBool_t *out = dynamic_cast<MathParser::MathArgBool_t*>(args[0]);
798  ASSERT(out != 0);
799  (*out)() = (*arg1)().GetBool();
800  } break;
801 
802  case MathParser::AT_INT: {
803  MathParser::MathArgInt_t *out = dynamic_cast<MathParser::MathArgInt_t*>(args[0]);
804  ASSERT(out != 0);
805  (*out)() = (*arg1)().GetInt();
806  } break;
807 
808  case MathParser::AT_REAL: {
809  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t*>(args[0]);
810  ASSERT(out != 0);
811  (*out)() = (*arg1)().GetReal();
812  } break;
813 
814  case MathParser::AT_STRING: {
815  MathParser::MathArgString_t *out = dynamic_cast<MathParser::MathArgString_t*>(args[0]);
816  ASSERT(out != 0);
818  val.Cast((*arg1)());
819  (*out)() = val.GetString();
820  } break;
821 
822  default:
823  // add support for future types
824  return 1;
825  }
826 
827  return 0;
828 }
829 
830 /* tipi delle variabili */
831 struct TypeName_t {
832  const char* name;
834 };
835 
836 static const TypeName_t TypeNames[] = {
837  { "bool", TypedValue::VAR_BOOL },
838  { "integer", TypedValue::VAR_INT },
839  { "real", TypedValue::VAR_REAL },
840  { "string", TypedValue::VAR_STRING },
841 
842  { NULL, TypedValue::VAR_UNKNOWN }
843 };
844 
846  const char* name;
848 };
849 
851  { "const", TypedValue::MOD_CONST },
852  { NULL, TypedValue::MOD_UNKNOWN }
853 };
854 
856  const char* name;
858 };
859 
861  { "ifndef", MathParser::DMOD_IFNDEF },
862  { NULL, MathParser::DMOD_UNKNOWN }
863 };
864 
866  const TypedValue::Type& to,
867  const TypedValue::Type& from,
868  const std::string r)
869 : MBDynErrBase(MBDYN_EXCEPT_ARGS_NOOPT_PASSTHRU, std::string("cannot cast \"") + GetTypeName(from) + "\" into \"" + GetTypeName(to) + "\"" + r)
870 {
871  NO_OP;
872 }
873 
876 {
877  NO_OP;
878 }
879 
881 {
882  NO_OP;
883 }
884 
885 TypedValue::TypedValue(const bool& b, bool isConst)
886 : type(TypedValue::VAR_BOOL), bConst(isConst)
887 {
888  v.i = b;
889 }
890 
891 TypedValue::TypedValue(const Int& i, bool isConst)
892 : type(TypedValue::VAR_INT), bConst(isConst)
893 {
894  v.i = i;
895 }
896 
897 TypedValue::TypedValue(const Real& r, bool isConst)
898 : type(TypedValue::VAR_REAL), bConst(isConst)
899 {
900  v.r = r;
901 }
902 
903 TypedValue::TypedValue(const std::string& s, bool isConst)
904 : type(TypedValue::VAR_STRING), bConst(isConst), s(s)
905 {
906  NO_OP;
907 }
908 
910 : type(t), bConst(isConst)
911 {
912  switch (type) {
914  case TypedValue::VAR_INT:
915  v.i = 0;
916  break;
917 
919  v.r = 0.;
920  break;
921 
923  s = "";
924  break;
925 
926  default:
928  }
929 }
930 
931 // NOTE: TypedValue does not inherit const'ness
933 : type(var.type), bConst(false)
934 {
935  switch (type) {
937  ASSERT(var.v.i == 0 || var.v.i == 1);
938  // fallthru
939  case TypedValue::VAR_INT:
940  v.i = var.v.i;
941  break;
942 
944  v.r = var.v.r;
945  break;
946 
948  s = var.s;
949  break;
950 
952  /* allow initialization from unspecified type right now */
953  break;
954 
955  default:
957  }
958 }
959 
960 TypedValue&
962 {
963  if (Const()) {
965  }
966 
967  bConst = false;
968  if (type == TypedValue::VAR_STRING) {
969  char buf[BUFSIZ];
970 
971  switch (var.type) {
973  case TypedValue::VAR_INT:
974  snprintf(buf, sizeof(buf), "%ld", (long)var.GetInt());
975  Set(std::string(buf));
976  break;
977 
979  snprintf(buf, sizeof(buf), "%e", (double)var.GetReal());
980  Set(std::string(buf));
981  break;
982 
984  this->s = var.GetString();
985  break;
986 
987  default:
989  }
990 
991  } else {
992  switch (var.type) {
994  type = var.type;
995  Set(var.GetBool());
996  break;
997 
998  case TypedValue::VAR_INT:
999  type = var.type;
1000  Set(var.GetInt());
1001  break;
1002 
1003  case TypedValue::VAR_REAL:
1004  type = var.type;
1005  Set(var.GetReal());
1006  break;
1007 
1009  if (type != TypedValue::VAR_UNKNOWN) {
1010  throw ErrWrongType(MBDYN_EXCEPT_ARGS, type, var.type);
1011  }
1013  s = var.s;
1014  break;
1015 
1017  if (type != TypedValue::VAR_UNKNOWN) {
1018  throw ErrWrongType(MBDYN_EXCEPT_ARGS, type, var.type);
1019  }
1020  break;
1021 
1022  default:
1024  }
1025  }
1026 
1027  // NOTE: TypedValue does not inherit const'ness
1028  return *this;
1029 }
1030 
1031 TypedValue&
1032 TypedValue::Cast(const TypedValue& var, bool bErr)
1033 {
1034  if (Const()) {
1036  }
1037 
1038  if (type == TypedValue::VAR_STRING) {
1039  char buf[BUFSIZ];
1040 
1041  switch (var.type) {
1042  case TypedValue::VAR_BOOL:
1043  case TypedValue::VAR_INT:
1044  // TODO: use std::ostringstream?
1045  snprintf(buf, sizeof(buf), "%ld", (long)var.GetInt());
1046  Set(std::string(buf));
1047  break;
1048 
1049  case TypedValue::VAR_REAL:
1050  // TODO: use std::ostringstream?
1051  snprintf(buf, sizeof(buf), "%e", (double)var.GetReal());
1052  Set(std::string(buf));
1053  break;
1054 
1056  this->s = var.GetString();
1057  break;
1058 
1059  default:
1061  }
1062 
1063  } else {
1064  switch (type) {
1065  case TypedValue::VAR_BOOL:
1066  switch (var.type) {
1067  case TypedValue::VAR_BOOL:
1068  break;
1069 
1070  case TypedValue::VAR_INT:
1071  case TypedValue::VAR_REAL:
1072  if (bErr) {
1073  Real r = var.GetReal();
1074  if (r != 0. && r != 1.) {
1075  silent_cerr(" Error: implicit cast "
1076  "of " << var
1077  << " from " << GetTypeName(var.type)
1078  << " to " << GetTypeName(type)
1079  << " alters its value"
1080  << std::endl);
1082  }
1083  }
1084 
1085  silent_cerr("Warning: implicit cast "
1086  "from " << GetTypeName(var.type)
1087  << " to " << GetTypeName(type)
1088  << " may alter its value"
1089  << " at line " << mbdyn_get_line_data()
1090  << std::endl);
1091  break;
1092 
1093  default:
1094  throw ErrWrongType(MBDYN_EXCEPT_ARGS, type, var.type);
1095  }
1096  Set(var.GetBool());
1097  break;
1098 
1099  case TypedValue::VAR_INT:
1100  switch (var.type) {
1101  case TypedValue::VAR_BOOL:
1102  case TypedValue::VAR_INT:
1103  break;
1104 
1105  case TypedValue::VAR_REAL:
1106  if (bErr) {
1107  if (var.GetReal() != Real(var.GetInt())) {
1108  silent_cerr(" Error: implicit cast "
1109  "of " << var
1110  << " from " << GetTypeName(var.type)
1111  << " to " << GetTypeName(type)
1112  << " alters its value"
1113  << std::endl);
1115  }
1116  }
1117 
1118  silent_cerr("Warning: implicit cast "
1119  "from " << GetTypeName(var.type)
1120  << " to " << GetTypeName(type)
1121  << " may alter its value"
1122  << " at line " << mbdyn_get_line_data()
1123  << std::endl);
1124  break;
1125 
1126  default:
1127  throw ErrWrongType(MBDYN_EXCEPT_ARGS, type, var.type);
1128  }
1129  Set(var.GetInt());
1130  break;
1131 
1132  case TypedValue::VAR_REAL:
1133  switch (var.type) {
1134  case TypedValue::VAR_BOOL:
1135  case TypedValue::VAR_INT:
1136  case TypedValue::VAR_REAL:
1137  break;
1138 
1139  default:
1140  throw ErrWrongType(MBDYN_EXCEPT_ARGS, type, var.type);
1141  }
1142  Set(var.GetReal());
1143  break;
1144 
1145  default:
1147  }
1148  }
1149 
1150  bConst = var.Const();
1151  return *this;
1152 }
1153 
1156 {
1157  return type;
1158 }
1159 
1160 const char *const
1162 {
1163  switch (t) {
1164  case TypedValue::VAR_BOOL:
1165  case TypedValue::VAR_INT:
1166  case TypedValue::VAR_REAL:
1168  return TypeNames[t].name;
1169 
1170  default:
1172  }
1173 }
1174 
1175 const char *const
1177 {
1178  return GetTypeName(type);
1179 }
1180 
1181 bool
1183 {
1184  return bConst;
1185 }
1186 
1187 bool
1189 {
1190  switch (type) {
1191  case TypedValue::VAR_BOOL:
1192  return v.i;
1193 
1194  case TypedValue::VAR_INT:
1195  return v.i ? 1 : 0;
1196 
1197  case TypedValue::VAR_REAL:
1198  return v.r ? 1 : 0;
1199 
1202 
1203  default:
1205  }
1206 }
1207 
1208 Int
1210 {
1211  switch (type) {
1212  case TypedValue::VAR_BOOL:
1213  case TypedValue::VAR_INT:
1214  return v.i;
1215 
1216  case TypedValue::VAR_REAL:
1217  return Int(v.r);
1218 
1221 
1222  default:
1224  }
1225 }
1226 
1227 Real
1229 {
1230  switch (type) {
1231  case TypedValue::VAR_BOOL:
1232  case TypedValue::VAR_INT:
1233  return Real(v.i);
1234 
1235  case TypedValue::VAR_REAL:
1236  return v.r;
1237 
1240 
1241  default:
1243  }
1244 }
1245 
1246 const std::string &
1248 {
1249  switch (type) {
1250  case TypedValue::VAR_BOOL:
1251  case TypedValue::VAR_INT:
1252  case TypedValue::VAR_REAL:
1254 
1256  return s;
1257 
1258  default:
1260  }
1261 }
1262 
1263 void
1265 {
1266  if (Const()) {
1268  }
1269 
1270  type = t;
1271  bConst = isConst;
1272 }
1273 
1274 void
1275 TypedValue::SetConst(bool isConst, bool bForce)
1276 {
1277  if (Const() && !isConst && !bForce) {
1279  }
1280 
1281  bConst = isConst;
1282 }
1283 
1284 const TypedValue&
1285 TypedValue::Set(const bool& b)
1286 {
1287  if (Const()) {
1289  }
1290 
1291  switch (GetType()) {
1292  case TypedValue::VAR_BOOL:
1293  case TypedValue::VAR_INT:
1294  v.i = b ? 1 : 0;
1295  break;
1296 
1297  case TypedValue::VAR_REAL:
1298  v.r = b ? 1. : 0.;
1299  break;
1300 
1303 
1304  default:
1306  }
1307 
1308  return *this;
1309 }
1310 
1311 const TypedValue&
1312 TypedValue::Set(const Int& i)
1313 {
1314  if (Const()) {
1315  throw ErrConstraintViolation(MBDYN_EXCEPT_ARGS);
1316  }
1317 
1318  switch (GetType()) {
1319  case TypedValue::VAR_BOOL:
1320  v.i = i ? 1 : 0;
1321  break;
1322 
1323  case TypedValue::VAR_INT:
1324  v.i = i;
1325  break;
1326 
1327  case TypedValue::VAR_REAL:
1328  v.r = Real(i);
1329  break;
1330 
1332  throw ErrWrongType(MBDYN_EXCEPT_ARGS, GetType(), VAR_INT);
1333 
1334  default:
1335  throw ErrUnknownType(MBDYN_EXCEPT_ARGS);
1336  }
1337 
1338  return *this;
1339 }
1340 
1341 const TypedValue&
1343 {
1344  if (Const()) {
1346  }
1347 
1348  switch (GetType()) {
1349  case TypedValue::VAR_BOOL:
1350  v.i = r ? 1 : 0;
1351  break;
1352 
1353  case TypedValue::VAR_INT:
1354  v.i = Int(r);
1355  break;
1356 
1357  case TypedValue::VAR_REAL:
1358  v.r = r;
1359  break;
1360 
1363 
1364  default:
1366  }
1367 
1368  return *this;
1369 }
1370 
1371 const TypedValue&
1372 TypedValue::Set(const std::string& s)
1373 {
1374  if (Const()) {
1376  }
1377 
1378  switch (GetType()) {
1379  case TypedValue::VAR_BOOL:
1380  case TypedValue::VAR_INT:
1381  case TypedValue::VAR_REAL:
1383 
1385  this->s = s;
1386  break;
1387 
1388  default:
1390  }
1391 
1392  return *this;
1393 }
1394 
1395 bool
1397 {
1398  return (GetReal() && v.GetReal());
1399 }
1400 
1401 bool
1403 {
1404  return (GetReal() || v.GetReal());
1405 }
1406 
1407 bool
1409 {
1410  return (GetReal() > v.GetReal());
1411 }
1412 
1413 bool
1415 {
1416  return (GetReal() >= v.GetReal());
1417 }
1418 
1419 bool
1421 {
1422  return (GetReal() == v.GetReal());
1423 }
1424 
1425 bool
1427 {
1428  return (GetReal() <= v.GetReal());
1429 }
1430 
1431 bool
1433 {
1434  return (GetReal() < v.GetReal());
1435 }
1436 
1437 bool
1439 {
1440  return (GetReal() != v.GetReal());
1441 }
1442 
1443 TypedValue
1445 {
1446  if (GetType() == TypedValue::VAR_STRING) {
1447  char buf[BUFSIZ];
1448 
1449  switch (v.GetType()) {
1450  case TypedValue::VAR_BOOL:
1451  case TypedValue::VAR_INT:
1452  snprintf(buf, sizeof(buf), "%ld", (long)v.GetInt());
1453  return TypedValue(GetString() + buf);
1454 
1455  case TypedValue::VAR_REAL:
1456  snprintf(buf, sizeof(buf), "%e", (double)v.GetReal());
1457  return TypedValue(GetString() + buf);
1458 
1460  return TypedValue(GetString() + v.GetString());
1461 
1462  default:
1464  }
1465  }
1466 
1469  {
1470  // bool is implicitly cast to Int
1471  return TypedValue(GetInt() + v.GetInt());
1472  }
1473 
1474  return TypedValue(GetReal() + v.GetReal());
1475 }
1476 
1477 TypedValue
1479 {
1482  {
1483  // bool is implicitly cast to Int
1484  return TypedValue(GetInt() - v.GetInt());
1485  }
1486 
1487  return TypedValue(GetReal() - v.GetReal());
1488 }
1489 
1490 TypedValue
1492 {
1495  {
1496  // bool is implicitly cast to Int
1497  return TypedValue(GetInt()*v.GetInt());
1498  }
1499 
1500  return TypedValue(GetReal()*v.GetReal());
1501 }
1502 
1503 TypedValue
1505 {
1508  {
1509  // bool is implicitly cast to Int
1510  return TypedValue(GetInt()/v.GetInt());
1511  }
1512 
1513  return TypedValue(GetReal()/v.GetReal());
1514 }
1515 
1516 TypedValue
1518 {
1519  // bool is implicitly cast to Int
1521  {
1522  throw ErrWrongType(MBDYN_EXCEPT_ARGS, TypedValue::VAR_INT, v.GetType(), " in right argument");
1523  }
1524 
1526  {
1527  throw ErrWrongType(MBDYN_EXCEPT_ARGS, TypedValue::VAR_INT, GetType(), " in left argument");
1528  }
1529 
1530  return TypedValue(GetInt() % v.GetInt());
1531 }
1532 
1533 const TypedValue&
1535 {
1536  if (Const()) {
1538  }
1539 
1540  if (GetType() == TypedValue::VAR_STRING) {
1541  char buf[BUFSIZ];
1542 
1543  switch (v.GetType()) {
1544  case TypedValue::VAR_BOOL:
1545  case TypedValue::VAR_INT:
1546  snprintf(buf, sizeof(buf), "%ld", (long)v.GetInt());
1547  this->s += buf;
1548  break;
1549 
1550  case TypedValue::VAR_REAL:
1551  snprintf(buf, sizeof(buf), "%e", (double)v.GetReal());
1552  this->s += buf;
1553  break;
1554 
1556  this->s += v.GetString();
1557  break;
1558 
1559  default:
1561  }
1562 
1563  return *this;
1564  }
1565 
1568  {
1569  // bool is implicitly cast to Int
1570  return Set(GetInt() + v.GetInt());
1571  }
1572 
1573  Real d = GetReal() + v.GetReal();
1575 
1576  return Set(d);
1577 }
1578 
1579 const TypedValue&
1581 {
1582  if (Const()) {
1584  }
1585 
1588  {
1589  // bool is implicitly cast to Int
1590  return Set(GetInt() - v.GetInt());
1591  }
1592  Real d = GetReal() - v.GetReal();
1594  return Set(d);
1595 }
1596 
1597 const TypedValue&
1599 {
1600  if (Const()) {
1602  }
1603 
1606  {
1607  // bool is implicitly cast to Int
1608  return Set(GetInt()*v.GetInt());
1609  }
1610  Real d = GetReal()*v.GetReal();
1612  return Set(d);
1613 }
1614 
1615 const TypedValue&
1617 {
1618  if (Const()) {
1620  }
1621 
1624  {
1625  // bool is implicitly cast to Int
1626  return Set(GetInt()/v.GetInt());
1627  }
1628  Real d = GetReal()/v.GetReal();
1630  return Set(d);
1631 }
1632 
1633 const TypedValue&
1635 {
1636  if (Const()) {
1638  }
1639 
1640  // bool is implicitly cast to Int
1642  {
1643  throw ErrWrongType(MBDYN_EXCEPT_ARGS, TypedValue::VAR_INT, v.GetType(), " in right argument");
1644  }
1645 
1647  {
1648  throw ErrWrongType(MBDYN_EXCEPT_ARGS, TypedValue::VAR_INT, GetType(), " in left argument");
1649  }
1650 
1651  Int i = GetInt() % v.GetInt();
1653  return Set(i);
1654 }
1655 
1656 bool
1658 {
1659  if (v.GetType() == TypedValue::VAR_STRING) {
1660  return v.GetString().empty();
1661  }
1662 
1663  return (!v.GetReal());
1664 }
1665 
1666 TypedValue
1668 {
1669  switch (v.GetType()) {
1670  case TypedValue::VAR_BOOL:
1671  // bool is implicitly cast to Int
1672  case TypedValue::VAR_INT:
1673  return TypedValue(-v.GetInt());
1674 
1675  case TypedValue::VAR_REAL:
1676  return TypedValue(-v.GetReal());
1677 
1680 
1681  default:
1683  }
1684 
1685  return 0;
1686 }
1687 
1688 TypedValue
1690 {
1691  return v;
1692 }
1693 
1694 std::ostream&
1695 operator << (std::ostream& out, const TypedValue& v)
1696 {
1697  switch (v.GetType()) {
1698  case TypedValue::VAR_BOOL:
1699  case TypedValue::VAR_INT:
1700  return out << v.GetInt();
1701 
1702  case TypedValue::VAR_REAL: {
1703  // FIXME: precision?
1704  // make sure there is a (trailing) '.'
1705  std::ostringstream os;
1706  os << v.GetReal();
1707  if (os.str().find('.') == std::string::npos) {
1708  os << '.';
1709  }
1710  return out << os.str();
1711  }
1712 
1714  return out << '"' << v.GetString() << '"';
1715 
1716  default:
1718  }
1719 
1720  return out;
1721 }
1722 
1723 /* classe per la memorizzazione delle variabili */
1724 
1725 NamedValue::NamedValue(const char *const s)
1726 : name(NULL)
1727 {
1728  AllocName(s);
1729 }
1730 
1732 {
1733  ASSERT(name != NULL);
1735 }
1736 
1737 void
1738 NamedValue::AllocName(const char* const s)
1739 {
1740  ASSERT(s != NULL);
1741  SAFESTRDUP(name, s);
1742 }
1743 
1744 bool
1746 {
1747  return false;
1748 }
1749 
1750 const char*
1752 {
1753  ASSERT(name != NULL);
1754  return name;
1755 }
1756 
1757 const char *const
1759 {
1760  return TypedValue::GetTypeName(GetType());
1761 }
1762 
1763 Var::Var(const char* const s, const TypedValue& v)
1764 : NamedValue(s), value(v)
1765 {
1766  value.SetConst(v.Const(), true);
1767 }
1768 
1769 Var::Var(const char* const s, const bool& v)
1770 : NamedValue(s), value(v)
1771 {
1772  NO_OP;
1773 }
1774 
1775 Var::Var(const char* const s, const Int& v)
1776 : NamedValue(s), value(v)
1777 {
1778  NO_OP;
1779 }
1780 
1781 Var::Var(const char* const s, const Real& v)
1782 : NamedValue(s), value(v)
1783 {
1784  NO_OP;
1785 }
1786 
1787 Var::Var(const char* const s, const std::string& v)
1788 : NamedValue(s), value(v)
1789 {
1790  NO_OP;
1791 }
1792 
1794 {
1795  NO_OP;
1796 }
1797 
1798 bool
1799 Var::IsVar(void) const
1800 {
1801  return true;
1802 }
1803 
1805 Var::GetType(void) const
1806 {
1807  return value.GetType();
1808 }
1809 
1810 bool
1811 Var::Const(void) const
1812 {
1813  return value.Const();
1814 }
1815 
1816 bool
1817 Var::MayChange(void) const
1818 {
1819  return !value.Const();
1820 }
1821 
1822 TypedValue
1823 Var::GetVal(void) const
1824 {
1825  return value;
1826 }
1827 
1828 void
1829 Var::SetVal(const bool& v)
1830 {
1831  value.Set(v);
1832 }
1833 
1834 void
1835 Var::SetVal(const Int& v)
1836 {
1837  value.Set(v);
1838 }
1839 
1840 void
1842 {
1843  value.Set(v);
1844 }
1845 
1846 void
1847 Var::SetVal(const std::string& v)
1848 {
1849  value.Set(v);
1850 }
1851 
1852 void
1854 {
1855  value = v;
1856 }
1857 
1858 void
1859 Var::Cast(const TypedValue& v, bool bErr)
1860 {
1861  value.Cast(v, bErr);
1862 }
1863 
1864 void
1865 MathParser::trim_arg(char *const s)
1866 {
1867  int i, l;
1868 
1869  for (i = 0; isspace(s[i]); ++i) {
1870  NO_OP;
1871  }
1872 
1873  l = strlen(&s[i]);
1874  if (i > 0) {
1875  memmove(s, &s[i], l + 1);
1876  }
1877 
1878  for (i = l - 1; isspace(s[i]); --i) {
1879  NO_OP;
1880  }
1881  s[i + 1] = '\0';
1882 }
1883 
1885 : NamedValue(s), pgin(p)
1886 {
1887  NO_OP;
1888 }
1889 
1891 {
1892  if (pgin) {
1893  SAFEDELETE(pgin);
1894  }
1895 }
1896 
1899 {
1900  return pgin->GetType();
1901 }
1902 
1903 bool
1905 {
1906  return true;
1907 }
1908 
1909 bool
1911 {
1912  return true;
1913 }
1914 
1915 TypedValue
1917 {
1918  return pgin->GetVal();
1919 }
1920 
1923 
1926  silent_cerr(what() << " at line " << p->GetLineNumber() << std::endl);
1927 }
1928 
1929 /* gioca con table e stream di ingresso */
1930 Table&
1932 {
1933  return table;
1934 }
1935 
1936 void
1938 {
1939  table = T;
1940 }
1941 
1942 int
1944 {
1945  ASSERT(in != NULL);
1946  return in->GetLineNumber();
1947 }
1948 
1949 void
1951 {
1952  TokenVal tv;
1953  tv.m_t = t;
1954  if (t == NUM) {
1955  tv.m_v = value;
1956  } else if (t == NAME) {
1957  tv.m_v = TypedValue(namebuf);
1958  }
1959  TokenStack.push(tv);
1960 }
1961 
1962 int
1964 {
1965  if (TokenStack.empty()) {
1966  return 0;
1967  }
1968 
1969  TokenVal tv = TokenStack.top();
1970  TokenStack.pop();
1971 
1972  currtoken = tv.m_t;
1973  if (currtoken == NUM) {
1974  value = tv.m_v;
1975  } else if (currtoken == NAME) {
1976  // note: namebuf is expected to be large enough for value
1977  namebuf = tv.m_v.GetString();
1978  }
1979 
1980  return 1;
1981 }
1982 
1985 {
1986  return nameSpaceMap;
1987 }
1988 
1989 MathParser::NameSpace::NameSpace(const std::string& name)
1990 : name(name)
1991 {
1992  NO_OP;
1993 }
1994 
1996 {
1997  NO_OP;
1998 }
1999 
2000 const std::string&
2002 {
2003  return name;
2004 }
2005 
2006 static bool sns = 0;
2007 
2009 : MathParser::NameSpace("default"), m_pTable(pTable)
2010 {
2011  // make sure there's only one StaticNameSpace
2012  if (sns) {
2013  // error
2015  }
2016  sns = true;
2017 
2018  MathFunc_t *f;
2019 
2020  // asin
2021  f = new MathFunc_t;
2022  f->fname = std::string("asin");
2023  f->ns = this;
2024  f->args.resize(1 + 1);
2025  f->args[0] = new MathArgReal_t;
2026  f->args[1] = new MathArgReal_t;
2027  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, asin>;
2028  f->t = mp_asin_t;
2029  f->errmsg = std::string("invalid arg to asin()");
2030 
2031  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2032  silent_cerr("static namespace: "
2033  "unable to insert handler "
2034  "for function " << f->fname << std::endl);
2036  }
2037 
2038  // acos
2039  f = new MathFunc_t;
2040  f->fname = std::string("acos");
2041  f->ns = this;
2042  f->args.resize(1 + 1);
2043  f->args[0] = new MathArgReal_t;
2044  f->args[1] = new MathArgReal_t;
2045  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, acos>;
2046  f->t = mp_acos_t;
2047  f->errmsg = std::string("invalid arg to acos()");
2048 
2049  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2050  silent_cerr("static namespace: "
2051  "unable to insert handler "
2052  "for function " << f->fname << std::endl);
2054  }
2055 
2056  // atan
2057  f = new MathFunc_t;
2058  f->fname = std::string("atan");
2059  f->ns = this;
2060  f->args.resize(1 + 1);
2061  f->args[0] = new MathArgReal_t;
2062  f->args[1] = new MathArgReal_t;
2063  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, atan>;
2064  f->t = 0;
2065 
2066  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2067  silent_cerr("static namespace: "
2068  "unable to insert handler "
2069  "for function " << f->fname << std::endl);
2071  }
2072 
2073  // actan
2074  f = new MathFunc_t;
2075  f->fname = std::string("actan");
2076  f->ns = this;
2077  f->args.resize(1 + 1);
2078  f->args[0] = new MathArgReal_t;
2079  f->args[1] = new MathArgReal_t;
2080  f->f = mp_actg;
2081  f->t = 0;
2082 
2083  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2084  silent_cerr("static namespace: "
2085  "unable to insert handler "
2086  "for function " << f->fname << std::endl);
2088  }
2089 
2090  // atan2
2091  f = new MathFunc_t;
2092  f->fname = std::string("atan2");
2093  f->ns = this;
2094  f->args.resize(1 + 2);
2095  f->args[0] = new MathArgReal_t;
2096  f->args[1] = new MathArgReal_t;
2097  f->args[2] = new MathArgReal_t;
2098  f->f = mp_func_2<MathParser::MathArgReal_t, MathParser::MathArgReal_t, atan2>;
2099  f->t = 0;
2100 
2101  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2102  silent_cerr("static namespace: "
2103  "unable to insert handler "
2104  "for function " << f->fname << std::endl);
2106  }
2107 
2108  // actan2
2109  f = new MathFunc_t;
2110  f->fname = std::string("actan2");
2111  f->ns = this;
2112  f->args.resize(1 + 2);
2113  f->args[0] = new MathArgReal_t;
2114  f->args[1] = new MathArgReal_t;
2115  f->args[2] = new MathArgReal_t;
2116  f->f = mp_actg2;
2117  f->t = 0;
2118 
2119  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2120  silent_cerr("static namespace: "
2121  "unable to insert handler "
2122  "for function " << f->fname << std::endl);
2124  }
2125 
2126  // cos
2127  f = new MathFunc_t;
2128  f->fname = std::string("cos");
2129  f->ns = this;
2130  f->args.resize(1 + 1);
2131  f->args[0] = new MathArgReal_t;
2132  f->args[1] = new MathArgReal_t;
2133  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, cos>;
2134  f->t = 0;
2135 
2136  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2137  silent_cerr("static namespace: "
2138  "unable to insert handler "
2139  "for function " << f->fname << std::endl);
2141  }
2142 
2143  // sin
2144  f = new MathFunc_t;
2145  f->fname = std::string("sin");
2146  f->ns = this;
2147  f->args.resize(1 + 1);
2148  f->args[0] = new MathArgReal_t;
2149  f->args[1] = new MathArgReal_t;
2150  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, sin>;
2151  f->t = 0;
2152 
2153  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2154  silent_cerr("static namespace: "
2155  "unable to insert handler "
2156  "for function " << f->fname << std::endl);
2158  }
2159 
2160  // tan
2161  f = new MathFunc_t;
2162  f->fname = std::string("tan");
2163  f->ns = this;
2164  f->args.resize(1 + 1);
2165  f->args[0] = new MathArgReal_t;
2166  f->args[1] = new MathArgReal_t;
2167  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, tan>;
2168  f->t = mp_tan_t;
2169 
2170  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2171  silent_cerr("static namespace: "
2172  "unable to insert handler "
2173  "for function " << f->fname << std::endl);
2175  }
2176 
2177  // ctan
2178  f = new MathFunc_t;
2179  f->fname = std::string("ctan");
2180  f->ns = this;
2181  f->args.resize(1 + 1);
2182  f->args[0] = new MathArgReal_t;
2183  f->args[1] = new MathArgReal_t;
2184  f->f = mp_ctg;
2185  f->t = mp_ctg_t;
2186 
2187  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2188  silent_cerr("static namespace: "
2189  "unable to insert handler "
2190  "for function " << f->fname << std::endl);
2192  }
2193 
2194  // cosh
2195  f = new MathFunc_t;
2196  f->fname = std::string("cosh");
2197  f->ns = this;
2198  f->args.resize(1 + 1);
2199  f->args[0] = new MathArgReal_t;
2200  f->args[1] = new MathArgReal_t;
2201  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, cosh>;
2202  f->t = 0;
2203 
2204  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2205  silent_cerr("static namespace: "
2206  "unable to insert handler "
2207  "for function " << f->fname << std::endl);
2209  }
2210 
2211  // sinh
2212  f = new MathFunc_t;
2213  f->fname = std::string("sinh");
2214  f->ns = this;
2215  f->args.resize(1 + 1);
2216  f->args[0] = new MathArgReal_t;
2217  f->args[1] = new MathArgReal_t;
2218  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, sinh>;
2219  f->t = 0;
2220 
2221  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2222  silent_cerr("static namespace: "
2223  "unable to insert handler "
2224  "for function " << f->fname << std::endl);
2226  }
2227 
2228  // tanh
2229  f = new MathFunc_t;
2230  f->fname = std::string("tanh");
2231  f->ns = this;
2232  f->args.resize(1 + 1);
2233  f->args[0] = new MathArgReal_t;
2234  f->args[1] = new MathArgReal_t;
2235  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, tanh>;
2236  f->t = 0;
2237 
2238  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2239  silent_cerr("static namespace: "
2240  "unable to insert handler "
2241  "for function " << f->fname << std::endl);
2243  }
2244 
2245  // ctanh
2246  f = new MathFunc_t;
2247  f->fname = std::string("ctanh");
2248  f->ns = this;
2249  f->args.resize(1 + 1);
2250  f->args[0] = new MathArgReal_t;
2251  f->args[1] = new MathArgReal_t;
2252  f->f = mp_ctgh;
2253  f->t = mp_ctgh_t;
2254 
2255  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2256  silent_cerr("static namespace: "
2257  "unable to insert handler "
2258  "for function " << f->fname << std::endl);
2260  }
2261 
2262 #ifdef __USE_XOPEN
2263  // acosh
2264  f = new MathFunc_t;
2265  f->fname = std::string("acosh");
2266  f->ns = this;
2267  f->args.resize(1 + 1);
2268  f->args[0] = new MathArgReal_t;
2269  f->args[1] = new MathArgReal_t;
2270  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, acosh>;
2271  f->t = mp_acosh_t;
2272 
2273  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2274  silent_cerr("static namespace: "
2275  "unable to insert handler "
2276  "for function " << f->fname << std::endl);
2278  }
2279 
2280  // asinh
2281  f = new MathFunc_t;
2282  f->fname = std::string("asinh");
2283  f->ns = this;
2284  f->args.resize(1 + 1);
2285  f->args[0] = new MathArgReal_t;
2286  f->args[1] = new MathArgReal_t;
2287  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, asinh>;
2288  f->t = 0;
2289 
2290  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2291  silent_cerr("static namespace: "
2292  "unable to insert handler "
2293  "for function " << f->fname << std::endl);
2295  }
2296 
2297  // atanh
2298  f = new MathFunc_t;
2299  f->fname = std::string("atanh");
2300  f->ns = this;
2301  f->args.resize(1 + 1);
2302  f->args[0] = new MathArgReal_t;
2303  f->args[1] = new MathArgReal_t;
2304  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, atanh>;
2305  f->t = mp_atanh_t;
2306 
2307  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2308  silent_cerr("static namespace: "
2309  "unable to insert handler "
2310  "for function " << f->fname << std::endl);
2312  }
2313 
2314  // actanh
2315  f = new MathFunc_t;
2316  f->fname = std::string("actanh");
2317  f->ns = this;
2318  f->args.resize(1 + 1);
2319  f->args[0] = new MathArgReal_t;
2320  f->args[1] = new MathArgReal_t;
2321  f->f = mp_actgh;
2322  f->t = 0;
2323 
2324  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2325  silent_cerr("static namespace: "
2326  "unable to insert handler "
2327  "for function " << f->fname << std::endl);
2329  }
2330 #endif /* __USE_XOPEN */
2331 
2332  // exp
2333  f = new MathFunc_t;
2334  f->fname = std::string("exp");
2335  f->ns = this;
2336  f->args.resize(1 + 1);
2337  f->args[0] = new MathArgReal_t;
2338  f->args[1] = new MathArgReal_t;
2339  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, exp>;
2340  f->t = 0;
2341 
2342  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2343  silent_cerr("static namespace: "
2344  "unable to insert handler "
2345  "for function " << f->fname << std::endl);
2347  }
2348 
2349  // log
2350  f = new MathFunc_t;
2351  f->fname = std::string("log");
2352  f->ns = this;
2353  f->args.resize(1 + 1);
2354  f->args[0] = new MathArgReal_t;
2355  f->args[1] = new MathArgReal_t;
2356  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, log>;
2357  f->t = mp_greater_than_0_t;
2358 
2359  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2360  silent_cerr("static namespace: "
2361  "unable to insert handler "
2362  "for function " << f->fname << std::endl);
2364  }
2365 
2366  // log10
2367  f = new MathFunc_t;
2368  f->fname = std::string("log10");
2369  f->ns = this;
2370  f->args.resize(1 + 1);
2371  f->args[0] = new MathArgReal_t;
2372  f->args[1] = new MathArgReal_t;
2373  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, log10>;
2374  f->t = mp_greater_than_0_t;
2375 
2376  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2377  silent_cerr("static namespace: "
2378  "unable to insert handler "
2379  "for function " << f->fname << std::endl);
2381  }
2382 
2383  // sqrt
2384  f = new MathFunc_t;
2385  f->fname = std::string("sqrt");
2386  f->ns = this;
2387  f->args.resize(1 + 1);
2388  f->args[0] = new MathArgReal_t;
2389  f->args[1] = new MathArgReal_t;
2390  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, sqrt>;
2392 
2393  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2394  silent_cerr("static namespace: "
2395  "unable to insert handler "
2396  "for function " << f->fname << std::endl);
2398  }
2399 
2400  // abs
2401  f = new MathFunc_t;
2402  f->fname = std::string("abs");
2403  f->ns = this;
2404  f->args.resize(1 + 1);
2405  f->args[0] = new MathArgReal_t;
2406  f->args[1] = new MathArgReal_t;
2407  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, fabs>;
2408  f->t = 0;
2409 
2410  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2411  silent_cerr("static namespace: "
2412  "unable to insert handler "
2413  "for function " << f->fname << std::endl);
2415  }
2416 
2417  // sign
2418  f = new MathFunc_t;
2419  f->fname = std::string("sign");
2420  f->ns = this;
2421  f->args.resize(1 + 1);
2422  f->args[0] = new MathArgInt_t;
2423  f->args[1] = new MathArgReal_t;
2424  f->f = mp_sign;
2425  f->t = 0;
2426 
2427  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2428  silent_cerr("static namespace: "
2429  "unable to insert handler "
2430  "for function " << f->fname << std::endl);
2432  }
2433 
2434  // copysign
2435  f = new MathFunc_t;
2436  f->fname = std::string("copysign");
2437  f->ns = this;
2438  f->args.resize(1 + 2);
2439  f->args[0] = new MathArgReal_t;
2440  f->args[1] = new MathArgReal_t;
2441  f->args[2] = new MathArgReal_t;
2442  f->f = mp_func_2<MathParser::MathArgReal_t, MathParser::MathArgReal_t, copysign>;
2443  f->t = 0;
2444 
2445  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2446  silent_cerr("static namespace: "
2447  "unable to insert handler "
2448  "for function " << f->fname << std::endl);
2450  }
2451 
2452  // max
2453  f = new MathFunc_t;
2454  f->fname = std::string("max");
2455  f->ns = this;
2456  f->args.resize(1 + 2);
2457  f->args[0] = new MathArgReal_t;
2458  f->args[1] = new MathArgReal_t;
2459  f->args[2] = new MathArgReal_t;
2460  f->f = mp_max;
2461  f->t = 0;
2462 
2463  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2464  silent_cerr("static namespace: "
2465  "unable to insert handler "
2466  "for function " << f->fname << std::endl);
2468  }
2469 
2470  // min
2471  f = new MathFunc_t;
2472  f->fname = std::string("min");
2473  f->ns = this;
2474  f->args.resize(1 + 2);
2475  f->args[0] = new MathArgReal_t;
2476  f->args[1] = new MathArgReal_t;
2477  f->args[2] = new MathArgReal_t;
2478  f->f = mp_min;
2479  f->t = 0;
2480 
2481  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2482  silent_cerr("static namespace: "
2483  "unable to insert handler "
2484  "for function " << f->fname << std::endl);
2486  }
2487 
2488  // floor
2489  f = new MathFunc_t;
2490  f->fname = std::string("floor");
2491  f->ns = this;
2492  f->args.resize(1 + 1);
2493  f->args[0] = new MathArgReal_t;
2494  f->args[1] = new MathArgReal_t;
2495  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, floor>;
2496  f->t = 0;
2497 
2498  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2499  silent_cerr("static namespace: "
2500  "unable to insert handler "
2501  "for function " << f->fname << std::endl);
2503  }
2504 
2505  // ceil
2506  f = new MathFunc_t;
2507  f->fname = std::string("ceil");
2508  f->ns = this;
2509  f->args.resize(1 + 1);
2510  f->args[0] = new MathArgReal_t;
2511  f->args[1] = new MathArgReal_t;
2512  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, ceil>;
2513  f->t = 0;
2514 
2515  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2516  silent_cerr("static namespace: "
2517  "unable to insert handler "
2518  "for function " << f->fname << std::endl);
2520  }
2521 
2522 #ifdef __USE_XOPEN
2523  // round
2524  f = new MathFunc_t;
2525  f->fname = std::string("round");
2526  f->ns = this;
2527  f->args.resize(1 + 1);
2528  f->args[0] = new MathArgReal_t;
2529  f->args[1] = new MathArgReal_t;
2530  f->f = mp_func_1<MathParser::MathArgReal_t, MathParser::MathArgReal_t, rint>;
2531  f->t = 0;
2532 
2533  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2534  silent_cerr("static namespace: "
2535  "unable to insert handler "
2536  "for function " << f->fname << std::endl);
2538  }
2539 #endif /* __USE_XOPEN */
2540 
2541  // rand
2542  f = new MathFunc_t;
2543  f->fname = std::string("rand");
2544  f->ns = this;
2545  f->args.resize(1 + 0);
2546  f->args[0] = new MathArgInt_t;
2547  f->f = mp_rand;
2548  f->t = 0;
2549 
2550  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2551  silent_cerr("static namespace: "
2552  "unable to insert handler "
2553  "for function " << f->fname << std::endl);
2555  }
2556 
2557  // random
2558  f = new MathFunc_t;
2559  f->fname = std::string("random");
2560  f->ns = this;
2561  f->args.resize(1 + 0);
2562  f->args[0] = new MathArgReal_t;
2563  f->f = mp_rndm;
2564  f->t = 0;
2565 
2566  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2567  silent_cerr("static namespace: "
2568  "unable to insert handler "
2569  "for function " << f->fname << std::endl);
2571  }
2572 
2573  // seed
2574  f = new MathFunc_t;
2575  f->fname = std::string("seed");
2576  f->ns = this;
2577  f->args.resize(1 + 1);
2578  f->args[0] = new MathArgVoid_t;
2579  f->args[1] = new MathArgInt_t;
2580  f->f = mp_srnd;
2581  f->t = 0;
2582 
2583  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2584  silent_cerr("static namespace: "
2585  "unable to insert handler "
2586  "for function " << f->fname << std::endl);
2588  }
2589 
2590  // step
2591  f = new MathFunc_t;
2592  f->fname = std::string("step");
2593  f->ns = this;
2594  f->args.resize(1 + 1);
2595  f->args[0] = new MathArgReal_t;
2596  f->args[1] = new MathArgReal_t;
2597  f->f = mp_step;
2598  f->t = 0;
2599 
2600  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2601  silent_cerr("static namespace: "
2602  "unable to insert handler "
2603  "for function " << f->fname << std::endl);
2605  }
2606 
2607  // ramp
2608  f = new MathFunc_t;
2609  f->fname = std::string("ramp");
2610  f->ns = this;
2611  f->args.resize(1 + 1);
2612  f->args[0] = new MathArgReal_t;
2613  f->args[1] = new MathArgReal_t;
2614  f->f = mp_ramp;
2615  f->t = 0;
2616 
2617  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2618  silent_cerr("static namespace: "
2619  "unable to insert handler "
2620  "for function " << f->fname << std::endl);
2622  }
2623 
2624  // sramp
2625  f = new MathFunc_t;
2626  f->fname = std::string("sramp");
2627  f->ns = this;
2628  f->args.resize(1 + 2);
2629  f->args[0] = new MathArgReal_t;
2630  f->args[1] = new MathArgReal_t;
2631  f->args[2] = new MathArgReal_t;
2632  f->f = mp_sramp;
2633  f->t = 0;
2634 
2635  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2636  silent_cerr("static namespace: "
2637  "unable to insert handler "
2638  "for function " << f->fname << std::endl);
2640  }
2641 
2642  // par
2643  f = new MathFunc_t;
2644  f->fname = std::string("par");
2645  f->ns = this;
2646  f->args.resize(1 + 1);
2647  f->args[0] = new MathArgReal_t;
2648  f->args[1] = new MathArgReal_t;
2649  f->f = mp_par;
2650  f->t = 0;
2651 
2652  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2653  silent_cerr("static namespace: "
2654  "unable to insert handler "
2655  "for function " << f->fname << std::endl);
2657  }
2658 
2659  // in
2660  f = new MathFunc_t;
2661  f->fname = std::string("in_ll");
2662  f->ns = this;
2663  f->args.resize(1 + 3);
2664  f->args[0] = new MathArgReal_t;
2665  f->args[1] = new MathArgReal_t;
2666  f->args[2] = new MathArgReal_t;
2667  f->args[3] = new MathArgReal_t;
2668  f->f = mp_in<IN_LL>;
2669  f->t = 0;
2670 
2671  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2672  silent_cerr("static namespace: "
2673  "unable to insert handler "
2674  "for function " << f->fname << std::endl);
2676  }
2677 
2678  f = new MathFunc_t;
2679  f->fname = std::string("in_le");
2680  f->ns = this;
2681  f->args.resize(1 + 3);
2682  f->args[0] = new MathArgReal_t;
2683  f->args[1] = new MathArgReal_t;
2684  f->args[2] = new MathArgReal_t;
2685  f->args[3] = new MathArgReal_t;
2686  f->f = mp_in<IN_LE>;
2687  f->t = 0;
2688 
2689  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2690  silent_cerr("static namespace: "
2691  "unable to insert handler "
2692  "for function " << f->fname << std::endl);
2694  }
2695 
2696  f = new MathFunc_t;
2697  f->fname = std::string("in_el");
2698  f->ns = this;
2699  f->args.resize(1 + 3);
2700  f->args[0] = new MathArgReal_t;
2701  f->args[1] = new MathArgReal_t;
2702  f->args[2] = new MathArgReal_t;
2703  f->args[3] = new MathArgReal_t;
2704  f->f = mp_in<IN_EL>;
2705  f->t = 0;
2706 
2707  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2708  silent_cerr("static namespace: "
2709  "unable to insert handler "
2710  "for function " << f->fname << std::endl);
2712  }
2713 
2714  f = new MathFunc_t;
2715  f->fname = std::string("in_ee");
2716  f->ns = this;
2717  f->args.resize(1 + 3);
2718  f->args[0] = new MathArgReal_t;
2719  f->args[1] = new MathArgReal_t;
2720  f->args[2] = new MathArgReal_t;
2721  f->args[3] = new MathArgReal_t;
2722  f->f = mp_in<IN_EE>;
2723  f->t = 0;
2724 
2725  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2726  silent_cerr("static namespace: "
2727  "unable to insert handler "
2728  "for function " << f->fname << std::endl);
2730  }
2731 
2732  // print
2733  f = new MathFunc_t;
2734  f->fname = std::string("print");
2735  f->ns = this;
2736  f->args.resize(1 + 1);
2737  f->args[0] = new MathArgVoid_t;
2738  f->args[1] = new MathArgReal_t;
2739  f->f = mp_print;
2740  f->t = 0;
2741 
2742  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2743  silent_cerr("static namespace: "
2744  "unable to insert handler "
2745  "for function " << f->fname << std::endl);
2747  }
2748 
2749  // sprintf
2750  f = new MathFunc_t;
2751  f->fname = std::string("sprintf");
2752  f->ns = this;
2753  f->args.resize(1 + 2);
2754  f->args[0] = new MathArgString_t;
2755  f->args[1] = new MathArgString_t;
2756  f->args[2] = new MathArgAny_t;
2757  f->f = mp_sprintf;
2758  f->t = 0;
2759 
2760  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2761  silent_cerr("static namespace: "
2762  "unable to insert handler "
2763  "for function " << f->fname << std::endl);
2765  }
2766 
2767  // stop
2768  f = new MathFunc_t;
2769  f->fname = std::string("stop");
2770  f->ns = this;
2771  f->args.resize(1 + 2);
2772  f->args[0] = new MathArgVoid_t;
2773  f->args[1] = new MathArgInt_t;
2774  f->args[2] = new MathArgInt_t;
2775  f->f = mp_stop;
2776  f->t = 0;
2777 
2778  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2779  silent_cerr("static namespace: "
2780  "unable to insert handler "
2781  "for function " << f->fname << std::endl);
2783  }
2784 
2785  // cast
2786  {
2787  struct {
2788  TypedValue::Type type;
2789  MathArg_t *arg;
2790  } data[5] = {
2792  { TypedValue::VAR_INT },
2796  };
2797 
2798  data[0].arg = new MathArgBool_t;
2799  data[1].arg = new MathArgInt_t;
2800  data[2].arg = new MathArgReal_t;
2801  data[3].arg = new MathArgString_t;
2802 
2803  for (int i = 0; data[i].type != TypedValue::VAR_UNKNOWN; i++) {
2804  f = new MathFunc_t;
2805  f->fname = std::string(TypedValue::GetTypeName(data[i].type));
2806  f->ns = this;
2807  f->args.resize(1 + 1);
2808  f->args[0] = data[i].arg;
2809  f->args[1] = new MathArgAny_t;
2810  f->f = mp_cast;
2811  f->t = 0;
2812 
2813  if (!func.insert(funcType::value_type(f->fname, f)).second) {
2814  silent_cerr("static namespace: "
2815  "unable to insert handler "
2816  "for function " << f->fname << std::endl);
2818  }
2819  }
2820  }
2821 }
2822 
2824 {
2825  for (funcType::iterator f = func.begin(); f != func.end(); ++f) {
2826  delete f->second;
2827  }
2828 }
2829 
2830 bool
2831 MathParser::StaticNameSpace::IsFunc(const std::string& fname) const
2832 {
2833 #if 0
2834  for (funcType::const_iterator f = func.begin(); f != func.end(); ++f) {
2835  silent_cerr("*** " << f->second->fname << std::endl);
2836  }
2837 #endif
2838 
2839  if (func.find(fname) != func.end()) {
2840  return true;
2841  }
2842 
2843  return false;
2844 }
2845 
2847 MathParser::StaticNameSpace::GetFunc(const std::string& fname) const
2848 {
2849  funcType::const_iterator i = func.find(fname);
2850 
2851  if (i != func.end()) {
2852  return new MathParser::MathFunc_t(*i->second);
2853  }
2854 
2855  return 0;
2856 }
2857 
2858 TypedValue
2860 {
2861  f->f(f->args);
2862 
2863  switch (f->args[0]->Type()) {
2864  case MathParser::AT_VOID:
2865  return TypedValue(0);
2866 
2867  case MathParser::AT_BOOL:
2868  return TypedValue((*dynamic_cast<MathArgBool_t*>(f->args[0]))());
2869 
2870  case MathParser::AT_INT:
2871  return TypedValue((*dynamic_cast<MathArgInt_t*>(f->args[0]))());
2872 
2873  case MathParser::AT_REAL:
2874  return TypedValue((*dynamic_cast<MathArgReal_t*>(f->args[0]))());
2875 
2876  case MathParser::AT_STRING:
2877  return TypedValue((*dynamic_cast<MathArgString_t*>(f->args[0]))());
2878 
2879  default:
2881  }
2882 }
2883 
2884 Table*
2886 {
2887  return m_pTable;
2888 }
2889 
2891 MathParser::GetType(const char* const s) const
2892 {
2893  for (Int i = 0; TypeNames[i].name != NULL; i++) {
2894  if (strcmp(s, TypeNames[i].name) == 0) {
2895  return TypeNames[i].type;
2896  }
2897  }
2898 
2899  return TypedValue::VAR_UNKNOWN;
2900 }
2901 
2903 MathParser::GetTypeModifier(const char* const s) const
2904 {
2905  for (Int i = 0; TypeModifierNames[i].name != NULL; i++) {
2906  if (strcmp(s, TypeModifierNames[i].name) == 0) {
2907  return TypeModifierNames[i].type;
2908  }
2909  }
2910 
2911  return TypedValue::MOD_UNKNOWN;
2912 }
2913 
2915 MathParser::GetDeclarationModifier(const char* const s) const
2916 {
2917  for (Int i = 0; DeclarationModifierNames[i].name != NULL; i++) {
2918  if (strcmp(s, DeclarationModifierNames[i].name) == 0) {
2919  return DeclarationModifierNames[i].type;
2920  }
2921  }
2922 
2923  return DMOD_UNKNOWN;
2924 }
2925 
2926 bool
2927 MathParser::IsType(const char* const s) const
2928 {
2929  return GetType(s) != TypedValue::VAR_UNKNOWN;
2930 }
2931 
2932 bool
2933 MathParser::IsTypeModifier(const char* const s) const
2934 {
2936 }
2937 
2938 bool
2939 MathParser::IsDeclarationModifier(const char* const s) const
2940 {
2941  return GetDeclarationModifier(s) != DMOD_UNKNOWN;
2942 }
2943 
2944 bool
2945 MathParser::IsKeyWord(MathParser::NameSpace *ns, const char* const s) const
2946 {
2947  if (IsTypeModifier(s)) {
2948  return true;
2949  }
2950  if (IsType(s)) {
2951  return true;
2952  }
2953  if (ns->IsFunc(s)) {
2954  return true;
2955  }
2956  return false;
2957 }
2958 
2961 {
2962  ASSERT(in != NULL);
2963 
2964  if (TokenPop()) {
2965  /* se lo trova! */
2966  return currtoken;
2967  }
2968 
2969  int c = 0;
2970 
2971 start_parsing:;
2972  /* skip spaces */
2973  while ((c = in->get()), isspace(c)) {
2974  NO_OP;
2975  };
2976 
2977  if (c == EOF || in->eof()) {
2978  return (currtoken = ENDOFFILE);
2979  }
2980 
2981  if (c == ONE_LINE_REMARK) {
2982  for (c = in->get(); c != '\n'; c = in->get()) {
2983  /* a trailing '\' continues the one-line remark
2984  * on the following line
2985  * FIXME: are we sure we want this? */
2986  if (c == '\\') {
2987  c = in->get();
2988  if (c == '\r') {
2989  c = in->get();
2990  }
2991  }
2992  }
2993  goto start_parsing;
2994  }
2995 
2996  /* number? */
2997  if (c == '.' || isdigit(c)) {
2998  // lot of space...
2999  char s[BUFSIZ];
3000  bool f = false;
3001  unsigned i = 0;
3002 
3003  // FIXME: need to check for overflow
3004 
3005  s[i++] = char(c);
3006 
3007  if (c == '.') {
3008  f = true;
3009  }
3010  while ((c = in->get()) == '.' || isdigit(c)) {
3011  s[i++] = char(c);
3012  if (c == '.') {
3013  if (f) {
3014  return (currtoken = UNKNOWNTOKEN);
3015  }
3016  f = true;
3017  }
3018  if (i >= sizeof(s)) {
3019  // buffer about to overflow
3020  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "value too long");
3021  }
3022  }
3023  if (std::strchr("efdgEFDG", c) != 0) {
3024  f = true;
3025  // use 'e' because strtod only understands 'e' or 'E'
3026  s[i++] = 'e';
3027  if (i >= sizeof(s)) {
3028  // buffer about to overflow
3029  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "value too long");
3030  }
3031  if ((c = in->get()) == '-' || c == '+') {
3032  s[i++] = char(c);
3033  if (i >= sizeof(s)) {
3034  // buffer about to overflow
3035  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "value too long");
3036  }
3037  c = in->get();
3038  }
3039  if (isdigit(c)) {
3040  s[i++] = char(c);
3041  if (i >= sizeof(s)) {
3042  // buffer about to overflow
3043  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "value too long");
3044  }
3045 
3046  } else {
3047  return (currtoken = UNKNOWNTOKEN);
3048  }
3049  while (isdigit((c = in->get()))) {
3050  s[i++] = char(c);
3051  if (i >= sizeof(s)) {
3052  // buffer about to overflow
3053  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "value too long");
3054  }
3055  }
3056  }
3057  s[i] = '\0';
3058  if (in->eof()) {
3059  // force EOF because on some archs (e.g. arm) char is unsigned,
3060  // thus putback won't restore EOF
3061  in->putback(char(c));
3062  in->GetStream().setstate(std::ios::eofbit);
3063  } else {
3064  in->putback(char(c));
3065  }
3066  char *endptr = 0;
3067  if (!f) {
3069 #ifdef HAVE_STRTOL
3070  errno = 0;
3071  long l = strtol(s, &endptr, 10);
3072  int save_errno = errno;
3073  if (endptr == s || endptr[0] != '\0') {
3074  silent_cerr(" MathParser - unable to parse \"" << s << "\" as integer"
3075  << " at line " << GetLineNumber() << std::endl);
3076  return (currtoken = UNKNOWNTOKEN);
3077  }
3078 
3079  if (save_errno == ERANGE) {
3080  // over/under-flow
3081  if (l == LONG_MIN) {
3082  throw ErrGeneric(this,
3084  std::string("integer value ") + std::string(s, endptr - s) + " underflow");
3085  }
3086 
3087  if (l == LONG_MAX) {
3088  throw ErrGeneric(this,
3090  std::string("integer value ") + std::string(s, endptr - s) + " overflow");
3091  }
3092 
3094  }
3095  value.Set(Int(l));
3096 #else /* !HAVE_STRTOL */
3097  value.Set(Int(atoi(s)));
3098 #endif /* !HAVE_STRTOL */
3099 
3100  } else {
3102 #ifdef HAVE_STRTOD
3103  errno = 0;
3104  double d = strtod(s, &endptr);
3105  int save_errno = errno;
3106  if (endptr == s || endptr[0] != '\0') {
3107  silent_cerr(" MathParser - unable to parse \"" << s << "\" as real"
3108  << " at line " << GetLineNumber() << std::endl);
3109  return (currtoken = UNKNOWNTOKEN);
3110  }
3111 
3112  if (save_errno == ERANGE) {
3113  // over/under-flow
3114  if (std::abs(d) == HUGE_VAL) {
3115  throw ErrGeneric(this,
3117  std::string("real value ") + std::string(s, endptr - s) + " overflow");
3118  }
3119 
3120  if (d == 0.) {
3121  throw ErrGeneric(this,
3123  std::string("real value ") + std::string(s, endptr - s) + " underflow");
3124  }
3125 
3127  }
3128  value.Set(Real(d));
3129 #else /* !HAVE_STRTOD */
3130  value.Set(Real(atof(s)));
3131 #endif /* !HAVE_STRTOD */
3132  }
3133 
3134  return (currtoken = NUM);
3135  }
3136 
3137  /* name? */
3138  if (isalpha(c) || c == '_') {
3139  namebuf.clear();
3140  namebuf.push_back(char(c));
3141  while ((c = in->get())) {
3142  if (!(c == '_'
3143  || isalnum(c)
3144  || ((currtoken == NAMESPACESEP) && c == ':')))
3145  {
3146  break;
3147  }
3148 
3149  namebuf.push_back(char(c));
3150  }
3151  in->putback(char(c));
3152  return (currtoken = NAME);
3153  }
3154 
3155  switch (c) {
3156  case '^':
3157  return (currtoken = EXP);
3158 
3159  case '*':
3160  return (currtoken = MULT);
3161 
3162  case '/':
3163  if ((c = in->get()) == '*') {
3164  for (c = in->get();; c = in->get()) {
3165  if (c == '*') {
3166 end_of_comment:;
3167  c = in->get();
3168  if (c == '/') {
3169  goto start_parsing;
3170  }
3171  } else if (c == '/') {
3172  c = in->get();
3173  if (c == '*') {
3174  silent_cerr("warning: '/*' "
3175  "inside a comment at line "
3176  << GetLineNumber()
3177  << std::endl);
3178  goto end_of_comment;
3179  }
3180  }
3181  }
3182 
3183  } else {
3184  in->putback(char(c));
3185  return (currtoken = DIV);
3186  }
3187 
3188  case '%':
3189  return (currtoken = MOD);
3190 
3191  case '-':
3192  return (currtoken = MINUS);
3193 
3194  case '+':
3195  return (currtoken = PLUS);
3196 
3197  case '>':
3198  if ((c = in->get()), c == '=') {
3199  return (currtoken = GE);
3200  }
3201  in->putback(char(c));
3202  return (currtoken = GT);
3203 
3204  case '=':
3205  if ((c = in->get()), c == '=') {
3206  return (currtoken = EQ);
3207  }
3208  in->putback(char(c));
3209  return (currtoken = ASSIGN);
3210 
3211  case '<':
3212  if ((c = in->get()), c == '=') {
3213  return (currtoken = LE);
3214  }
3215  in->putback(char(c));
3216  return (currtoken = LT);
3217 
3218  case '!':
3219  if ((c = in->get()), c == '=') {
3220  return (currtoken = NE);
3221  }
3222  in->putback(char(c));
3223  return (currtoken = NOT);
3224 
3225  case '&':
3226  if ((c = in->get()), c != '&') {
3227  return (currtoken = UNKNOWNTOKEN);
3228  }
3229  return (currtoken = AND);
3230 
3231  case '|':
3232  if ((c = in->get()), c != '|') {
3233  return (currtoken = UNKNOWNTOKEN);
3234  }
3235  return (currtoken = OR);
3236 
3237  case '~':
3238  if ((c = in->get()), c != '|') {
3239  return (currtoken = UNKNOWNTOKEN);
3240  }
3241  return (currtoken = XOR);
3242 
3243  case '(':
3244  return (currtoken = OBR);
3245 
3246  case ')':
3247  return (currtoken = CBR);
3248 
3249  case '[':
3250  return (currtoken = OPGIN);
3251 
3252  case ']':
3253  return (currtoken = CPGIN);
3254 
3255  case ';':
3256  return (currtoken = STMTSEP);
3257 
3258  case ',':
3259  return (currtoken = ARGSEP);
3260 
3261  case ':':
3262  if ((c = in->get()), c != ':') {
3263  return (currtoken = UNKNOWNTOKEN);
3264  }
3265  return (currtoken = NAMESPACESEP);
3266 
3267  case '"': {
3268  namebuf.clear();
3269  while ((c = in->get()) != '"') {
3270  if (c == '\\') {
3271  c = in->get();
3272  if (c == '\0') {
3273  return (currtoken = UNKNOWNTOKEN);
3274  }
3275  if (c == EOF || in->eof()) {
3276  return (currtoken = ENDOFFILE);
3277  }
3278  }
3279  namebuf.push_back(char(c));
3280  }
3282  value.Set(namebuf);
3283  return (currtoken = NUM);
3284  }
3285 
3286  default:
3287  return (currtoken = UNKNOWNTOKEN);
3288  }
3289 }
3290 
3291 bool
3292 MathParser::bNameValidate(const std::string& s) const
3293 {
3294  std::string::const_iterator i = s.begin();
3295  if (*i != '_' && !isalpha(*i)) {
3296  return false;
3297  }
3298 
3299  while (++i != s.end()) {
3300  if (*i != '_' && !isalnum(*i)) {
3301  return false;
3302  }
3303  }
3304 
3305  return true;
3306 }
3307 
3308 #ifndef USE_EE
3309 TypedValue
3311 {
3312  return logical_int(relational());
3313 }
3314 
3315 TypedValue
3317 {
3318  return logical_int(relational(d));
3319 }
3320 
3321 TypedValue
3323 {
3324  while (true) {
3325  switch (currtoken) {
3326  case AND:
3327  GetToken();
3328  d = (d && relational());
3329  break;
3330 
3331  case OR:
3332  GetToken();
3333  d = (d || relational());
3334  break;
3335 
3336  case XOR: {
3337  GetToken();
3338  TypedValue e = relational();
3339  d = ((!(d && e)) && (d || e));
3340  break;
3341  }
3342 
3343  default:
3344  return d;
3345  }
3346  }
3347 }
3348 
3349 TypedValue
3351 {
3352  return relational_int(binary());
3353 }
3354 
3355 TypedValue
3357 {
3358  return relational_int(binary(d));
3359 }
3360 
3361 TypedValue
3363 {
3364  while (true) {
3365  switch (currtoken) {
3366  case GT:
3367  GetToken();
3368  d = (d > binary());
3369  break;
3370 
3371  case GE:
3372  GetToken();
3373  d = (d >= binary());
3374  break;
3375 
3376  case EQ:
3377  GetToken();
3378  d = (d == binary());
3379  break;
3380 
3381  case LE:
3382  GetToken();
3383  d = (d <= binary());
3384  break;
3385 
3386  case LT:
3387  GetToken();
3388  d = (d < binary());
3389  break;
3390 
3391  case NE:
3392  GetToken();
3393  d = (d != binary());
3394  break;
3395 
3396  default:
3397  return d;
3398  }
3399  }
3400 }
3401 
3402 TypedValue
3404 {
3405  return binary_int(mult());
3406 }
3407 
3408 TypedValue
3410 {
3411  return binary_int(mult(d));
3412 }
3413 
3414 TypedValue
3416 {
3417  while (true) {
3418  switch (currtoken) {
3419  case PLUS:
3420  GetToken();
3421  d += mult();
3422  break;
3423 
3424  case MINUS:
3425  GetToken();
3426  d -= mult();
3427  break;
3428 
3429  default:
3430  return d;
3431  }
3432  }
3433 }
3434 
3435 TypedValue
3437 {
3438  return mult_int(power());
3439 }
3440 
3441 TypedValue
3443 {
3444  return mult_int(power(d));
3445 }
3446 
3447 TypedValue
3449 {
3450  while (true) {
3451  switch (currtoken) {
3452  case MULT:
3453  GetToken();
3454  d *= power();
3455  break;
3456 
3457  case DIV: {
3458  GetToken();
3459  TypedValue e = power();
3460  if (e == 0.) {
3461  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "divide by zero in mult()");
3462  }
3463  d /= e;
3464  break;
3465  }
3466 
3467  case MOD: {
3468  GetToken();
3469  TypedValue e = power();
3470  if (e == 0.) {
3471  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "divide by zero in mult()");
3472  }
3473  d %= e;
3474  break;
3475  }
3476 
3477  default:
3478  return d;
3479  }
3480  }
3481 }
3482 
3483 
3484 TypedValue
3486 {
3487  return power_int(unary());
3488 }
3489 
3490 TypedValue
3492 {
3493  return power_int(d);
3494 }
3495 
3496 TypedValue
3498 {
3499  if (currtoken == EXP) {
3500  GetToken();
3501 
3502  /*
3503  * Per l'esponente chiamo di nuovo power cosi' richiama unary;
3504  * se per caso dopo unary c'e' di nuovo un esponente,
3505  * l'associazione avviene correttamente da destra:
3506  *
3507  * d^e1^e2 == d^(e1^e2)
3508  */
3509  TypedValue e = power();
3510 
3511  if (d < 0. && e <= 0.) {
3512  DEBUGCERR("can't compute (" << d << ")^("
3513  << e << ") in power()" << std::endl);
3514  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "invalid operands in power()");
3515  }
3516 
3517  /*
3518  * Se sono entrambi interi, uso la sequenza di prodotti
3519  * (maggiore accuratezza? comunque va in overflow
3520  * correttamente)
3521  */
3522  if (e.GetType() == TypedValue::VAR_INT
3523  && d.GetType() == TypedValue::VAR_INT)
3524  {
3525  Int i = e.GetInt();
3526  Int j = d.GetInt();
3527  Int r = j;
3528  if (i == 0) {
3529  r = 1;
3530  } else if (i < 0) {
3531  r = 0;
3532  } else {
3533  for (Int k = i-1; k-- > 0; ) {
3534  r *= j;
3535  }
3536  }
3537  d = TypedValue(r);
3538  /*
3539  * Altrimenti li forzo entrambi a reale e uso pow
3540  * (ottimizzata di suo)
3541  */
3542  } else {
3543  Real r = e.GetReal();
3544  Real b = d.GetReal();
3546  d = TypedValue(Real(std::pow(b, r)));
3547  }
3548  }
3549 
3550  return d;
3551 }
3552 
3553 
3554 TypedValue
3556 {
3557  switch (currtoken) {
3558  case MINUS:
3559  GetToken();
3560  return -expr();
3561 
3562  case PLUS:
3563  GetToken();
3564  return expr();
3565 
3566  case NOT:
3567  GetToken();
3568  return !expr();
3569 
3570  default:
3571  return expr();
3572  }
3573 }
3574 
3575 TypedValue
3577 {
3578  for (unsigned i = 1; i < f->args.size(); i++) {
3579  switch (f->args[i]->Type()) {
3580  case MathParser::AT_ANY:
3581  if (currtoken == CBR) {
3582  if (!f->args[i]->IsFlag(MathParser::AF_OPTIONAL)) {
3583  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "argument expected");
3584  }
3585  (*dynamic_cast<MathArgAny_t*>(f->args[i]))() = (*dynamic_cast<MathArgAny_t*>(f->args[i]))();
3586  f->args[i]->SetFlag(MathParser::AF_OPTIONAL_NON_PRESENT);
3587 
3588  } else {
3589  (*dynamic_cast<MathArgAny_t*>(f->args[i]))() = stmtlist();
3590  }
3591  break;
3592 
3593  case MathParser::AT_BOOL:
3594  if (currtoken == CBR) {
3595  if (!f->args[i]->IsFlag(MathParser::AF_OPTIONAL)) {
3596  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "bool argument expected");
3597  }
3598  (*dynamic_cast<MathArgBool_t*>(f->args[i]))() = (*dynamic_cast<MathArgBool_t*>(f->args[i]))();
3599  f->args[i]->SetFlag(MathParser::AF_OPTIONAL_NON_PRESENT);
3600 
3601  } else {
3602  (*dynamic_cast<MathArgBool_t*>(f->args[i]))() = stmtlist().GetBool();
3603  }
3604  break;
3605 
3606  case MathParser::AT_INT:
3607  if (currtoken == CBR) {
3608  if (!f->args[i]->IsFlag(MathParser::AF_OPTIONAL)) {
3609  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "integer argument expected");
3610  }
3611  (*dynamic_cast<MathArgInt_t*>(f->args[i]))() = (*dynamic_cast<MathArgInt_t*>(f->args[i]))();
3612  f->args[i]->SetFlag(MathParser::AF_OPTIONAL_NON_PRESENT);
3613 
3614  } else {
3615  (*dynamic_cast<MathArgInt_t*>(f->args[i]))() = stmtlist().GetInt();
3616  }
3617  break;
3618 
3619  case MathParser::AT_REAL:
3620  if (currtoken == CBR) {
3621  if (!f->args[i]->IsFlag(MathParser::AF_OPTIONAL)) {
3622  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "real argument expected");
3623  }
3624  (*dynamic_cast<MathArgReal_t*>(f->args[i]))() = (*dynamic_cast<MathArgReal_t*>(f->args[i]))();
3625  f->args[i]->SetFlag(MathParser::AF_OPTIONAL_NON_PRESENT);
3626 
3627  } else {
3628  (*dynamic_cast<MathArgReal_t*>(f->args[i]))() = stmtlist().GetReal();
3629  }
3630  break;
3631 
3632  case MathParser::AT_STRING:
3633  if (currtoken == CBR) {
3634  if (!f->args[i]->IsFlag(MathParser::AF_OPTIONAL)) {
3635  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "string argument expected");
3636  }
3637  (*dynamic_cast<MathArgString_t*>(f->args[i]))() = (*dynamic_cast<MathArgString_t*>(f->args[i]))();
3638  f->args[i]->SetFlag(MathParser::AF_OPTIONAL_NON_PRESENT);
3639 
3640  } else {
3641  (*dynamic_cast<MathArgString_t*>(f->args[i]))() = stmtlist().GetString();
3642  }
3643  break;
3644 
3646  /* ignore */
3647  break;
3648 
3649  default:
3651  }
3652 
3653  if (i < f->args.size() - 1) {
3654  if (f->args[i + 1]->Type() != AT_PRIVATE) {
3655  switch (currtoken) {
3656  case CBR:
3657  if (!f->args[i + 1]->IsFlag(MathParser::AF_OPTIONAL)) {
3658  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
3659  "mandatory argument expected");
3660  }
3661  break;
3662 
3663  case ARGSEP:
3664  GetToken();
3665  break;
3666 
3667  default:
3668  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
3669  "argument separator expected");
3670  }
3671  }
3672  }
3673  }
3674 
3675  if (f->t != 0) {
3676  if (f->t(f->args)) {
3677  DEBUGCERR("error in function "
3678  << ns->sGetName() << "::" << f->fname
3679  << " " "(msg: " << f->errmsg << ")"
3680  << " in evalfunc()" << std::endl);
3681  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, f->fname + ": error " + f->errmsg);
3682  }
3683  }
3684 
3685  TypedValue val = ns->EvalFunc(f);
3686 
3687  return val;
3688 }
3689 
3690 TypedValue
3692 {
3693  if (currtoken == NUM) {
3694  GetToken();
3695  return value;
3696  }
3697 
3698  if (currtoken == OBR) {
3699  GetToken();
3700  TypedValue d = stmtlist();
3701  if (currtoken != CBR) {
3702  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "closing parenthesis expected");
3703  }
3704  GetToken();
3705  return d;
3706  }
3707 
3708  if (currtoken == OPGIN) {
3709  TypedValue d = readplugin();
3710  if (currtoken != CPGIN) {
3711  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "closing plugin expected");
3712  }
3713  GetToken();
3714  return d;
3715  }
3716 
3717  if (currtoken == NAME) {
3718  std::string name(namebuf);
3719  MathParser::NameSpace *currNameSpace = defaultNameSpace;
3720  Table *currTable = &table;
3721 
3722  GetToken();
3723  if (currtoken == NAMESPACESEP) {
3724  NameSpaceMap::iterator i = nameSpaceMap.find(name);
3725  if (i == nameSpaceMap.end()) {
3726  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
3727  std::string("unable to find namespace \"") + namebuf + "\"");
3728  }
3729  currNameSpace = i->second;
3730  currTable = currNameSpace->GetTable();
3731  GetToken();
3732  if (currtoken != NAME) {
3733  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "name expected after namespace");
3734  }
3735  name += "::";
3736  name += namebuf;
3737  GetToken();
3738  }
3739 
3740  if (currtoken == OBR) {
3741  /* in futuro ci potranno essere magari i dati strutturati */
3742  MathParser::MathFunc_t* f = currNameSpace->GetFunc(namebuf);
3743  if (f == NULL) {
3744  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
3745  std::string("function \"") + namebuf + "\" not found");
3746  }
3747  GetToken();
3748  TypedValue d = evalfunc(currNameSpace, f);
3749  delete f;
3750  if (currtoken != CBR) {
3751  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
3752  std::string("closing parenthesis expected after function \"")
3753  + f->fname + "\" in expr()");
3754  }
3755  GetToken();
3756  return d;
3757 
3758  } else {
3759  NamedValue* v = 0;
3760  if (currTable) {
3761  v = currTable->Get(namebuf);
3762  }
3763 
3764  if (v != NULL) {
3765  return v->GetVal();
3766  }
3767  }
3768 
3769  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, std::string("unknown name \"") + name + "\"");
3770  }
3771 
3772  /* invalid expr */
3773  if (currtoken != ENDOFFILE) {
3774  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "unknown token");
3775  }
3776 
3777  return TypedValue(0.);
3778 }
3779 
3780 TypedValue
3782 {
3783  if (currtoken == NAME) {
3784  bool isIfndef = false;
3785  bool isConst = false;
3786 
3787  DeclarationModifier declarationmodifier = GetDeclarationModifier(namebuf.c_str());
3788  if (declarationmodifier != DMOD_UNKNOWN) {
3789  switch (declarationmodifier) {
3790  case DMOD_IFNDEF:
3791  isIfndef = true;
3792  break;
3793 
3794  default:
3795  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
3796  std::string("unhandled definition modifier \"") + namebuf + "\"");
3797  }
3798 
3799  if (GetToken() != NAME) {
3800  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "type (modifier) expected "
3801  "after definition modifier in declaration");
3802  }
3803  }
3804 
3805  TypedValue::TypeModifier typemodifier = GetTypeModifier(namebuf.c_str());
3806  if (typemodifier != TypedValue::MOD_UNKNOWN) {
3807  switch (typemodifier) {
3808  case TypedValue::MOD_CONST:
3809  isConst = true;
3810  break;
3811 
3812  default:
3813  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
3814  std::string("unhandled type modifier \"") + namebuf + "\"");
3815  }
3816 
3817  if (GetToken() != NAME) {
3818  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "type expected "
3819  "after type modifier in declaration");
3820  }
3821  }
3822 
3823  /* declaration? */
3824  TypedValue::Type type = GetType(namebuf.c_str());
3825  if (type != TypedValue::VAR_UNKNOWN) {
3826  switch (GetToken()) {
3827  case OBR:
3828  // explicit cast?
3830  currtoken = NAME;
3831  return logical();
3832 
3833  case NAME:
3834  break;
3835 
3836  default:
3837  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "name expected "
3838  "after type in declaration");
3839  }
3840 
3841  if (IsKeyWord(defaultNameSpace, namebuf.c_str())) {
3842  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, std::string("name \"")
3843  + namebuf + "\" is a keyword");
3844  }
3845 
3846  MathParser::NameSpace *currNameSpace = defaultNameSpace;
3847  Table *currTable = &table;
3848  std::string name(namebuf);
3849 
3850  GetToken();
3851  if (currtoken == NAMESPACESEP) {
3852  NameSpaceMap::iterator i = nameSpaceMap.find(name);
3853  if (i == nameSpaceMap.end()) {
3854  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
3855  std::string("unable to find namespace \"") + namebuf + "\"");
3856  }
3857  currNameSpace = i->second;
3858  currTable = currNameSpace->GetTable();
3859  GetToken();
3860  if (currtoken != NAME) {
3861  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "name expected after namespace");
3862  }
3863  name += "::";
3864  name += namebuf;
3865  GetToken();
3866  }
3867 
3868  /* with assign? */
3869  if (currtoken == ASSIGN) {
3870  if (currTable == 0) {
3871  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
3872  std::string("namespace \"") + currNameSpace->sGetName()
3873  + "\" does not support variables");
3874  }
3875 
3876  /* faccio una copia del nome! */
3877  std::string varname(namebuf);
3878 
3879  GetToken();
3880  TypedValue d = logical();
3881  /* set const'ness of newly gotten value */
3882  if (isConst) {
3883  d.SetConst();
3884  }
3885  /* cerco la variabile */
3886  NamedValue* v = currTable->Get(varname.c_str());
3887 
3888  if (v == NULL) {
3889  /* create new var with assigned type */
3890  TypedValue newvar(type);
3891  /* assign new var, so that it internally
3892  * takes care of casting, while it inherits
3893  * const'ness from d */
3894  newvar.Cast(d);
3895  v = currTable->Put(varname.c_str(), newvar);
3896 
3897  if (isIfndef) {
3898  silent_cerr("warning, ifndef variable " << v->GetTypeName() << " \"" << name
3899  << "\" not yet defined; set to \"" << newvar << "\" at line " << mbdyn_get_line_data() << std::endl);
3900  }
3901 
3902  } else {
3903  /* altrimenti, se la posso ridefinire, mi limito
3904  * ad assegnarle il nuovo valore */
3905  if (!bRedefineVars && !isIfndef) {
3907  std::string("cannot redefine var \"") + name + "\"");
3908  }
3909 
3910  if (v->Const() && !isIfndef) {
3911  // TODO: check redefinition of const'ness
3913  std::string("cannot redefine const named value \"") + name + "\"");
3914  }
3915 
3916  if (!v->IsVar()) {
3918  std::string("cannot redefine non-var named value \"") + name + "\"");
3919  }
3920 
3921  if (!isIfndef) {
3922  dynamic_cast<Var *>(v)->SetVal(d);
3923 
3924  } else {
3925  if (v->GetType() != type) {
3926  silent_cerr("warning, skipping redefinition of \"" << name.c_str() << "\""
3927  << " from " << v->GetTypeName() << " to " << TypedValue::GetTypeName(type)
3928  << " (orig=" << v->GetVal() << ", unchanged; new=" << d << ")"
3929  << " at line " << mbdyn_get_line_data() << std::endl);
3930 
3931  } else {
3932  silent_cerr("warning, skipping redefinition of " << v->GetTypeName() << " \"" << name.c_str() << "\""
3933  << " (orig=" << v->GetVal() << ", unchanged; new=" << d << ")"
3934  << " at line " << mbdyn_get_line_data() << std::endl);
3935  }
3936  }
3937  }
3938  return v->GetVal();
3939 
3940  } else if (currtoken == STMTSEP) {
3941  if (currTable == 0) {
3942  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
3943  std::string("namespace \"") + currNameSpace->sGetName()
3944  + "\" does not support variables");
3945  }
3946 
3947  NamedValue* v = currTable->Get(namebuf);
3948  if (v == NULL || (!bRedefineVars && !isIfndef)) {
3949  if (isConst) {
3950  /* cannot insert a const var
3951  * with no value */
3953  std::string("cannot create const named value \"")
3954  + namebuf + "\" with no value");
3955  }
3956  /* se la var non esiste, la inserisco;
3957  * se invece esiste e non vale
3958  * la ridefinizione, tento
3959  * di inserirla comunque, cosi'
3960  * table da' errore */
3961  v = currTable->Put(namebuf, TypedValue(type));
3962  }
3963 
3964  return v->GetVal();
3965  }
3966 
3967  } else {
3968  if (declarationmodifier != DMOD_UNKNOWN) {
3970  "definition modifier without type");
3971  }
3972 
3973  if (typemodifier != TypedValue::MOD_UNKNOWN) {
3975  "type modifier without type");
3976  }
3977 
3978  MathParser::NameSpace *currNameSpace = defaultNameSpace;
3979  Table *currTable = &table;
3980  std::string name(namebuf);
3981 
3982  GetToken();
3983  if (currtoken == NAMESPACESEP) {
3984  NameSpaceMap::iterator i = nameSpaceMap.find(name);
3985  if (i == nameSpaceMap.end()) {
3986  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
3987  std::string("unable to find namespace \"") + namebuf + "\"");
3988  }
3989  currNameSpace = i->second;
3990  currTable = currNameSpace->GetTable();
3991  GetToken();
3992  if (currtoken != NAME) {
3993  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "name expected after namespace");
3994  }
3995  name += "::";
3996  name += namebuf;
3997  GetToken();
3998  }
3999 
4000  if (currtoken == OBR) {
4001  /* in futuro ci potranno essere magari i dati strutturati */
4002  MathParser::MathFunc_t* f = currNameSpace->GetFunc(namebuf);
4003  if (f == NULL) {
4004  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
4005  std::string("function \"") + namebuf + "\" not found");
4006  }
4007  GetToken();
4008  TypedValue d = evalfunc(currNameSpace, f);
4009  delete f;
4010  if (currtoken != CBR) {
4011  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
4012  std::string("closing parenthesis expected after function \"")
4013  + f->fname + "\" in expr()");
4014  }
4015  GetToken();
4016 
4017  return logical(d);
4018  }
4019 
4020  /* assignment? */
4021  if (currTable == 0) {
4022  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
4023  std::string("namespace \"") + currNameSpace->sGetName()
4024  + "\" does not support variables");
4025  }
4026  NamedValue* v = currTable->Get(namebuf);
4027  if (v == NULL) {
4028  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, std::string("var \"") + namebuf + "\" not found");
4029  }
4030 
4031  if (currtoken == ASSIGN) {
4032  GetToken();
4033  TypedValue d = logical();
4034  if (v->Const()) {
4036  std::string("cannot assign const named value \"") + name + "\"");
4037  }
4038 
4039  if (!v->IsVar()) {
4041  std::string("cannot assign non-var named value \"") + name + "\"");
4042  }
4043  dynamic_cast<Var *>(v)->Cast(d);
4044  return v->GetVal();
4045 
4046  } else {
4047  // NOTE: fails if <name> is actually <namespace>::<name>
4048  // ASSERT(currtoken != NAME);
4049  // TokenPush(currtoken);
4050  // currtoken = NAME;
4051 
4052  // NOTE: fails if <name> is not the complete <stmt>
4053  // return v->GetVal();
4054 
4055  return logical(v->GetVal());
4056  }
4057  }
4058  }
4059  return logical();
4060 }
4061 
4062 TypedValue
4064 {
4065  /*
4066  * parse plugin:
4067  * - arg[0]: nome plugin
4068  * - arg[1]: nome variabile
4069  * - arg[2]->arg[n]: dati da passare al costrutture
4070  */
4071  std::vector<char *> argv(1);
4072  char c, buf[1024];
4073  int argc = 0;
4074  unsigned int i = 0, in_quotes = 0;
4075 
4076  /*
4077  * inizializzo l'array degli argomenti
4078  */
4079  argv[0] = NULL;
4080 
4081  /*
4082  * parserizzo la stringa:
4083  * <plugin> ::= '[' <type> ',' <var_name> <list_of_args> ']'
4084  * <type> ::= <registered_type>
4085  * <var_name> ::= <legal_var_name>
4086  * <list_of_args> ::= ',' <arg> <list_of_args> | ''
4087  * <arg> ::= <legal_string> (no unescaped ']' or ','!)
4088  */
4089  while ((c = in->get()), !in->eof()) {
4090  switch (c) {
4091  case '\\':
4092  c = in->get();
4093  if (in_quotes) {
4094  switch (c) {
4095  case 'n':
4096  c = '\n';
4097  break;
4098 
4099  default:
4100  in->putback(c);
4101  c = '\\';
4102  break;
4103  }
4104  }
4105  buf[i++] = c;
4106  break;
4107 
4108  case '"':
4109  if (in_quotes == 0) {
4110  in_quotes = 1;
4111  break;
4112  }
4113  in_quotes = 0;
4114  while (isspace((c = in->get()))) {
4115  NO_OP;
4116  }
4117  if (c != ',' && c != ']') {
4118  silent_cerr("need a separator "
4119  "after closing quotes" << std::endl);
4121  }
4122  in->putback(c);
4123  break;
4124 
4125  case ',':
4126  case ']':
4127  if (in_quotes) {
4128  buf[i++] = c;
4129  break;
4130  }
4131  buf[i] = '\0';
4132  argv.resize(argc + 2);
4133  trim_arg(buf);
4134  SAFESTRDUP(argv[argc], buf);
4135  ++argc;
4136  argv[argc] = NULL;
4137  if (c == ']') {
4138  goto last_arg;
4139  }
4140  i = 0;
4141  break;
4142 
4143  default:
4144  buf[i++] = c;
4145  break;
4146  }
4147 
4148  /*
4149  * FIXME: rendere dinamico il buffer ...
4150  */
4151  if (i >= sizeof(buf)) {
4152  silent_cerr("MathParser::readplugin(): buffer overflow" << std::endl);
4154  }
4155  }
4156 
4157 last_arg:
4158  if (in->eof()) {
4159  silent_cerr("eof encountered while parsing plugin"
4160  << std::endl);
4162  }
4163 
4164  /*
4165  * put the close plugin token back
4166  */
4167  in->putback(c);
4168  buf[i] = '\0';
4169 
4170  /*
4171  * argomenti comuni a tutti i plugin
4172  */
4173  char *pginname = argv[0];
4174  char *varname = argv[1];
4175  trim_arg(pginname);
4176  trim_arg(varname);
4177 
4178  /*
4179  * verifiche di validita' argomenti
4180  */
4181  if (pginname == NULL || *pginname == '\0') {
4182  silent_cerr("illegal or missing plugin name" << std::endl);
4184  }
4185 
4186  if (varname == NULL || *varname == '\0') {
4187  silent_cerr("illegal or missing plugin variable name"
4188  << std::endl);
4190  }
4191 
4192  /*
4193  * verifica esistenza nome
4194  */
4195  NamedValue* v = table.Get(varname);
4196  if (v != NULL) {
4197  silent_cerr("variable \"" << varname << "\" already defined"
4198  << std::endl);
4200  }
4201 
4202  /*
4203  * ricerca registrazione plugin
4204  */
4205  for (struct PlugInRegister *p = PlugIns; p != NULL; p = p->next) {
4206  if (strcasecmp(p->name, pginname) != 0) {
4207  continue;
4208  }
4209 #ifdef DEBUG
4210  for (int i = 0; argv[i] != NULL; i++) {
4211  silent_cout("argv[" << i << "]=" << argv[i]
4212  << std::endl);
4213  }
4214 #endif /* DEBUG */
4215 
4216  /*
4217  * costruisce il plugin e gli fa interpretare gli argomenti
4218  */
4219  MathParser::PlugIn *pgin = (*p->constructor)(*this, p->arg);
4220  pgin->Read(argc - 2, &argv[2]);
4221 
4222  /*
4223  * riporta il parser nello stato corretto
4224  */
4225  GetToken();
4226 
4227  /*
4228  * costruisce la variabile, la inserisce nella tabella
4229  * e ne ritorna il valore (prima esecuzione)
4230  */
4232  PlugInVar(varname, pgin));
4233  table.Put(v);
4234 
4235  /*
4236  * pulizia ...
4237  */
4238  for (int i = 0; argv[i] != NULL; i++) {
4239  SAFEDELETEARR(argv[i]);
4240  }
4241 
4242  return v->GetVal();
4243  }
4244 
4245  /*
4246  * si arriva qui solo se il plugin non e' stato registrato
4247  */
4248  silent_cerr(" plugin '" << pginname << "' not supported" << std::endl);
4250 }
4251 
4252 TypedValue
4254 {
4255  TypedValue d = stmt();
4256  if (currtoken == STMTSEP) {
4257  GetToken();
4258  return stmtlist();
4259  }
4260  return d;
4261 }
4262 
4263 #endif // ! USE_EE
4264 
4265 
4267 : PlugIns(0),
4268 table(t),
4269 bRedefineVars(bRedefineVars),
4270 in(const_cast<InputStream*>(&strm)),
4271 defaultNameSpace(0),
4272 value(),
4274 {
4275  DEBUGCOUTFNAME("MathParser::MathParser");
4276 
4277  // namebuf.resize(4);
4278 
4281  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
4282  std::string("unable to register namespace \"") + defaultNameSpace->sGetName() + "\"");
4283  }
4284 
4285  time_t tm;
4286  time(&tm);
4287  srand(tm);
4288 }
4289 
4290 MathParser::MathParser(Table& t, bool bRedefineVars)
4291 : PlugIns(0),
4292 table(t),
4293 bRedefineVars(bRedefineVars),
4294 in(0),
4295 defaultNameSpace(0),
4296 value(),
4297 currtoken(UNKNOWNTOKEN)
4298 {
4299  DEBUGCOUTFNAME("MathParser::MathParser");
4300 
4301  // namebuf.resize(4);
4302 
4305  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
4306  std::string("unable to register namespace \"") + defaultNameSpace->sGetName() + "\"");
4307  }
4308 
4309  time_t tm;
4310  time(&tm);
4311  srand(tm);
4312 }
4313 
4314 NamedValue *
4315 MathParser::InsertSym(const char* const s, const Real& v, int redefine)
4316 {
4317  /* cerco la variabile */
4318  NamedValue* var = table.Get(s);
4319 
4320  if (var == 0) {
4321  /* Se non c'e' la inserisco */
4322  var = table.Put(s, TypedValue(v));
4323  } else {
4324  /* altrimenti, se la posso ridefinire, mi limito
4325  * ad assegnarle il nuovo valore */
4326  if (redefine) {
4327  if (var->IsVar()) {
4328  dynamic_cast<Var *>(var)->SetVal(TypedValue(v));
4329  } else {
4331  std::string("cannot redefine non-var named value \"") + var->GetName() + "\"");
4332  }
4333 
4334  } else {
4335  /* altrimenti la reinserisco, cosi'
4336  * da provocare l'errore di table */
4337  var = table.Put(s, TypedValue(v));
4338  }
4339  }
4340 
4341  if (var == NULL) {
4342  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, std::string("error while adding real var \"") + s + "\"");
4343  }
4344 
4345  return var;
4346 }
4347 
4348 NamedValue *
4349 MathParser::InsertSym(const char* const s, const Int& v, int redefine)
4350 {
4351  /* cerco la variabile */
4352  NamedValue* var = table.Get(s);
4353 
4354  if (var == NULL) {
4355  /* Se non c'e' la inserisco */
4356  var = table.Put(s, TypedValue(v));
4357 
4358  } else {
4359  /* altrimenti, se la posso ridefinire, mi limito
4360  * ad assegnarle il nuovo valore */
4361  if (redefine) {
4362  if (var->IsVar()) {
4363  dynamic_cast<Var *>(var)->SetVal(TypedValue(v));
4364 
4365  } else {
4367  std::string("cannot redefine non-var named value \"") + var->GetName() + "\"");
4368  }
4369 
4370  } else {
4371  /* altrimenti la reinserisco, cosi'
4372  * da provocare l'errore di table */
4373  var = table.Put(s, TypedValue(v));
4374  }
4375  }
4376 
4377  if (var == NULL) {
4378  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
4379  std::string("error while adding integer var \"") + s + "\"");
4380  }
4381 
4382  return var;
4383 }
4384 
4386 {
4387  DEBUGCOUTFNAME("MathParser::~MathParser");
4388 
4389  while (PlugIns) {
4390  PlugInRegister *next = PlugIns->next;
4393  PlugIns = next;
4394  }
4395 
4396  for (NameSpaceMap::iterator i = nameSpaceMap.begin(); i != nameSpaceMap.end(); ++i) {
4397  delete i->second;
4398  }
4399 }
4400 
4401 Real
4403 {
4404  if (GetToken() == t) {
4405  return d;
4406  }
4407 
4408  for (;;) {
4409 #ifdef USE_EE
4410  ExpressionElement *e = stmtlist();
4411  d = e->Eval().GetReal();
4412  if (pedantic_out) {
4413  std::cout << "GetLastStmt: \"", e->Output(std::cout) << "\" = " << d << std::endl;
4414  }
4415  delete e;
4416 #else // ! USE_EE
4417  d = stmtlist().GetReal();
4418 #endif // ! USE_EE
4419  if (currtoken == ENDOFFILE || currtoken == t) {
4420  break;
4421  }
4422  if (currtoken != STMTSEP) {
4423  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "statement separator expected");
4424  }
4425  }
4426 
4427  return d;
4428 }
4429 
4430 Real
4432 {
4433  const InputStream* save_in = in;
4434  Token save_currtoken = currtoken;
4435 
4436  in = const_cast<InputStream *>(&strm);
4438 
4439  d = GetLastStmt(d, t);
4440 
4441  in = const_cast<InputStream *>(save_in);
4442  currtoken = save_currtoken;
4443 
4444  return d;
4445 }
4446 
4447 #ifdef USE_EE
4449 MathParser::GetExpr(void)
4450 {
4451  if (GetToken() == ARGSEP) {
4452  return new EE_Value(0.);
4453  }
4454 
4455  ExpressionElement *e = 0;
4456  for (;;) {
4457  e = stmtlist();
4458  if (pedantic_out) {
4459  std::cout << "GetExpr: \"", e->Output(std::cout) << "\"" << std::endl;
4460  }
4461 
4462  if (currtoken == ENDOFFILE || currtoken == ARGSEP) {
4463  break;
4464  }
4465 
4466  if (currtoken != STMTSEP) {
4467  delete e;
4468  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "statement separator expected");
4469  }
4470  }
4471 
4472  // NOTE: caller must explicitly delete it
4473  return e;
4474 }
4475 
4477 MathParser::GetExpr(const InputStream& strm)
4478 {
4479  const InputStream *save_in = in;
4480  Token save_currtoken = currtoken;
4481 
4482  in = const_cast<InputStream *>(&strm);
4484 
4485  ExpressionElement *e = GetExpr();
4486 
4487  in = const_cast<InputStream *>(save_in);
4488  currtoken = save_currtoken;
4489 
4490  // NOTE: caller must explicitly delete it
4491  return e;
4492 }
4493 #endif // USE_EE
4494 
4495 Real
4497 {
4498  TypedValue v(d);
4499  v = Get(v);
4500  return v.GetReal();
4501 }
4502 
4503 Real
4505 {
4506  TypedValue v(d);
4507  v = Get(strm, v);
4508  return v.GetReal();
4509 }
4510 
4511 TypedValue
4512 MathParser::Get(const TypedValue& /* v */ )
4513 {
4514  GetToken();
4515 #ifdef USE_EE
4516  ExpressionElement *e = stmt();
4517  TypedValue vv = e->Eval();
4518  if (pedantic_out) {
4519  std::cout << "Get: \"", e->Output(std::cout) << "\" = " << vv << std::endl;
4520  }
4521  delete e;
4522 #else // ! USE_EE
4523  TypedValue vv = stmt();
4524 #endif // ! USE_EE
4525  if (currtoken != STMTSEP && currtoken != ENDOFFILE) {
4526  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "statement separator expected");
4527  }
4528  return vv;
4529 }
4530 
4531 TypedValue
4533 {
4534  const InputStream* p = in;
4535  in = (InputStream*)&strm;
4536  GetToken();
4537  TypedValue vv = v;
4538  if (currtoken != STMTSEP && currtoken != ARGSEP) {
4539 #ifdef USE_EE
4540  ExpressionElement *e = stmt();
4541  vv = e->Eval();
4542  if (pedantic_out) {
4543  std::cout << "Get: \"", e->Output(std::cout) << "\" = " << vv << std::endl;
4544  }
4545  delete e;
4546 #else // ! USE_EE
4547  vv = stmt();
4548 #endif // ! USE_EE
4549  }
4550  if (currtoken == STMTSEP) {
4551  in->putback(';');
4552 
4553  } else if (currtoken == ARGSEP) {
4554  in->putback(',');
4555 
4556  } else {
4557  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "separator expected");
4558  }
4559  in = const_cast<InputStream *>(p);
4560 
4561  return vv;
4562 }
4563 
4564 void
4565 MathParser::GetForever(std::ostream& out, const char* const sep)
4566 {
4567  do {
4568  TypedValue val(0.);
4569  out << Get(val) << sep;
4570  } while (currtoken == STMTSEP);
4571 }
4572 
4573 void
4574 MathParser::GetForever(const InputStream& strm, std::ostream& out,
4575  const char* const /* sep */ )
4576 {
4577  InputStream *p = in;
4578  in = const_cast<InputStream *>(&strm);
4579  GetForever(out);
4580  in = p;
4581 }
4582 
4583 int
4585  MathParser::PlugIn * (*constructor)(MathParser&, void *),
4586  void *arg)
4587 {
4588  pedantic_cout("registering plugin \"" << name << "\"" << std::endl);
4589 
4590  PlugInRegister *p = NULL;
4591  SAFENEW(p, PlugInRegister);
4592  SAFESTRDUP(p->name, name);
4593  p->constructor = constructor;
4594  p->arg = arg;
4595  p->next = PlugIns;
4596  PlugIns = p;
4597 
4598  return 0;
4599 }
4600 
4601 int
4603 {
4604  ASSERT(ns != 0);
4605 
4606  pedantic_cout("MathParser::RegisterNameSpace: "
4607  "registering namespace \"" << ns->sGetName() << "\""
4608  << std::endl);
4609 
4610  if (nameSpaceMap.find(ns->sGetName()) != nameSpaceMap.end()) {
4611  return 1;
4612  }
4613 
4614  nameSpaceMap[ns->sGetName()] = ns;
4615 
4616  return 0;
4617 }
4618 
4620 MathParser::GetNameSpace(const std::string& name) const
4621 {
4622  NameSpaceMap::const_iterator i = nameSpaceMap.find(name);
4623  if (i == nameSpaceMap.end()) {
4624  return 0;
4625  }
4626 
4627  return i->second;
4628 }
4629 
4630 #ifdef USE_EE
4631 /*
4632  * Evaluator code
4633  * Each function return ExpressionElement * for constructing a tree
4634  */
4636 MathParser::logical(void)
4637 {
4638  return logical_int(relational());
4639 }
4640 
4643 {
4644  return logical_int(relational(d));
4645 }
4646 
4649 {
4650  while (true) {
4651  switch (currtoken) {
4652  case AND:
4653  GetToken();
4654  // d = new EE_AND(d , relational());
4655  d = EECreate<EE_AND>(d , relational());
4656  break;
4657 
4658  case OR:
4659  GetToken();
4660  // d = new EE_OR(d, relational());
4661  d = EECreate<EE_OR>(d , relational());
4662  break;
4663 
4664  case XOR:
4665  GetToken();
4666  // d = new EE_XOR(d, relational());
4667  d = EECreate<EE_XOR>(d , relational());
4668  break;
4669 
4670  default:
4671  return d;
4672  }
4673  }
4674 }
4675 
4678 {
4679  return relational_int(binary());
4680 }
4681 
4684 {
4685  return relational_int(binary(d));
4686 }
4687 
4690 {
4691  while (true) {
4692  switch (currtoken) {
4693  case GT:
4694  GetToken();
4695  // d = new EE_Greater(d, binary());
4696  d = EECreate<EE_Greater>(d , binary());
4697  break;
4698 
4699  case GE:
4700  GetToken();
4701  // d = new EE_Greater_Equal(d, binary());
4702  d = EECreate<EE_Greater_Equal>(d , binary());
4703  break;
4704 
4705  case EQ:
4706  GetToken();
4707  // d = new EE_Equal_Equal(d, binary());
4708  d = EECreate<EE_Equal_Equal>(d , binary());
4709  break;
4710 
4711  case LE:
4712  GetToken();
4713  // d = new EE_Lesser_Equal(d, binary());
4714  d = EECreate<EE_Lesser_Equal>(d , binary());
4715  break;
4716 
4717  case LT:
4718  GetToken();
4719  // d = new EE_Lesser(d, binary());
4720  d = EECreate<EE_Lesser>(d , binary());
4721  break;
4722 
4723  case NE:
4724  GetToken();
4725  // d = new EE_Not_Equal(d, binary());
4726  d = EECreate<EE_Not_Equal>(d , binary());
4727  break;
4728 
4729  default:
4730  return d;
4731  }
4732  }
4733 }
4734 
4736 MathParser::binary(void)
4737 {
4738  return binary_int(mult());
4739 }
4740 
4743 {
4744  return binary_int(mult(d));
4745 }
4746 
4749 {
4750  while (true) {
4751  switch (currtoken) {
4752  case PLUS:
4753  GetToken();
4754  // d = new EE_Plus(d, mult());
4755  d = EECreate<EE_Plus>(d , mult());
4756  break;
4757 
4758  case MINUS:
4759  GetToken();
4760  // d = new EE_Minus(d, mult());
4761  d = EECreate<EE_Minus>(d , mult());
4762  break;
4763 
4764  default:
4765  return d;
4766  }
4767  }
4768 }
4769 
4771 MathParser::mult(void)
4772 {
4773  return mult_int(power());
4774 }
4775 
4778 {
4779  return mult_int(power(d));
4780 }
4781 
4784 {
4785  while (true) {
4786  switch (currtoken) {
4787  case MULT:
4788  GetToken();
4789  // d = new EE_Multiply(d, power());
4790  d = EECreate<EE_Multiply>(d , power());
4791  break;
4792 
4793  case DIV:
4794  GetToken();
4795  // d = new EE_Divide(d, power());
4796  d = EECreate<EE_Divide>(d , power());
4797  break;
4798 
4799  case MOD:
4800  GetToken();
4801  // d = new EE_Modulus(d, power());
4802  d = EECreate<EE_Modulus>(d , power());
4803  break;
4804 
4805  default:
4806  return d;
4807  }
4808  }
4809 }
4810 
4811 
4813 MathParser::power(void)
4814 {
4815  return power_int(unary());
4816 }
4817 
4820 {
4821  return power_int(d);
4822 }
4823 
4826 {
4827  if (currtoken == EXP) {
4828  GetToken();
4829 
4830  /*
4831  * Per l'esponente chiamo di nuovo power cosi' richiama unary;
4832  * se per caso dopo unary c'e' di nuovo un esponente,
4833  * l'associazione avviene correttamente da destra:
4834  *
4835  * d^e1^e2 == d^(e1^e2)
4836  */
4837 
4838  // d = new EE_Power(d, power());
4839  d = EECreate<EE_Power>(d , power());
4840  }
4841 
4842  return d;
4843 }
4844 
4845 
4847 MathParser::unary(void)
4848 {
4849  switch (currtoken) {
4850  case MINUS:
4851  GetToken();
4852  // return new EE_Unary_minus(expr());
4853  return EECreate<EE_Unary_minus>(expr());
4854 
4855  case PLUS:
4856  GetToken();
4857  return expr();
4858 
4859  case NOT:
4860  GetToken();
4861  // return new EE_NOT(expr());
4862  return EECreate<EE_NOT>(expr());
4863 
4864  default:
4865  return expr();
4866  }
4867 }
4868 
4870 MathParser::parsefunc(MathFunc_t* f)
4871 {
4872  for (unsigned i = 1; i < f->args.size(); i++) {
4873  switch (f->args[i]->Type()) {
4874  case MathParser::AT_ANY:
4875  case MathParser::AT_BOOL:
4876  case MathParser::AT_INT:
4877  case MathParser::AT_REAL:
4878  case MathParser::AT_STRING:
4879  if (currtoken == CBR) {
4880  if (!f->args[i]->IsFlag(MathParser::AF_OPTIONAL)) {
4881  switch (f->args[i]->Type()) {
4882  case MathParser::AT_ANY:
4883  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "argument expected");
4884  case MathParser::AT_BOOL:
4885  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "bool argument expected");
4886  case MathParser::AT_INT:
4887  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "integer argument expected");
4888  case MathParser::AT_REAL:
4889  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "real argument expected");
4890  case MathParser::AT_STRING:
4891  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "string argument expected");
4892  default:
4893  // impossible
4894  ASSERT(0);
4895  throw;
4896  }
4897  }
4898  f->args[i]->SetFlag(MathParser::AF_OPTIONAL_NON_PRESENT);
4899 
4900  } else {
4901  ExpressionElement *ee = stmtlist();
4902  f->args[i]->SetExpr(ee);
4903  if (dynamic_cast<EE_Value *>(ee)) {
4904  f->args[i]->SetFlag(AF_CONST);
4905  }
4906  }
4907  break;
4908 
4910  /* ignore */
4911  break;
4912 
4913  default:
4914  /* NOTE: will need to deal with future types */
4916  }
4917 
4918  if (i < f->args.size() - 1) {
4919  if (f->args[i + 1]->Type() != MathParser::AT_PRIVATE) {
4920  switch (currtoken) {
4921  case CBR:
4922  if (!f->args[i + 1]->IsFlag(MathParser::AF_OPTIONAL)) {
4923  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
4924  "mandatory argument expected");
4925  }
4926  break;
4927 
4928  case ARGSEP:
4929  GetToken();
4930  break;
4931 
4932  default:
4933  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
4934  "argument separator expected");
4935  }
4936  }
4937  }
4938  }
4939 
4940  return new EE_Func(this, f);
4941 }
4942 
4944 MathParser::expr(void)
4945 {
4946  if (currtoken == NUM) {
4947  GetToken();
4948  return new EE_Value(value);
4949  }
4950 
4951  if (currtoken == OBR) {
4952  GetToken();
4953  ExpressionElement *d = stmtlist();
4954  if (currtoken != CBR) {
4955  delete d;
4956  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "closing parenthesis expected");
4957  }
4958  GetToken();
4959  return d;
4960  }
4961 
4962  if (currtoken == OPGIN) {
4964  if (currtoken != CPGIN) {
4965  delete d;
4966  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "closing plugin expected");
4967  }
4968  GetToken();
4969  return d;
4970  }
4971 
4972  if (currtoken == NAME) {
4973  std::string name(namebuf);
4974  MathParser::NameSpace *currNameSpace = defaultNameSpace;
4975  Table *currTable = &table;
4976 
4977  GetToken();
4978  if (currtoken == NAMESPACESEP) {
4979  NameSpaceMap::iterator i = nameSpaceMap.find(name);
4980  if (i == nameSpaceMap.end()) {
4981  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
4982  std::string("unable to find namespace \"") + namebuf + "\"");
4983  }
4984  currNameSpace = i->second;
4985  currTable = currNameSpace->GetTable();
4986  GetToken();
4987  if (currtoken != NAME) {
4988  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "name expected after namespace");
4989  }
4990  name += "::";
4991  name += namebuf;
4992  GetToken();
4993  }
4994 
4995  if (currtoken == OBR) {
4996  /* function handling
4997  * in futuro ci potranno essere magari i dati strutturati */
4998  MathFunc_t* f = currNameSpace->GetFunc(namebuf);
4999  if (f == 0) {
5000  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5001  std::string("function \"") + name + "\" not found");
5002  }
5003  GetToken();
5004  ExpressionElement *e = parsefunc(f);
5005  if (currtoken != CBR) {
5006  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5007  std::string("closing parenthesis expected after function \"") + f->fname + "\" in expr()");
5008  }
5009  GetToken();
5010  return e;
5011 
5012  } else {
5013  NamedValue* v = 0;
5014  if (currTable) {
5015  v = currTable->Get(namebuf);
5016  }
5017 
5018  if (v != NULL) {
5020  return new EE_Var(v, currNameSpace);
5021  }
5022  return new EE_Value(v->GetVal());
5023  }
5024  }
5025 
5026  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, std::string("unknown name \"") + name + "\"");
5027  }
5028 
5029  /* invalid expr */
5030  if (currtoken != ENDOFFILE) {
5031  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "unknown token");
5032  }
5033 
5034  // FIXME: is this ok?
5035  TypedValue a(0., true);
5036  return new EE_Value(a);
5037 }
5038 
5039 
5041 MathParser::stmt(void)
5042 {
5043  if (currtoken == NAME) {
5044  bool bIsIfndef = false;
5045  bool bIsConst = false;
5046 
5047  DeclarationModifier declarationmodifier = GetDeclarationModifier(namebuf.c_str());
5048  if (declarationmodifier != DMOD_UNKNOWN) {
5049  switch (declarationmodifier) {
5050  case DMOD_IFNDEF:
5051  bIsIfndef = true;
5052  break;
5053 
5054  default:
5055  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5056  std::string("unhandled definition modifier \"") + namebuf + "\"");
5057  }
5058 
5059  if (GetToken() != NAME) {
5060  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "type (modifier) expected "
5061  "after definition modifier in declaration");
5062  }
5063  }
5064 
5065  TypedValue::TypeModifier typemodifier = GetTypeModifier(namebuf.c_str());
5066  if (typemodifier != TypedValue::MOD_UNKNOWN) {
5067  switch (typemodifier) {
5068  case TypedValue::MOD_CONST:
5069  bIsConst = true;
5070  break;
5071 
5072  default:
5073  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5074  std::string("unhandled type modifier \"") + namebuf + "\"");
5075  }
5076 
5077  if (GetToken() != NAME) {
5078  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "type expected "
5079  "after type modifier in declaration");
5080  }
5081  }
5082 
5083  /* declaration? */
5084  TypedValue::Type type = GetType(namebuf.c_str());
5085  if (type != TypedValue::VAR_UNKNOWN) {
5086  switch (GetToken()) {
5087  case OBR:
5088  // explicit cast?
5090  currtoken = NAME;
5091  return logical();
5092 
5093  case NAME:
5094  break;
5095 
5096  default:
5097  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "name expected "
5098  "after type in declaration");
5099  }
5100 
5101  if (IsKeyWord(defaultNameSpace, namebuf.c_str())) {
5102  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5103  std::string("name \"") + namebuf + "\" is a keyword");
5104  }
5105 
5106  MathParser::NameSpace *currNameSpace = defaultNameSpace;
5107  Table *currTable = &table;
5108  std::string name(namebuf);
5109 
5110  GetToken();
5111  if (currtoken == NAMESPACESEP) {
5112  NameSpaceMap::iterator i = nameSpaceMap.find(name);
5113  if (i == nameSpaceMap.end()) {
5114  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5115  std::string("unable to find namespace \"") + namebuf + "\"");
5116  }
5117  currNameSpace = i->second;
5118  currTable = currNameSpace->GetTable();
5119  GetToken();
5120  if (currtoken != NAME) {
5121  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "name expected after namespace");
5122  }
5123  name += "::";
5124  name += namebuf;
5125  GetToken();
5126  }
5127 
5128  /* TODO: this needs a *LOT* of work
5129  *
5130  * - if the definition is without assignment?
5131  * - if the definition is with assignment and it is const?
5132  * - when can we safely evaluate the value?
5133 
5134  (const integer i = 10) -> declaration, assignment, referentiation ::= EE_Declare, EE_Assign?
5135  (integer i = 10) -> declaration, assignment, referentiation ::= EE_Declare, EE_Assign?
5136  (integer i) -> declaration ::= EE_Declare?
5137  (i = 10) -> assigment, referentiation ::= EE_Assign?
5138  (i) -> referentiation ::= EE_Var
5139 
5140  * if we pre-declare, and only use EE_Assign, we implicitly
5141  * turn stuff like "real A = B + C" into "real A" once,
5142  * followed by multiple "A = B + C", which may be good
5143  * but is not consistent with earlier behavior
5144  *
5145  * Alternatively, we need EE_Declare (and possibly EE_Declare_Assign),
5146  * although its only purpose is to fail when repeatedly invoked.
5147  *
5148  * Another point: an expression like
5149 
5150  ((integer i = 10) && i)
5151 
5152  * is now perfectly valid, since "i" is created before it is referenced
5153  * after "&&".
5154  *
5155  * However, in the new implementation as it is now (pre-declaration)
5156  * it works fine, but it would fail if we introduce EE_Declare,
5157  * because "i" would not exist during parsing, it would only exist
5158  * during evaluation.
5159  *
5160  * Pre-declaration seems good, but we need to find a way
5161  * to intercept repeated declarations. For instance:
5162  * - pre-declaration and assignment of const
5163  * - pre-declaration, deferred assignment of non-const
5164  * - evaluation flag for all? Fail if evaluated more than once.
5165  */
5166 
5167  /* with assign? */
5168  if (currtoken == ASSIGN) {
5169  if (currTable == 0) {
5170  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5171  std::string("namespace \"") + currNameSpace->sGetName() + "\" does not support variables");
5172  }
5173 
5174  /* faccio una copia del nome! */
5175  std::string varname(namebuf);
5176 
5177  GetToken();
5178  ExpressionElement *e = logical();
5179 
5180  /* cerco la variabile */
5181  NamedValue* v = currTable->Get(varname.c_str());
5182 
5183  if (v == 0) {
5184  /* create new var with assigned type */
5185  TypedValue newvar(type);
5186  /* assign new var, so that it internally
5187  * takes care of casting, while it inherits
5188  * const'ness from d */
5189  TypedValue d(e->Eval());
5190  delete e;
5191  e = 0;
5192 
5193  if (bIsConst) {
5194  d.SetConst();
5195  }
5196  newvar.Cast(d);
5197 
5198  v = currTable->Put(varname.c_str(), newvar);
5199 
5200  if (bIsIfndef) {
5201  silent_cerr("warning, ifndef variable " << v->GetTypeName() << " \"" << name
5202  << "\" not yet defined; set to \"" << newvar << "\" at line " << mbdyn_get_line_data() << std::endl);
5203  }
5204 
5205  } else {
5206  /* altrimenti, se la posso ridefinire, mi limito
5207  * ad assegnarle il nuovo valore */
5208  if (!bRedefineVars && !bIsIfndef) {
5210  std::string("cannot redefine var \"") + name + "\"");
5211  }
5212 
5213  if (v->Const() && !bIsIfndef) {
5214  // TODO: check redefinition of const'ness
5216  std::string("cannot redefine const named value \"") + name + "\"");
5217  }
5218 
5219  if (!v->IsVar()) {
5221  std::string("cannot redefine non-var named value \"") + name + "\"");
5222  }
5223 
5224  if (!bIsIfndef) {
5225  dynamic_cast<Var *>(v)->SetVal(e->Eval());
5226 
5227  } else {
5228  if (v->GetType() != type) {
5229  silent_cerr("warning, skipping redefinition of \"" << name.c_str() << "\""
5230  << " from " << v->GetTypeName() << " to " << TypedValue::GetTypeName(type)
5231  << " (orig=" << v->GetVal() << ", unchanged; new=" << e->Eval() << ")"
5232  << " at line " << mbdyn_get_line_data() << std::endl);
5233 
5234  } else {
5235  silent_cerr("warning, skipping redefinition of " << v->GetTypeName() << " \"" << name.c_str() << "\""
5236  << " (orig=" << v->GetVal() << ", unchanged; new=" << e->Eval() << ")"
5237  << " at line " << mbdyn_get_line_data() << std::endl);
5238  }
5239  }
5240 
5241  delete e;
5242  e = 0;
5243  }
5244 
5246  return new EE_Value(dynamic_cast<Var *>(v)->GetVal());
5247 
5248  } else {
5249  return new EE_Var(v, currNameSpace);
5250  }
5251 
5252  } else if (currtoken == STMTSEP) {
5253  if (currTable == 0) {
5254  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5255  std::string("namespace \"") + currNameSpace->sGetName() + "\" does not support variables");
5256  }
5257 
5258  NamedValue* v = currTable->Get(namebuf);
5259  if (v == NULL || (!bRedefineVars && !bIsIfndef)) {
5260  if (bIsConst) {
5261  /* cannot insert a const var
5262  * with no value */
5264  std::string("cannot create const named value \"") + namebuf + "\" with no value");
5265  }
5266 
5267  /* se la var non esiste, la inserisco;
5268  * se invece esiste e non vale
5269  * la ridefinizione, tento
5270  * di inserirla comunque, cosi'
5271  * table da' errore */
5272  v = currTable->Put(namebuf, TypedValue(type));
5273  }
5274 
5275  return new EE_Var(v, currNameSpace);
5276  }
5277 
5278  } else {
5279  if (declarationmodifier != DMOD_UNKNOWN) {
5281  "definition modifier without type");
5282  }
5283 
5284  if (typemodifier != TypedValue::MOD_UNKNOWN) {
5286  "type modifier without type");
5287  }
5288 
5289  MathParser::NameSpace *currNameSpace = defaultNameSpace;
5290  Table *currTable = &table;
5291  std::string name(namebuf);
5292 
5293  GetToken();
5294  if (currtoken == NAMESPACESEP) {
5295  NameSpaceMap::iterator i = nameSpaceMap.find(name);
5296  if (i == nameSpaceMap.end()) {
5297  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5298  std::string("unable to find namespace \"") + namebuf + "\"");
5299  }
5300  currNameSpace = i->second;
5301  currTable = currNameSpace->GetTable();
5302  GetToken();
5303  if (currtoken != NAME) {
5304  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS, "name expected after namespace");
5305  }
5306  name += "::";
5307  name += namebuf;
5308  GetToken();
5309  }
5310 
5311  if (currtoken == OBR) {
5312  /* in futuro ci potranno essere magari i dati strutturati */
5313  MathFunc_t* f = currNameSpace->GetFunc(namebuf);
5314  if (f == 0) {
5315  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5316  std::string("function \"") + namebuf + "\" not found");
5317  }
5318  GetToken();
5319  ExpressionElement *e = parsefunc(f);
5320  if (currtoken != CBR) {
5321  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5322  std::string("closing parenthesis expected after function \"")
5323  + f->fname + "\" in expr()");
5324  }
5325  GetToken();
5326 
5327  return logical(e);
5328  }
5329 
5330  /* assignment? */
5331  if (currTable == 0) {
5332  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5333  std::string("namespace \"") + currNameSpace->sGetName()
5334  + "\" does not support variables");
5335  }
5336  NamedValue* v = currTable->Get(namebuf);
5337  if (v != 0) {
5338  if (currtoken == ASSIGN) {
5339  GetToken();
5340  ExpressionElement *e = logical();
5341  if (v->Const()) {
5343  std::string("cannot assign const named value \"") + name + "\"");
5344  }
5345 
5346  if (!v->IsVar()) {
5348  std::string("cannot assign non-var named value \"") + name + "\"");
5349  }
5350 
5351  // FIXME: we need to define a EE_Assign that does the operation below
5352  dynamic_cast<Var *>(v)->Cast(e->Eval());
5353  delete e;
5354  return new EE_Var(v, currNameSpace);
5355 
5356  } else {
5357  // NOTE: fails if <name> is actually <namespace>::<name>
5358  // ASSERT(currtoken != NAME);
5359  // TokenPush(currtoken);
5360  // currtoken = NAME;
5361 
5362  // NOTE: fails if <name> is not the complete <stmt>
5363  // return v->GetVal();
5364  ExpressionElement *e;
5366  e = new EE_Var(v, currNameSpace);
5367  } else {
5368  e = new EE_Value(v->GetVal());
5369  }
5370  return logical(e);
5371  }
5372 
5373  } else {
5374  throw ErrGeneric(this, MBDYN_EXCEPT_ARGS,
5375  std::string("unable to find variable \"")
5376  + currNameSpace->sGetName() + "::" + namebuf + "\"");
5377  }
5378  }
5379  }
5380  return logical();
5381 }
5382 
5385 {
5386  ExpressionElement * d = stmt();
5387  if (currtoken == STMTSEP) {
5388  GetToken();
5389  return d = new EE_StmtList(d, stmtlist());
5390  }
5391  //return new EE_StmtList(NULL , d);
5392  return d;
5393 }
5394 
5397 {
5398  /*
5399  * parse plugin:
5400  * - arg[0]: nome plugin
5401  * - arg[1]: nome variabile
5402  * - arg[2]->arg[n]: dati da passare al costrutture
5403  */
5404  std::vector<char *> argv(1);
5405  char c, buf[1024];
5406  int argc = 0;
5407  unsigned int i = 0, in_quotes = 0;
5408 
5409  /*
5410  * inizializzo l'array degli argomenti
5411  */
5412  argv[0] = NULL;
5413 
5414  /*
5415  * parserizzo la stringa:
5416  * <plugin> ::= '[' <type> ',' <var_name> <list_of_args> ']'
5417  * <type> ::= <registered_type>
5418  * <var_name> ::= <legal_var_name>
5419  * <list_of_args> ::= ',' <arg> <list_of_args> | ''
5420  * <arg> ::= <legal_string> (no unescaped ']' or ','!)
5421  */
5422  while ((c = in->get()), !in->eof()) {
5423  switch (c) {
5424  case '\\':
5425  c = in->get();
5426  if (in_quotes) {
5427  switch (c) {
5428  case 'n':
5429  c = '\n';
5430  break;
5431 
5432  default:
5433  in->putback(c);
5434  c = '\\';
5435  break;
5436  }
5437  }
5438  buf[i++] = c;
5439  break;
5440 
5441  case '"':
5442  if (in_quotes == 0) {
5443  in_quotes = 1;
5444  break;
5445  }
5446  in_quotes = 0;
5447  while (isspace((c = in->get()))) {
5448  NO_OP;
5449  }
5450  if (c != ',' && c != ']') {
5451  silent_cerr("need a separator "
5452  "after closing quotes" << std::endl);
5454  }
5455  in->putback(c);
5456  break;
5457 
5458  case ',':
5459  case ']':
5460  if (in_quotes) {
5461  buf[i++] = c;
5462  break;
5463  }
5464  buf[i] = '\0';
5465  argv.resize(argc + 2);
5466  trim_arg(buf);
5467  SAFESTRDUP(argv[argc], buf);
5468  ++argc;
5469  argv[argc] = NULL;
5470  if (c == ']') {
5471  goto last_arg;
5472  }
5473  i = 0;
5474  break;
5475 
5476  default:
5477  buf[i++] = c;
5478  break;
5479  }
5480 
5481  /*
5482  * FIXME: rendere dinamico il buffer ...
5483  */
5484  if (i >= sizeof(buf)) {
5485  silent_cerr("MathParser::readplugin(): buffer overflow" << std::endl);
5487  }
5488  }
5489 
5490 last_arg:
5491  if (in->eof()) {
5492  silent_cerr("eof encountered while parsing plugin"
5493  << std::endl);
5495  }
5496 
5497  /*
5498  * put the close plugin token back
5499  */
5500  in->putback(c);
5501  buf[i] = '\0';
5502 
5503  /*
5504  * argomenti comuni a tutti i plugin
5505  */
5506  char *pginname = argv[0];
5507  char *varname = argv[1];
5508  trim_arg(pginname);
5509  trim_arg(varname);
5510 
5511  /*
5512  * verifiche di validita' argomenti
5513  */
5514  if (pginname == NULL || *pginname == '\0') {
5515  silent_cerr("illegal or missing plugin name" << std::endl);
5517  }
5518 
5519  if (varname == NULL || *varname == '\0') {
5520  silent_cerr("illegal or missing plugin variable name"
5521  << std::endl);
5523  }
5524 
5525  /*
5526  * verifica esistenza nome
5527  */
5528  NamedValue* v = table.Get(varname);
5529  if (v != NULL) {
5530  silent_cerr("variable \"" << varname << "\" already defined"
5531  << std::endl);
5533  }
5534 
5535  /*
5536  * ricerca registrazione plugin
5537  */
5538  struct PlugInRegister *p = 0;
5539  for (p = PlugIns; p != 0; p = p->next) {
5540  if (strcasecmp(p->name, pginname) == 0) {
5541  break;
5542  }
5543  }
5544 
5545  if (p == 0) {
5546  silent_cerr(" plugin '" << pginname << "' not supported" << std::endl);
5548  }
5549 
5550 #ifdef DEBUG
5551  for (int i = 0; argv[i] != NULL; i++) {
5552  silent_cout("argv[" << i << "]=" << argv[i]
5553  << std::endl);
5554  }
5555 #endif /* DEBUG */
5556 
5557  /*
5558  * costruisce il plugin e gli fa interpretare gli argomenti
5559  */
5560  MathParser::PlugIn *pgin = (*p->constructor)(*this, p->arg);
5561  pgin->Read(argc - 2, &argv[2]);
5562 
5563  /*
5564  * riporta il parser nello stato corretto
5565  */
5566  GetToken();
5567 
5568  /*
5569  * costruisce la variabile, la inserisce nella tabella
5570  * e ne ritorna il valore (prima esecuzione)
5571  */
5572  SAFENEWWITHCONSTRUCTOR(v, PlugInVar,
5573  PlugInVar(varname, pgin));
5574  table.Put(v);
5575 
5576  /*
5577  * pulizia ...
5578  */
5579  for (int i = 0; argv[i] != NULL; i++) {
5580  SAFEDELETEARR(argv[i]);
5581  }
5582 
5583  return new EE_Var(v, defaultNameSpace);
5584 }
5585 
5586 #endif // USE_EE
GradientExpression< UnaryExpr< FuncTanh, Expr > > tanh(const GradientExpression< Expr > &u)
Definition: gradient.h:2982
void trim_arg(char *const s)
Definition: mathp.cc:1865
TypedValue::Type GetType(void) const
Definition: mathp.cc:1805
MathArgPriv_t< Real, AT_REAL > MathArgReal_t
Definition: mathp.h:155
TypedValue stmtlist(void)
Definition: mathp.cc:4253
virtual Table * GetTable(void)
Definition: mathp.cc:2885
const char * name
Definition: mathp.cc:846
TypedValue logical(void)
Definition: mathp.cc:3310
static int mp_in(const MathParser::MathArgs &args)
Definition: mathp.cc:721
TypedValue relational_int(TypedValue d)
Definition: mathp.cc:3362
TypedValue operator+(const TypedValue &v) const
Definition: mathp.cc:1444
static int mp_cast(const MathParser::MathArgs &args)
Definition: mathp.cc:787
NameSpace(const std::string &name)
Definition: mathp.cc:1989
bool IsVar(void) const
Definition: mathp.cc:1799
InputStream * in
Definition: mathp.h:295
MathParser(const MathParser &)
#define M_PI
Definition: gradienttest.cc:67
std::map< std::string, NameSpace * > NameSpaceMap
Definition: mathp.h:351
static const char ONE_LINE_REMARK
Definition: mathp.h:188
static int mp_step(const MathParser::MathArgs &args)
Definition: mathp.cc:606
Real Get(Real d=0.)
Definition: mathp.cc:4496
Definition: mathtyp.h:175
Real GetReal(void) const
Definition: mathp.cc:1228
GradientExpression< BinaryExpr< FuncPow, LhsExpr, RhsExpr > > pow(const GradientExpression< LhsExpr > &u, const GradientExpression< RhsExpr > &v)
Definition: gradient.h:2961
bool IsKeyWord(NameSpace *ns, const char *const s) const
Definition: mathp.cc:2945
std::string namebuf
Definition: mathp.h:358
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
static int mp_ramp(const MathParser::MathArgs &args)
Definition: mathp.cc:633
const TypedValue & operator-=(const TypedValue &v)
Definition: mathp.cc:1580
#define DEBUGCOUTFNAME(fname)
Definition: myassert.h:256
TypedValue::Type GetType(void) const
Definition: mathp.cc:1155
NamedValue * InsertSym(const char *const s, const Real &v, int redefine=0)
Definition: mathp.cc:4315
virtual TypedValue::Type GetType(void) const =0
bool Const(void) const
Definition: mathp.cc:1811
Var * Put(const std::string &name, const TypedValue &v)
Definition: table.cc:110
static int mp_greater_than_or_equal_to_0_t(const MathParser::MathArgs &args)
Definition: mathp.cc:205
#define MBDYN_EXCEPT_ARGS_PASSTHRU
Definition: except.h:55
const TypedValue & Set(const bool &b)
Definition: mathp.cc:1285
TypedValue::Type type
Definition: mathtyp.h:86
bool IsDeclarationModifier(const char *const s) const
Definition: mathp.cc:2939
static int mp_acosh_t(const MathParser::MathArgs &args)
Definition: mathp.cc:156
bool MayChange(void) const
Definition: mathp.cc:1910
int RegisterNameSpace(NameSpace *ns)
Definition: mathp.cc:4602
~TypedValue(void)
Definition: mathp.cc:880
virtual TypedValue GetVal(void) const =0
static int mp_actg2(const MathParser::MathArgs &args)
Definition: mathp.cc:456
std::vector< MathArg_t * > MathArgs
Definition: mathp.h:158
static int mp_sign(const MathParser::MathArgs &args)
Definition: mathp.cc:515
TypedValue & operator=(const TypedValue &var)
Definition: mathp.cc:961
TypedValue binary_int(TypedValue d)
Definition: mathp.cc:3415
const char * what(void) const
Definition: except.cc:54
const char * name
Definition: mathp.cc:832
Int i
Definition: mathtyp.h:89
static int mp_srnd(const MathParser::MathArgs &args)
Definition: mathp.cc:249
static int mp_greater_than_0_t(const MathParser::MathArgs &args)
Definition: mathp.cc:189
#define SAFEDELETEARR(pnt)
Definition: mynewmem.h:713
bool operator>(const TypedValue &v) const
Definition: mathp.cc:1408
std::string errmsg
Definition: mathp.h:172
~Var(void)
Definition: mathp.cc:1793
static const declarationmodifiernames DeclarationModifierNames[]
Definition: mathp.cc:860
bool operator!(const TypedValue &v)
Definition: mathp.cc:1657
DeclarationModifier
Definition: mathp.h:340
std::ostream & operator<<(std::ostream &out, const MathParser::MathArgVoid_t &)
Definition: mathp.cc:314
union TypedValue::@14 v
bool IsTypeModifier(const char *const s) const
Definition: mathp.cc:2933
TypedValue m_v
Definition: mathp.h:368
void GetForever(std::ostream &out, const char *const sep="\n")
Definition: mathp.cc:4565
#define DEBUGCERR(msg)
Definition: myassert.h:235
TypedValue mult(void)
Definition: mathp.cc:3436
#define MBDYN_EXCEPT_ARGS_NOOPT_PASSTHRU
Definition: except.h:53
static int mp_rand(const MathParser::MathArgs &args)
Definition: mathp.cc:221
virtual TypedValue Eval(void) const =0
TypedValue::Type type
Definition: mathp.cc:833
#define NO_OP
Definition: myassert.h:74
char get(void)
Definition: input.h:99
MathParser::PlugIn *(* constructor)(MathParser &, void *)
Definition: mathp.h:270
MathArgPriv_t< bool, AT_BOOL > MathArgBool_t
Definition: mathp.h:153
TypedValue & Cast(const TypedValue &var, bool bErr=false)
Definition: mathp.cc:1032
const TypedValue & operator*=(const TypedValue &v)
Definition: mathp.cc:1598
bool operator<(const TypedValue &v) const
Definition: mathp.cc:1432
const char *const GetTypeName(void) const
Definition: mathp.cc:1176
GradientExpression< UnaryExpr< FuncFabs, Expr > > fabs(const GradientExpression< Expr > &u)
Definition: gradient.h:2973
const char * name
Definition: mathp.h:269
static int mp_ctgh(const MathParser::MathArgs &args)
Definition: mathp.cc:481
int Int
Definition: mathtyp.h:40
StaticNameSpace(Table *pTable=0)
Definition: mathp.cc:2008
static int mp_rndm(const MathParser::MathArgs &args)
Definition: mathp.cc:235
TypedValue operator/(const TypedValue &v) const
Definition: mathp.cc:1504
static int mp_actg(const MathParser::MathArgs &args)
Definition: mathp.cc:438
MathParser::MathFunc_t * GetFunc(const std::string &fname) const
Definition: mathp.cc:2847
TypedValue::Type GetType(void) const
Definition: mathp.cc:1898
void Cast(const TypedValue &v, bool bErr=false)
Definition: mathp.cc:1859
TypedValue power_int(TypedValue d)
Definition: mathp.cc:3497
static const typemodifiernames TypeModifierNames[]
Definition: mathp.cc:850
static int mp_atanh_t(const MathParser::MathArgs &args)
Definition: mathp.cc:172
TypedValue(void)
Definition: mathp.cc:874
enum Token GetToken(void)
Definition: mathp.cc:2960
unsigned long int GetLineNumber(void) const
Definition: input.h:132
bool IsType(const char *const s) const
Definition: mathp.cc:2927
bool Const(void) const
Definition: mathp.cc:1904
void AllocName(const char *const s)
Definition: mathp.cc:1738
TypedValue stmt(void)
Definition: mathp.cc:3781
void func(const T &u, const T &v, const T &w, doublereal e, T &f)
TypedValue GetVal(void) const
Definition: mathp.cc:1823
const std::istream & GetStream(void) const
Definition: input.h:146
MathArgPriv_t< TypedValue, AT_ANY > MathArgAny_t
Definition: mathp.h:152
static int mp_tan_t(const MathParser::MathArgs &args)
Definition: mathp.cc:137
ErrWrongType(const char *file, int line, const char *func, const std::string r=std::string())
Definition: mathtyp.h:70
bool bRedefineVars
Definition: mathp.h:288
double(* mp_f2_f)(double, double)
Definition: mathp.cc:56
static const TypeName_t TypeNames[]
Definition: mathp.cc:836
MathFunc_f f
Definition: mathp.h:170
MathFuncTest_f t
Definition: mathp.h:171
static int mp_sprintf(const MathParser::MathArgs &args)
Definition: mathp.cc:264
virtual MathParser::MathFunc_t * GetFunc(const std::string &fname) const =0
static int mp_ctgh_t(const MathParser::MathArgs &args)
Definition: mathp.cc:499
struct PlugInRegister * next
Definition: mathp.h:272
enum Token currtoken
Definition: mathp.h:364
const char * name
Definition: mathp.cc:856
static bool IsFlag(EEFlags f)
Definition: evaluator.h:66
bool operator<=(const TypedValue &v) const
Definition: mathp.cc:1426
Definition: mathp.cc:713
Definition: mathp.cc:716
virtual ~NamedValue(void)
Definition: mathp.cc:1731
virtual TypedValue EvalFunc(MathParser::MathFunc_t *f) const
Definition: mathp.cc:2859
TypedValue binary(void)
Definition: mathp.cc:3403
#define SAFENEW(pnt, item)
Definition: mynewmem.h:695
#define MBDYN_EXCEPT_ARGS_DECL_NODEF
Definition: except.h:49
virtual std::ostream & Output(std::ostream &out) const =0
virtual bool MayChange(void) const =0
StaticNameSpace * defaultNameSpace
Definition: mathp.h:348
Definition: mathp.cc:715
TypedValue operator-(const TypedValue &v)
Definition: mathp.cc:1667
TypedValue::TypeModifier GetTypeModifier(const char *const s) const
Definition: mathp.cc:2903
static int mp_min(const MathParser::MathArgs &args)
Definition: mathp.cc:562
InputStream & putback(char ch)
Definition: input.h:121
Definition: mbdyn.h:76
static int mp_stop(const MathParser::MathArgs &args)
Definition: mathp.cc:373
MathParser::DeclarationModifier type
Definition: mathp.cc:857
NamedValue(const char *const s)
Definition: mathp.cc:1725
doublereal copysign(doublereal x, doublereal y)
Definition: gradient.h:97
virtual const std::string & sGetName(void) const
Definition: mathp.cc:2001
PlugInVar(const char *const s, MathParser::PlugIn *p)
Definition: mathp.cc:1884
Definition: mathp.cc:714
static int mp_acos_t(const MathParser::MathArgs &args)
Definition: mathp.cc:120
TypedValue power(void)
Definition: mathp.cc:3485
const NameSpaceMap & GetNameSpaceMap(void) const
Definition: mathp.cc:1984
Var(const char *const s, const TypedValue &v)
Definition: mathp.cc:1763
char * name
Definition: mathtyp.h:154
TypedValue evalfunc(MathParser::NameSpace *ns, MathParser::MathFunc_t *f)
Definition: mathp.cc:3576
bool bNameValidate(const std::string &s) const
Definition: mathp.cc:3292
double(* mp_f1_f)(double)
Definition: mathp.cc:55
static int mp_sramp(const MathParser::MathArgs &args)
Definition: mathp.cc:657
TypedValue readplugin(void)
Definition: mathp.cc:4063
const std::string & GetString(void) const
Definition: mathp.cc:1247
static int mp_func_1(const MathParser::MathArgs &args)
Definition: mathp.cc:60
bool bConst
Definition: mathtyp.h:87
TypedValue value
Definition: mathtyp.h:177
int TokenPop(void)
Definition: mathp.cc:1963
#define ASSERT(expression)
Definition: colamd.c:977
~MathParser(void)
Definition: mathp.cc:4385
virtual ~NameSpace(void)
Definition: mathp.cc:1995
TypedValue operator%(const TypedValue &v) const
Definition: mathp.cc:1517
virtual TypedValue EvalFunc(MathParser::MathFunc_t *f) const =0
mp_in_e
Definition: mathp.cc:712
const TypedValue & operator+=(const TypedValue &v)
Definition: mathp.cc:1534
bool operator>=(const TypedValue &v) const
Definition: mathp.cc:1414
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
Definition: mynewmem.h:698
bool operator||(const TypedValue &v) const
Definition: mathp.cc:1402
MathArgPriv_t< std::string, AT_STRING > MathArgString_t
Definition: mathp.h:156
TypedValue unary(void)
Definition: mathp.cc:3555
static int mp_ctg_t(const MathParser::MathArgs &args)
Definition: mathp.cc:419
Definition: except.h:79
int GetLineNumber(void) const
Definition: mathp.cc:1943
TypedValue operator+(const TypedValue &v)
Definition: mathp.cc:1689
bool operator!=(const TypedValue &v) const
Definition: mathp.cc:1438
TypedValue operator*(const TypedValue &v) const
Definition: mathp.cc:1491
static std::stack< cleanup * > c
Definition: cleanup.cc:59
TypedValue::TypeModifier type
Definition: mathp.cc:847
static int mp_asin_t(const MathParser::MathArgs &args)
Definition: mathp.cc:103
NameSpace * GetNameSpace(const std::string &name) const
Definition: mathp.cc:4620
void TokenPush(enum Token t)
Definition: mathp.cc:1950
virtual bool Const(void) const =0
virtual bool IsFunc(const std::string &fname) const =0
NameSpace * ns
Definition: mathp.h:168
TypedValue expr(void)
Definition: mathp.cc:3691
NamedValue * Get(const std::string &name) const
Definition: table.cc:150
bool operator&&(const TypedValue &v) const
Definition: mathp.cc:1396
Real GetLastStmt(Real d=0., Token t=ARGSEP)
Definition: mathp.cc:4402
#define SAFESTRDUP(pnt, src)
Definition: mynewmem.h:707
bool IsFunc(const std::string &fname) const
Definition: mathp.cc:2831
TypedValue logical_int(TypedValue d)
Definition: mathp.cc:3322
HighParser::ErrOut mbdyn_get_line_data(void)
Definition: parser.cc:603
TypedValue operator-(const TypedValue &v) const
Definition: mathp.cc:1478
std::string s
Definition: mathtyp.h:92
Real r
Definition: mathtyp.h:90
Definition: table.h:43
static const doublereal a
Definition: hfluid_.h:289
void PutSymbolTable(Table &T)
Definition: mathp.cc:1937
virtual Table * GetTable(void)=0
static bool sns
Definition: mathp.cc:2006
virtual const char *const GetTypeName(void) const
Definition: mathp.cc:1758
TypedValue value
Definition: mathp.h:361
void SetConst(bool isConst=true, bool bForce=false)
Definition: mathp.cc:1275
bool operator==(const TypedValue &v) const
Definition: mathp.cc:1420
#define MBDYN_EXCEPT_ARGS_DECL_NOOPT
Definition: except.h:41
TypedValue relational(void)
Definition: mathp.cc:3350
static doublereal buf[BUFSIZE]
Definition: discctrl.cc:333
TypedValue mult_int(TypedValue d)
Definition: mathp.cc:3448
MathArgPriv_t< Int, AT_INT > MathArgInt_t
Definition: mathp.h:154
const char * GetName(void) const
Definition: mathp.cc:1751
std::stack< TokenVal > TokenStack
Definition: mathp.h:370
virtual int Read(int argc, char *argv[])=0
static int mp_ctg(const MathParser::MathArgs &args)
Definition: mathp.cc:401
GradientExpression< BinaryExpr< FuncAtan2, LhsExpr, RhsExpr > > atan2(const GradientExpression< LhsExpr > &u, const GradientExpression< RhsExpr > &v)
Definition: gradient.h:2962
Int GetInt(void) const
Definition: mathp.cc:1209
MathParser::DeclarationModifier GetDeclarationModifier(const char *const s) const
Definition: mathp.cc:2915
static int mp_max(const MathParser::MathArgs &args)
Definition: mathp.cc:538
TypedValue::Type GetType(const char *const s) const
Definition: mathp.cc:2891
int RegisterPlugIn(const char *name, MathParser::PlugIn *(*)(MathParser &, void *), void *arg)
Definition: mathp.cc:4584
NameSpaceMap nameSpaceMap
Definition: mathp.h:355
void SetVal(const bool &b)
Definition: mathp.cc:1829
static int mp_func_2(const MathParser::MathArgs &args)
Definition: mathp.cc:79
bool GetBool(void) const
Definition: mathp.cc:1188
double Real
Definition: mathtyp.h:39
Table & GetSymbolTable(void) const
Definition: mathp.cc:1931
GradientExpression< UnaryExpr< FuncTan, Expr > > tan(const GradientExpression< Expr > &u)
Definition: gradient.h:2979
Table & table
Definition: mathp.h:287
const TypedValue & operator%=(const TypedValue &v)
Definition: mathp.cc:1634
bool Const(void) const
Definition: mathp.cc:1182
static int mp_par(const MathParser::MathArgs &args)
Definition: mathp.cc:689
virtual bool IsVar(void) const
Definition: mathp.cc:1745
static int mp_print(const MathParser::MathArgs &args)
Definition: mathp.cc:344
ErrGeneric(const char *file, int line, const char *func, const std::string r=std::string())
Definition: mathp.cc:1921
bool eof(void) const
Definition: input.h:139
std::string fname
Definition: mathp.h:167
bool MayChange(void) const
Definition: mathp.cc:1817
void SetType(TypedValue::Type t, bool isConst=false)
Definition: mathp.cc:1264
TypedValue GetVal(void) const
Definition: mathp.cc:1916
#define SAFEDELETE(pnt)
Definition: mynewmem.h:710
const TypedValue & operator/=(const TypedValue &v)
Definition: mathp.cc:1616
struct MathParser::PlugInRegister * PlugIns
TypeModifier
Definition: mathtyp.h:56