macro processor: support @#echomacrovars with symbol_list

closes #26
issue#70
Houtan Bastani 2019-08-26 18:12:04 +02:00
parent 2b3519e3b0
commit 3a21eda40e
No known key found for this signature in database
GPG Key ID: 000094FB955BE169
6 changed files with 75 additions and 33 deletions

View File

@ -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}

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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)
{
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;
}
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, line, save);
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)
{
get<0>(function)->printName(output);
output << " = '";
}
get<0>(function)->print(output);
output << " = ";
get<1>(function)->print(output);
if (save)
output << "';";
output << endl;
}

View File

@ -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(); }
};

View File

@ -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