diff --git a/doc/macroprocessor/macroprocessor.tex b/doc/macroprocessor/macroprocessor.tex index 4d26aa165780b430ca2fce86a0e674c8d05fa0d0..ed8bab86c2e93c674d28ab8049e85d8de00596c1 100644 --- a/doc/macroprocessor/macroprocessor.tex +++ b/doc/macroprocessor/macroprocessor.tex @@ -530,13 +530,17 @@ There is also \verb+@#ifndef+, which is the opposite of \verb+@#ifdef+ \begin{itemize} \item The echo directive will simply display a message on standard output \item The error directive will display the message and make Dynare stop (only makes sense inside a conditional directive) - \item The echomacrovars directive will display all of the macro variables and their values + \item The echomacrovars directive will display all of the macro variables (or + those specified) and their values, optionally saving them \end{itemize} \begin{block}{Syntax} \verb+@#echo +\textit{string\_expr} \\ \verb+@#error +\textit{string\_expr} \\ -\verb+@#echomacrovars + +\verb+@#echomacrovars +\\ +\verb+@#echomacrovars +\textit{list\_of\_variables}\\ +\verb+@#echomacrovars (save)+\\ +\verb+@#echomacrovars (save)+\textit{list\_of\_variables}\\ \end{block} \begin{block}{Examples} diff --git a/src/macro/Directives.cc b/src/macro/Directives.cc index f2f679262ef1d8530f5bc85e752282b5576579b4..e1207a28ab743d9761cb88e1fed0fd581cf80520 100644 --- a/src/macro/Directives.cc +++ b/src/macro/Directives.cc @@ -147,9 +147,9 @@ void EchoMacroVars::interpret(ostream &output, bool no_line_macro) { if (save) - env.print(output, location.begin.line, true); + env.print(output, vars, location.begin.line, true); else - env.print(cout); + env.print(cout, vars); printEndLineInfo(output, no_line_macro); } diff --git a/src/macro/Directives.hh b/src/macro/Directives.hh index 1c1409e5f55b7b3cabe39d68711e29cecd282209..09f34339da7e9f0b0916f14912e68f64e8d45d7e 100644 --- a/src/macro/Directives.hh +++ b/src/macro/Directives.hh @@ -145,10 +145,14 @@ namespace macro { private: const bool save; + const vector<string> vars; public: EchoMacroVars(bool save_arg, Environment &env_arg, Tokenizer::location location_arg) : Directive(env_arg, move(location_arg)), save{save_arg} { } + EchoMacroVars(bool save_arg, vector<string> vars_arg, + Environment &env_arg, Tokenizer::location location_arg) : + Directive(env_arg, move(location_arg)), save{save_arg}, vars{move(vars_arg)} { } void interpret(ostream &output, bool no_line_macro) override; }; diff --git a/src/macro/Environment.cc b/src/macro/Environment.cc index fcb8aa5c3de128d221ac24d5c6c9fcf99d6eef91..17e3f75673815583c2ed256e2cbc00b387c60259 100644 --- a/src/macro/Environment.cc +++ b/src/macro/Environment.cc @@ -101,42 +101,60 @@ Environment::isFunctionDefined(const string &name) const noexcept } void -Environment::print(ostream &output, int line, bool save) const +Environment::print(ostream &output, const vector<string> &vars, int line, bool save) const { if (!save && !variables.empty()) output << "Macro Variables:" << endl; - for (auto & it : variables) - { - output << (save ? "options_.macrovars_line_" + to_string(line) + "." : " " ); - output << it.first << " = "; - getVariable(it.first)->eval()->print(output, save); - if (save) - output << ";"; - output << endl; - } + if (vars.empty()) + for (auto & it : variables) + printVariable(output, it.first, line, save); + else + for (const auto & it : vars) + if (isVariableDefined(it)) + printVariable(output, it, line, save); if (!save && !functions.empty()) output << "Macro Functions:" << endl; - for (auto & it : functions) + if (vars.empty()) + for (const auto & it : functions) + printFunction(output, it.second, line, save); + else + for (const auto & it : vars) + if (isFunctionDefined(it)) + printFunction(output, functions.find(it)->second, line, save); + + if (parent) + parent->print(output, vars, line, save); +} + +void +Environment::printVariable(ostream &output, const string & name, int line, bool save) const +{ + output << (save ? "options_.macrovars_line_" + to_string(line) + "." : " " ); + output << name << " = "; + getVariable(name)->eval()->print(output, save); + if (save) + output << ";"; + output << endl; +} + +void +Environment::printFunction(ostream &output, const tuple<FunctionPtr, ExpressionPtr> & function, int line, bool save) const +{ + output << (save ? "options_.macrovars_line_" + to_string(line) + ".function." : " " ); + if (save) { - output << (save ? "options_.macrovars_line_" + to_string(line) + ".function." : " " ); - if (save) - { - get<0>(it.second)->printName(output); - output << " = '"; - } - - get<0>(it.second)->print(output); - output << " = "; - get<1>(it.second)->print(output); - - if (save) - output << "';"; - output << endl; + get<0>(function)->printName(output); + output << " = '"; } - if (parent) - parent->print(output, line, save); + get<0>(function)->print(output); + output << " = "; + get<1>(function)->print(output); + + if (save) + output << "';"; + output << endl; } diff --git a/src/macro/Environment.hh b/src/macro/Environment.hh index 905905ff1e0fab83aa0a2202bc60b5df06391823..c37d7c61154c81cc91f0dba2d0de05d79f13126e 100644 --- a/src/macro/Environment.hh +++ b/src/macro/Environment.hh @@ -43,7 +43,9 @@ namespace macro bool isVariableDefined(const string &name) const noexcept; bool isFunctionDefined(const string &name) const noexcept; inline bool isSymbolDefined(const string &name) const noexcept { return isVariableDefined(name) || isFunctionDefined(name); } - void print(ostream &output, int line = -1, bool save = false) const; + void print(ostream &output, const vector<string> &vars, int line = -1, bool save = false) const; + void printVariable(ostream &output, const string & name, int line, bool save) const; + void printFunction(ostream &output, const tuple<FunctionPtr, ExpressionPtr> & function, int line, bool save) const; inline size_t size() const noexcept { return variables.size() + functions.size(); } inline const Environment *getGlobalEnv() const noexcept { return parent == nullptr ? this : parent->getGlobalEnv(); } }; diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy index b46cea4bacf15ab09b62c7ca3dfd57d4ad4c29bc..b84009af4dd727985b8ee7d869efdadddfb68b63 100644 --- a/src/macro/Parser.yy +++ b/src/macro/Parser.yy @@ -100,6 +100,7 @@ using namespace macro; %type <VariablePtr> symbol %type <vector<ExpressionPtr>> comma_expr function_args tuple_comma_expr +%type <vector<string>> name_list %% @@ -138,10 +139,23 @@ directive_one_line : INCLUDE expr { $$ = make_shared<Error>($2, driver.env, @$); } | ECHOMACROVARS { $$ = make_shared<EchoMacroVars>(false, driver.env, @$); } + | ECHOMACROVARS name_list + { $$ = make_shared<EchoMacroVars>(false, $2, driver.env, @$); } | ECHOMACROVARS LPAREN SAVE RPAREN { $$ = make_shared<EchoMacroVars>(true, driver.env, @$); } + | ECHOMACROVARS LPAREN SAVE RPAREN name_list + { $$ = make_shared<EchoMacroVars>(true, $5, driver.env, @$); } ; +name_list : NAME + { $$ = vector<string>{$1}; } + | name_list NAME + { + $1.emplace_back($2); + $$ = $1; + } + ; + directive_multiline : for | if | ifdef