Before this commit, a dynare call such as
```
dynare <<mod file>> -Db=“A” -Da=@{b}
```
would not expand the value of `b` in `a` whereas
```
dynare <<mod file>> -Da=“A” -Db=@{a}
```
would expand the value of `a` into `b` because the arguments were stored in a map which printed the `@#define` statements in the .mod file in alphabetic order.
In particular, no need to put both upper and lower case letters in the
patterns, since the lexer is case-insensitive.
The only simplification that we do not perform is removing the quoting of
single quotes (i.e. replacing \' by '), since it confuses the C++ mode of
Emacs.
This feature is ill-designed and no longer needed by the GUI. And is not very
useful: it is not possible to interact with the preprocessor without using the
filesystem, since the preprocessor creates many files anyways.
If we really need to reimplement such a feature, it should rather be redesigned
by reading the modfile from standard input (cin). That could be triggered by
using "-" as the filename argument (as is already done by several standard Unix
utilities).
Due to a limitation of the current implementation, this breaks syntaxes like
[ (i,j) ] (but not [ (2,j) ]; the problem only occurs when an array is
constructed by specifying as first element a tuple whose first element is a
variable name). Solving this problem requires an overhaul of the
macro-processor, with construction of ASTs at parsing time, and evaluation
later on (instead of doing on-the-fly evaluation).
Ref #5
- == and != have now lower priority than <= < >= >, for consistency with the
Dynare modelling language (and incidentally C and C++, but not Julia).
- ^ has now higher priority and no associativity, for consistency with the
Dynare modelling language (and usual arithmetic notation).
- & has now higher priority than |, and both have lower priority than + and -,
but higher than inequality comparators. This is not the same as C and C++ (in
which & and | are just above && and ||), but this allows for expressions such
as "a|b == c" to have their most natural semantics (i.e. this will compare
the union of a and b with c; the C/C++ priority level would have resulted in
a type error).
Ref #5.
- use std::unique_ptr for MacroDriver::lexer
- use std::shared_ptr for MacroValue objects constructed by the parser
This is made possible using Bison 3.0 variant value type.
Using non-pointer type is not possible since MacroValue is polymorphic.
Using std::unique_ptr is not possible since the value type must be
copyable (see
https://lists.gnu.org/archive/html/bug-bison/2015-03/msg00004.html).
Define a new type MacroValuePtr == shared_ptr<const MacroValue> for code
clarity.
Use the following convention for shared_ptr arguments to functions:
+ if pass-by-value, means that the callee acquires ownership
+ if pass-by-const-reference, the callee does not acquire ownership
- naked pointers are still used for tracking the filename in Bison's location
type, since we don't have control over that
Also, by the way:
- arrays can now contain elements of any type
- simplify MacroDriver::loop_stack using std::tuple
- toArray() method now fails on function objects
- no need to use const qualifiers, since all MacroValue objects are immutable
- use an exception for detecting division by zero
Most cases can be handled in C++11 by std::stoi() and std::stod().
For the macroprocessor ArrayMV<T>::print() method, use template
specialization (instead of a lexical_cast to detect between T=int and
T=string).
Those were treated as comments.
Incidentally, fix a similar issue in the Dynare parser (which is much less
problematic, since double quotes are not used in the Dynare language).
ClosesDynareTeam/dynare#1621