Merge branch 'master' into ecb-master

# Conflicts:
#	examples/NK_baseline_steadystate.m
#	matlab/backward/backward_model_irf.m
#	matlab/modules/dseries
#	matlab/occbin/setss.m
#	preprocessor/SymbolList.cc
#	tests/identification/as2007/as2007_steadystate.m
#	tests/identification/kim/kim2_steadystate.m
#	tests/particle/dsge_base2_steadystate.m
#	tests/steady_state/walsh1_old_ss_steadystate.m
issue#70
Houtan Bastani 2018-01-11 16:25:42 +01:00
commit 3da0186774
17 changed files with 240 additions and 128 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2017 Dynare Team
* Copyright (C) 2003-2018 Dynare Team
*
* This file is part of Dynare.
*
@ -852,15 +852,15 @@ RamseyPolicyStatement::writeOutput(ostream &output, const string &basename, bool
output << "options_.k_order_solver = 1;" << endl;
options_list.writeOutput(output);
output << "var_list_ = char(";
output << "var_list_ = {";
for (vector<string>::const_iterator it = ramsey_policy_list.begin();
it != ramsey_policy_list.end(); ++it)
{
if (it != ramsey_policy_list.begin())
output << ",";
output << ";";
output << "'" << *it << "'";
}
output << ");" << endl
output << "};" << endl
<< "ramsey_policy(var_list_);" << endl;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2017 Dynare Team
* Copyright (C) 2003-2018 Dynare Team
*
* This file is part of Dynare.
*
@ -1773,21 +1773,38 @@ DynamicModel::reform(const string name1) const
}
void
DynamicModel::getNonZeroHessianEquations(map<int, string> &eqs) const
DynamicModel::printNonZeroHessianEquations(ostream &output) const
{
if (nonzero_hessian_eqs.size() != 1)
output << "[";
for (map<int, string>::const_iterator it = nonzero_hessian_eqs.begin();
it != nonzero_hessian_eqs.end(); it++)
{
if (it != nonzero_hessian_eqs.begin())
output << " ";
output << it->first;
}
if (nonzero_hessian_eqs.size() != 1)
output << "]";
}
void
DynamicModel::setNonZeroHessianEquations(map<int, string> &eqs)
{
for (second_derivatives_t::const_iterator it = second_derivatives.begin();
it != second_derivatives.end(); it++)
if (eqs.find(it->first.first) == eqs.end())
if (nonzero_hessian_eqs.find(it->first.first) == nonzero_hessian_eqs.end())
{
eqs[it->first.first] = "";
nonzero_hessian_eqs[it->first.first] = "";
for (size_t i = 0; i < equation_tags.size(); i++)
if (equation_tags[i].first == it->first.first)
if (equation_tags[i].second.first == "name")
{
eqs[it->first.first] = equation_tags[i].second.second;
nonzero_hessian_eqs[it->first.first] = equation_tags[i].second.second;
break;
}
}
eqs = nonzero_hessian_eqs;
}
void

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2017 Dynare Team
* Copyright (C) 2003-2018 Dynare Team
*
* This file is part of Dynare.
*
@ -80,6 +80,9 @@ private:
map<pair<int, int>, set<int> > xref_exo;
map<pair<int, int>, set<int> > xref_exo_det;
//! Nonzero equations in the Hessian
map<int, string> nonzero_hessian_eqs;
//! Number of columns of dynamic jacobian
/*! Set by computeDerivID()s and computeDynJacobianCols() */
int dynJacobianColsNbr;
@ -271,11 +274,11 @@ public:
void writeJsonXrefs(ostream &output) const;
void writeJsonXrefsHelper(ostream &output, const map<pair<int, int>, set<int> > &xrefs) const;
//! Return true if the hessian is equal to zero
inline bool checkHessianZero() const;
//! Print equations that have non-zero second derivatives
void printNonZeroHessianEquations(ostream &output) const;
//! Return equations that have non-zero second derivatives
void getNonZeroHessianEquations(map<int, string> &eqs) const;
//! Set the equations that have non-zero second derivatives
void setNonZeroHessianEquations(map<int, string> &eqs);
//! Set indices for var expectation in dynamic model file
void setVarExpectationIndices(map<string, pair<SymbolList, int> > var_model_info);
@ -569,12 +572,6 @@ public:
bool isChecksumMatching(const string &basename) const;
};
inline bool
DynamicModel::checkHessianZero() const
{
return second_derivatives.empty();
}
//! Classes to re-order derivatives for various sparse storage formats
class derivative
{

View File

@ -2789,6 +2789,7 @@ dynare_sensitivity_option : o_gsa_identification
| o_ar
| o_kalman_algo
| o_lik_init
| o_diffuse_filter
| o_analytic_derivation
| o_analytic_derivation_mode
;
@ -3360,16 +3361,16 @@ o_psd_fig_name : FIG_NAME EQUAL filename { driver.option_str("plot_shock_decomp.
o_psd_type : TYPE EQUAL QOQ
{ driver.option_str("plot_shock_decomp.type", "qoq"); }
| TYPE EQUAL YOY
{ driver.option_str("plot_shock_decomp.type", "qoq"); }
{ driver.option_str("plot_shock_decomp.type", "yoy"); }
| TYPE EQUAL AOA
{ driver.option_str("plot_shock_decomp.type", "qoq"); }
{ driver.option_str("plot_shock_decomp.type", "aoa"); }
;
o_icd_type : TYPE EQUAL QOQ
{ driver.option_str("initial_condition_decomp.type", "qoq"); }
| TYPE EQUAL YOY
{ driver.option_str("initial_condition_decomp.type", "qoq"); }
{ driver.option_str("initial_condition_decomp.type", "yoy"); }
| TYPE EQUAL AOA
{ driver.option_str("initial_condition_decomp.type", "qoq"); }
{ driver.option_str("initial_condition_decomp.type", "aoa"); }
;
o_icd_plot_init_date : PLOT_INIT_DATE EQUAL date_expr { driver.option_date("initial_condition_decomp.plot_init_date", $3); } ;
o_icd_plot_end_date : PLOT_END_DATE EQUAL date_expr { driver.option_date("initial_condition_decomp.plot_end_date", $3); } ;

View File

@ -50,12 +50,12 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool
);
void main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool save_macro, string &save_macro_file,
bool no_line_macro, map<string, string> &defines, vector<string> &path, stringstream &macro_output);
bool no_line_macro, bool no_empty_line_macro, map<string, string> &defines, vector<string> &path, stringstream &macro_output);
void
usage()
{
cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [onlyclearglobals] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [nolog] [warn_uninit]"
cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [onlyclearglobals] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [noemptylinemacro] [notmpterms] [nolog] [warn_uninit]"
<< " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test]"
<< " [-D<variable>[=<value>]] [-I/path] [nostrict] [stochastic] [fast] [minimal_workspace] [compute_xrefs] [output=dynamic|first|second|third] [language=C|C++|julia]"
<< " [params_derivs_order=0|1|2]"
@ -91,6 +91,7 @@ main(int argc, char **argv)
bool no_tmp_terms = false;
bool only_macro = false;
bool no_line_macro = false;
bool no_empty_line_macro = false;
bool no_log = false;
bool no_warn = false;
int params_derivs_order = 2;
@ -162,6 +163,8 @@ main(int argc, char **argv)
}
else if (!strcmp(argv[arg], "nolinemacro"))
no_line_macro = true;
else if (!strcmp(argv[arg], "noemptylinemacro"))
no_empty_line_macro = true;
else if (!strcmp(argv[arg], "notmpterms"))
no_tmp_terms = true;
else if (!strcmp(argv[arg], "nolog"))
@ -389,7 +392,8 @@ main(int argc, char **argv)
// Do macro processing
stringstream macro_output;
main1(modfile, basename, modfiletxt, debug, save_macro, save_macro_file, no_line_macro, defines, path, macro_output);
main1(modfile, basename, modfiletxt, debug, save_macro, save_macro_file, no_line_macro, no_empty_line_macro,
defines, path, macro_output);
if (only_macro)
return EXIT_SUCCESS;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Dynare Team
* Copyright (C) 2015-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -22,14 +22,18 @@
#include "macro/MacroDriver.hh"
bool compareNewline (int i, int j) {
return i == '\n' && j == '\n';
}
void
main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool save_macro, string &save_macro_file,
bool no_line_macro, map<string, string> &defines, vector<string> &path, stringstream &macro_output)
bool no_line_macro, bool no_empty_line_macro, map<string, string> &defines, vector<string> &path, stringstream &macro_output)
{
// Do macro processing
MacroDriver m;
m.parse(modfile, modfiletxt, macro_output, debug, no_line_macro, defines, path);
m.parse(modfile, basename, modfiletxt, macro_output, debug, no_line_macro, defines, path);
if (save_macro)
{
if (save_macro_file.empty())
@ -40,7 +44,11 @@ main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool sa
cerr << "Cannot open " << save_macro_file << " for macro output" << endl;
exit(EXIT_FAILURE);
}
macro_output_file << macro_output.str();
string str (macro_output.str());
if (no_empty_line_macro)
str.erase(unique(str.begin(), str.end(), compareNewline), str.end());
macro_output_file << str;
macro_output_file.close();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2017 Dynare Team
* Copyright (C) 2006-2018 Dynare Team
*
* This file is part of Dynare.
*
@ -615,15 +615,14 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_deri
else // No computing task requested, compute derivatives up to 2nd order by default
dynamic_model.computingPass(true, true, false, none, global_eval_context, no_tmp_terms, block, use_dll, byte_code, nopreprocessoroutput);
if ((linear && !mod_file_struct.ramsey_model_present && !dynamic_model.checkHessianZero())
|| (linear && mod_file_struct.ramsey_model_present && !orig_ramsey_dynamic_model.checkHessianZero()))
{
map<int, string> eqs;
if (mod_file_struct.ramsey_model_present)
orig_ramsey_dynamic_model.getNonZeroHessianEquations(eqs);
else
dynamic_model.getNonZeroHessianEquations(eqs);
map<int, string> eqs;
if (mod_file_struct.ramsey_model_present)
orig_ramsey_dynamic_model.setNonZeroHessianEquations(eqs);
else
dynamic_model.setNonZeroHessianEquations(eqs);
if (linear && !eqs.empty())
{
cerr << "ERROR: If the model is declared linear the second derivatives must be equal to zero." << endl
<< " The following equations had non-zero second derivatives:" << endl;
for (map<int, string >::const_iterator it = eqs.begin(); it != eqs.end(); it++)
@ -770,7 +769,13 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
mOutputFile << "};" << endl;
}
mOutputFile << "M_.hessian_eq_zero = " << dynamic_model.checkHessianZero() << ";" << endl;
mOutputFile << "M_.nonzero_hessian_eqs = ";
if (mod_file_struct.ramsey_model_present)
orig_ramsey_dynamic_model.printNonZeroHessianEquations(mOutputFile);
else
dynamic_model.printNonZeroHessianEquations(mOutputFile);
mOutputFile << ";" << endl
<< "M_.hessian_eq_zero = isempty(M_.nonzero_hessian_eqs);" << endl;
config_file.writeCluster(mOutputFile);

View File

@ -1453,35 +1453,31 @@ ModelTree::writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t
for (size_t i = 0; i < equations.size(); i++)
equations[i]->collectVariables(eModelLocalVariable, used_local_vars);
output << "\"external_functions_model_local_variables\": [";
for (set<int>::const_iterator it = used_local_vars.begin();
it != used_local_vars.end(); ++it)
{
vector<string> efout;
expr_t value = local_variables_table.find(*it)->second;
value->writeJsonExternalFunctionOutput(efout, tt, tef_terms);
for (vector<string>::const_iterator it1 = efout.begin(); it1 != efout.end(); it1++)
{
if (it1 != efout.begin())
output << ", ";
output << *it1;
}
}
output << "]"
<< ", \"model_local_variables\": [";
output << "\"model_local_variables\": [";
bool printed = false;
for (vector<int>::const_iterator it = local_variables_vector.begin();
it != local_variables_vector.end(); it++)
if (used_local_vars.find(*it) != used_local_vars.end())
{
int id = *it;
expr_t value = local_variables_table.find(id)->second;
if (printed)
output << ", ";
else
printed = true;
int id = *it;
vector<string> efout;
expr_t value = local_variables_table.find(id)->second;
value->writeJsonExternalFunctionOutput(efout, tt, tef_terms);
for (vector<string>::const_iterator it1 = efout.begin(); it1 != efout.end(); it1++)
{
if (it1 != efout.begin())
output << ", ";
output << *it1;
}
if (!efout.empty())
output << ", ";
/* We append underscores to avoid name clashes with "g1" or "oo_" (see
also VariableNode::writeOutput) */
output << "{\"variable\": \"" << symbol_table.getName(id) << "__\""

View File

@ -2580,8 +2580,7 @@ ParsingDriver::add_divide(expr_t arg1, expr_t arg2)
}
catch (DataTree::DivisionByZeroException)
{
cerr << "...division by zero error encountred when reading model from .mod file" << endl;
exit(EXIT_FAILURE);
error("Division by zero error encountered when reading model from .mod file");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2017 Dynare Team
* Copyright (C) 2003-2018 Dynare Team
*
* This file is part of Dynare.
*
@ -28,35 +28,15 @@ SymbolList::addSymbol(const string &symbol)
void
SymbolList::writeOutput(const string &varname, ostream &output) const
{
output << varname << " = ";
write(output);
output << ";" << endl;
}
void
SymbolList::write(ostream &output) const
{
output << " char(";
output << varname << " = {";
for (vector<string>::const_iterator it = symbols.begin();
it != symbols.end(); ++it)
{
if (it != symbols.begin())
output << ",";
output << ";";
output << "'" << *it << "'";
}
output << ")";
}
int
SymbolList::getSize() const
{
return symbols.size();
}
vector<string>
SymbolList::getSymbols() const
{
return symbols;
output << "};" << endl;
}
void
@ -78,3 +58,15 @@ SymbolList::clear()
{
symbols.clear();
}
int
SymbolList::getSize() const
{
return symbols.size();
}
vector<string>
SymbolList::getSymbols() const
{
return symbols;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2017 Dynare Team
* Copyright (C) 2003-2018 Dynare Team
*
* This file is part of Dynare.
*
@ -219,14 +219,13 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
if (exo_nbr() > 0)
{
output << "M_.exo_names = '" << getName(exo_ids[0]) << "';" << endl;
output << "M_.exo_names_tex = '" << getTeXName(exo_ids[0]) << "';" << endl;
output << "M_.exo_names_long = '" << getLongName(exo_ids[0]) << "';" << endl;
for (int id = 1; id < exo_nbr(); id++)
output << "M_.exo_names = char(M_.exo_names, '" << getName(exo_ids[id]) << "');" << endl
<< "M_.exo_names_tex = char(M_.exo_names_tex, '" << getTeXName(exo_ids[id]) << "');" << endl
<< "M_.exo_names_long = char(M_.exo_names_long, '" << getLongName(exo_ids[id]) << "');" << endl;
output << "M_.exo_names = cell(" << exo_nbr() << ",1);" << endl;
output << "M_.exo_names_tex = cell(" << exo_nbr() << ",1);" << endl;
output << "M_.exo_names_long = cell(" << exo_nbr() << ",1);" << endl;
for (int id = 0; id < exo_nbr(); id++)
output << "M_.exo_names(" << id+1 << ") = {'" << getName(exo_ids[id]) << "'};" << endl
<< "M_.exo_names_tex(" << id+1 << ") = {'" << getTeXName(exo_ids[id]) << "'};" << endl
<< "M_.exo_names_long(" << id+1 << ") = {'" << getLongName(exo_ids[id]) << "'};" << endl;
map<string, map<int, string> > partitions = getPartitionsForType(eExogenous);
for (map<string, map<int, string> >::const_iterator it = partitions.begin();
it != partitions.end(); it++)
@ -248,14 +247,13 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
if (exo_det_nbr() > 0)
{
output << "M_.exo_det_names = '" << getName(exo_det_ids[0]) << "';" << endl;
output << "M_.exo_det_names_tex = '" << getTeXName(exo_det_ids[0]) << "';" << endl;
output << "M_.exo_det_names_long = '" << getLongName(exo_det_ids[0]) << "';" << endl;
for (int id = 1; id < exo_det_nbr(); id++)
output << "M_.exo_det_names = char(M_.exo_det_names, '" << getName(exo_det_ids[id]) << "');" << endl
<< "M_.exo_det_names_tex = char(M_.exo_det_names_tex, '" << getTeXName(exo_det_ids[id]) << "');" << endl
<< "M_.exo_det_names_long = char(M_.exo_det_names_long, '" << getLongName(exo_det_ids[id]) << "');" << endl;
output << "M_.exo_det_names = cell(" << exo_det_nbr() << ",1);" << endl;
output << "M_.exo_det_names_tex = cell(" << exo_det_nbr() << ",1);" << endl;
output << "M_.exo_det_names_long = cell(" << exo_det_nbr() << ",1);" << endl;
for (int id = 0; id < exo_det_nbr(); id++)
output << "M_.exo_det_names(" << id+1 << ") = {'" << getName(exo_det_ids[id]) << "'};" << endl
<< "M_.exo_det_names_tex(" << id+1 << ") = {'" << getTeXName(exo_det_ids[id]) << "'};" << endl
<< "M_.exo_det_names_long(" << id+1 << ") = {'" << getLongName(exo_det_ids[id]) << "'};" << endl;
output << "M_.exo_det_partitions = struct();" << endl;
map<string, map<int, string> > partitions = getPartitionsForType(eExogenousDet);
for (map<string, map<int, string> >::const_iterator it = partitions.begin();
@ -278,14 +276,13 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
if (endo_nbr() > 0)
{
output << "M_.endo_names = '" << getName(endo_ids[0]) << "';" << endl;
output << "M_.endo_names_tex = '" << getTeXName(endo_ids[0]) << "';" << endl;
output << "M_.endo_names_long = '" << getLongName(endo_ids[0]) << "';" << endl;
for (int id = 1; id < endo_nbr(); id++)
output << "M_.endo_names = char(M_.endo_names, '" << getName(endo_ids[id]) << "');" << endl
<< "M_.endo_names_tex = char(M_.endo_names_tex, '" << getTeXName(endo_ids[id]) << "');" << endl
<< "M_.endo_names_long = char(M_.endo_names_long, '" << getLongName(endo_ids[id]) << "');" << endl;
output << "M_.endo_names = cell(" << endo_nbr() << ",1);" << endl;
output << "M_.endo_names_tex = cell(" << endo_nbr() << ",1);" << endl;
output << "M_.endo_names_long = cell(" << endo_nbr() << ",1);" << endl;
for (int id = 0; id < endo_nbr(); id++)
output << "M_.endo_names(" << id+1 << ") = {'" << getName(endo_ids[id]) << "'};" << endl
<< "M_.endo_names_tex(" << id+1 << ") = {'" << getTeXName(endo_ids[id]) << "'};" << endl
<< "M_.endo_names_long(" << id+1 << ") = {'" << getLongName(endo_ids[id]) << "'};" << endl;
output << "M_.endo_partitions = struct();" << endl;
map<string, map<int, string> > partitions = getPartitionsForType(eEndogenous);
for (map<string, map<int, string> >::const_iterator it = partitions.begin();
@ -308,19 +305,17 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
if (param_nbr() > 0)
{
output << "M_.param_names = '" << getName(param_ids[0]) << "';" << endl;
output << "M_.param_names_tex = '" << getTeXName(param_ids[0]) << "';" << endl;
output << "M_.param_names_long = '" << getLongName(param_ids[0]) << "';" << endl;
for (int id = 1; id < param_nbr(); id++)
output << "M_.param_names = cell(" << param_nbr() << ",1);" << endl;
output << "M_.param_names_tex = cell(" << param_nbr() << ",1);" << endl;
output << "M_.param_names_long = cell(" << param_nbr() << ",1);" << endl;
for (int id = 0; id < param_nbr(); id++)
{
output << "M_.param_names = char(M_.param_names, '" << getName(param_ids[id]) << "');" << endl
<< "M_.param_names_tex = char(M_.param_names_tex, '" << getTeXName(param_ids[id]) << "');" << endl
<< "M_.param_names_long = char(M_.param_names_long, '" << getLongName(param_ids[id]) << "');" << endl;
output << "M_.param_names(" << id+1 << ") = {'" << getName(param_ids[id]) << "'};" << endl
<< "M_.param_names_tex(" << id+1 << ") = {'" << getTeXName(param_ids[id]) << "'};" << endl
<< "M_.param_names_long(" << id+1 << ") = {'" << getLongName(param_ids[id]) << "'};" << endl;
if (getName(param_ids[id]) == "dsge_prior_weight")
output << "options_.dsge_var = 1;" << endl;
}
output << "M_.param_partitions = struct();" << endl;
map<string, map<int, string> > partitions = getPartitionsForType(eParameter);
for (map<string, map<int, string> >::const_iterator it = partitions.begin();
@ -394,7 +389,7 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
if (observedVariablesNbr() > 0)
{
int ic = 1;
output << "options_.varobs = cell(1);" << endl;
output << "options_.varobs = cell(" << observedVariablesNbr() << ", 1);" << endl;
for (vector<int>::const_iterator it = varobs.begin();
it != varobs.end(); it++, ic++)
output << "options_.varobs(" << ic << ") = {'" << getName(*it) << "'};" << endl;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2016 Dynare Team
* Copyright (C) 2008-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -74,7 +74,7 @@ class MacroDriver;
}
%token DEFINE LINE FOR IN IF ELSE ENDIF ECHO_DIR ERROR IFDEF IFNDEF
%token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL LENGTH
%token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL LENGTH ECHOMACROVARS SAVE
%token <int_val> INTEGER
%token <string_val> NAME STRING
@ -121,6 +121,10 @@ statement : expr
{ TYPERR_CATCH(driver.error(@$, $2), @$); }
| LINE STRING INTEGER
/* Ignore @#line declarations */
| ECHOMACROVARS
{ driver.printvars(@$, true); }
| ECHOMACROVARS LPAREN SAVE RPAREN
{ out << driver.printvars(@$, false); }
;
expr : INTEGER

View File

@ -37,10 +37,13 @@ MacroDriver::~MacroDriver()
}
void
MacroDriver::parse(const string &f, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro,
map<string, string> defines, vector<string> path)
MacroDriver::parse(const string &f, const string &fb, const string &modfiletxt,
ostream &out, bool debug, bool no_line_macro_arg, map<string, string> defines,
vector<string> path)
{
file = f;
basename = fb;
no_line_macro = no_line_macro_arg;
/*
Copy the file into a stringstream, and add an extra end-of-line. This is a
@ -205,3 +208,27 @@ MacroDriver::error(const Macro::parser::location_type &l, const MacroValue *valu
error(l, sval->value);
}
string
MacroDriver::printvars(const Macro::parser::location_type &l, const bool tostdout) const
{
if (tostdout)
{
cout << "Macroprocessor: Printing macro variable values from " << file
<< " at line " << l.begin.line << endl;
for (map<string, const MacroValue *>::const_iterator it = env.begin();
it != env.end(); it++)
cout << " " << it->first << " = " << it->second->print() << endl;
cout << endl;
return "";
}
stringstream intomfile;
if (!no_line_macro)
intomfile << "@#line \"" << file << "\" " << l.begin.line << endl;
for (map<string, const MacroValue *>::const_iterator it = env.begin();
it != env.end(); it++)
intomfile<< "options_.macrovars_line_" << l.begin.line << "." << it->first << " = " << it->second->print() << ";" << endl;
return intomfile.str();
}

View File

@ -182,12 +182,18 @@ public:
//! Starts parsing a file, returns output in out
/*! \param no_line_macro should we omit the @#line statements ? */
void parse(const string &f, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro,
void parse(const string &f, const string &fb, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro_arg,
map<string, string> defines, vector<string> path);
//! Name of main file being parsed
string file;
//! Basename of main file being parsed
string basename;
//! Whether or not to print @#line
bool no_line_macro;
//! Reference to the lexer
class MacroFlex *lexer;
@ -197,6 +203,9 @@ public:
//! Error handler
void error(const Macro::parser::location_type &l, const string &m) const;
//! Print variables
string printvars(const Macro::parser::location_type &l, const bool save) const;
//! Set a variable
void set_variable(const string &name, const MacroValue *value);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2016 Dynare Team
* Copyright (C) 2008-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -236,6 +236,9 @@ CONT \\\\
<STMT>line { return token::LINE; }
<STMT>define { return token::DEFINE; }
<STMT>echomacrovars { return token::ECHOMACROVARS; }
<STMT>save { return token::SAVE; }
<STMT>for { reading_for_statement = true; return token::FOR; }
<STMT>endfor { driver.error(*yylloc, "@#endfor is not matched by a @#for statement"); }

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2014 Dynare Team
* Copyright (C) 2008-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -280,6 +280,12 @@ IntMV::toString() const
return ss.str();
}
string
IntMV::print() const
{
return toString();
}
const MacroValue *
IntMV::toArray() const
{
@ -398,6 +404,12 @@ StringMV::toString() const
return value;
}
string
StringMV::print() const
{
return "'" + value + "'";
}
const MacroValue *
StringMV::toArray() const
{

View File

@ -23,6 +23,7 @@
#include <string>
#include <vector>
#include <sstream>
#include <boost/lexical_cast.hpp>
using namespace std;
@ -91,6 +92,8 @@ public:
virtual const MacroValue *operator[](const MacroValue &mv) const throw (TypeError, OutOfBoundsError);
//! Converts value to string
virtual string toString() const = 0;
//! Converts value to be printed
virtual string print() const = 0;
//! Converts value to array form
virtual const MacroValue *toArray() const = 0;
//! Gets length
@ -147,6 +150,7 @@ public:
//! Computes logical negation
virtual const MacroValue *operator!() const throw (TypeError);
virtual string toString() const;
virtual string print() const;
//! Converts value to array form
/*! Returns an integer array containing a single value */
virtual const MacroValue *toArray() const;
@ -187,6 +191,7 @@ public:
virtual const MacroValue *operator[](const MacroValue &mv) const throw (TypeError, OutOfBoundsError);
//! Returns underlying string value
virtual string toString() const;
virtual string print() const;
//! Converts value to array form
/*! Returns a string array containing a single value */
virtual const MacroValue *toArray() const;
@ -226,6 +231,7 @@ public:
virtual const MacroValue *operator[](const MacroValue &mv) const throw (TypeError, OutOfBoundsError);
//! Returns a string containing the concatenation of string representations of elements
virtual string toString() const;
virtual string print() const;
//! Returns itself
virtual const MacroValue *toArray() const;
//! Gets length
@ -335,6 +341,43 @@ ArrayMV<T>::toString() const
return ss.str();
}
template<typename T>
string
ArrayMV<T>::print() const
{
bool printStrArr = false;
try
{
typename vector<T>::const_iterator it = values.begin();
boost::lexical_cast<int>(*it);
}
catch (boost::bad_lexical_cast &)
{
printStrArr= true;
}
ostringstream ss;
if (printStrArr)
ss << "{";
else
ss << "[";
for (typename vector<T>::const_iterator it = values.begin();
it != values.end(); it++)
{
if (it != values.begin())
ss << ", ";
if (printStrArr)
ss << "'" << *it << "'";
else
ss << *it;
}
if (printStrArr)
ss << "}";
else
ss << "]";
return ss.str();
}
template<typename T>
const MacroValue *
ArrayMV<T>::toArray() const