Verified Commit 3a21eda4 authored by Houtan Bastani's avatar Houtan Bastani
Browse files

macro processor: support @#echomacrovars with symbol_list

closes #26
parent 2b3519e3
Pipeline #1649 failed with stage
in 17 seconds
......@@ -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}
......
......@@ -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);
}
......
......@@ -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;
};
......
......@@ -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;
}
......@@ -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(); }
};
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment