Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • normann/preprocessor
  • Dynare/preprocessor
  • FerhatMihoubi/preprocessor
  • MichelJuillard/preprocessor
  • sebastien/preprocessor
  • lnsongxf/preprocessor
  • albop/preprocessor
  • DoraK/preprocessor
  • amg/preprocessor
  • wmutschl/preprocessor
  • JohannesPfeifer/preprocessor
11 results
Select Git revision
Show changes
/* /*
* Copyright © 2003-2019 Dynare Team * Copyright © 2003-2020 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -1413,9 +1413,13 @@ ParsingDriver::option_symbol_list(string name_option) ...@@ -1413,9 +1413,13 @@ ParsingDriver::option_symbol_list(string name_option)
{ {
vector<string> shocks = symbol_list.get_symbols(); vector<string> shocks = symbol_list.get_symbols();
for (auto &shock : shocks) for (auto &shock : shocks)
{
if (!mod_file->symbol_table.exists(shock))
error("Unknown symbol: " + shock);
if (mod_file->symbol_table.getType(shock) != SymbolType::exogenous) if (mod_file->symbol_table.getType(shock) != SymbolType::exogenous)
error("Variables passed to irf_shocks must be exogenous. Caused by: " + shock); error("Variables passed to irf_shocks must be exogenous. Caused by: " + shock);
} }
}
if (name_option.compare("ms.parameters") == 0) if (name_option.compare("ms.parameters") == 0)
{ {
...@@ -1931,7 +1935,7 @@ ParsingDriver::set_corr_options(const string &name1, const string &name2, const ...@@ -1931,7 +1935,7 @@ ParsingDriver::set_corr_options(const string &name1, const string &name2, const
void void
ParsingDriver::run_estimation() ParsingDriver::run_estimation()
{ {
mod_file->addStatement(make_unique<EstimationStatement>(symbol_list, options_list)); mod_file->addStatement(make_unique<EstimationStatement>(mod_file->symbol_table, symbol_list, options_list));
symbol_list.clear(); symbol_list.clear();
options_list.clear(); options_list.clear();
} }
...@@ -2222,14 +2226,20 @@ ParsingDriver::evaluate_planner_objective() ...@@ -2222,14 +2226,20 @@ ParsingDriver::evaluate_planner_objective()
void void
ParsingDriver::discretionary_policy() ParsingDriver::discretionary_policy()
{ {
/* The logic here is different from “ramsey_policy” and “ramsey_model”,
because we want to allow several instances of “discretionary_policy” in
the same .mod file. */
if (!mod_file->symbol_table.exists("optimal_policy_discount_factor")) if (!mod_file->symbol_table.exists("optimal_policy_discount_factor"))
{
declare_parameter("optimal_policy_discount_factor"); declare_parameter("optimal_policy_discount_factor");
init_param("optimal_policy_discount_factor", data_tree->One);
} if (!planner_discount)
planner_discount = data_tree->One;
init_param("optimal_policy_discount_factor", planner_discount);
mod_file->addStatement(make_unique<DiscretionaryPolicyStatement>(symbol_list, options_list)); mod_file->addStatement(make_unique<DiscretionaryPolicyStatement>(symbol_list, options_list));
symbol_list.clear(); symbol_list.clear();
options_list.clear(); options_list.clear();
planner_discount = nullptr;
} }
void void
...@@ -2446,27 +2456,6 @@ ParsingDriver::conditional_forecast_paths() ...@@ -2446,27 +2456,6 @@ ParsingDriver::conditional_forecast_paths()
det_shocks.clear(); det_shocks.clear();
} }
void
ParsingDriver::det_cond_forecast_linear_decomposition(const string &plan)
{
symbol_list.clear();
symbol_list.addSymbol(plan);
mod_file->addStatement(make_unique<DetCondForecast>(symbol_list, options_list, mod_file->linear_decomposition));
symbol_list.clear();
options_list.clear();
}
void
ParsingDriver::det_cond_forecast_linear_decomposition(const string &plan, const string &dset)
{
symbol_list.clear();
symbol_list.addSymbol(plan);
symbol_list.addSymbol(dset);
mod_file->addStatement(make_unique<DetCondForecast>(symbol_list, options_list, mod_file->linear_decomposition));
symbol_list.clear();
options_list.clear();
}
void void
ParsingDriver::calib_smoother() ParsingDriver::calib_smoother()
{ {
...@@ -2532,7 +2521,9 @@ ParsingDriver::declare_and_init_model_local_variable(const string &name, expr_t ...@@ -2532,7 +2521,9 @@ ParsingDriver::declare_and_init_model_local_variable(const string &name, expr_t
} }
catch (SymbolTable::AlreadyDeclaredException &e) catch (SymbolTable::AlreadyDeclaredException &e)
{ {
// It can have already been declared in a steady_state_model block, check that it is indeed a ModelLocalVariable /* It can have already been declared in a steady_state_model block or
model_local_variable statement, check that it is indeed a
ModelLocalVariable */
symb_id = mod_file->symbol_table.getID(name); symb_id = mod_file->symbol_table.getID(name);
if (mod_file->symbol_table.getType(symb_id) != SymbolType::modelLocalVariable) if (mod_file->symbol_table.getType(symb_id) != SymbolType::modelLocalVariable)
error(name + " has wrong type or was already used on the right-hand side. You cannot use it on the left-hand side of a pound ('#') expression"); error(name + " has wrong type or was already used on the right-hand side. You cannot use it on the left-hand side of a pound ('#') expression");
......
...@@ -716,9 +716,6 @@ public: ...@@ -716,9 +716,6 @@ public:
void conditional_forecast_paths(); void conditional_forecast_paths();
//! Plot conditional forecast statement //! Plot conditional forecast statement
void plot_conditional_forecast(const string &periods = ""); void plot_conditional_forecast(const string &periods = "");
//! Deterministic conditional forecast statement
void det_cond_forecast_linear_decomposition(const string &plan);
void det_cond_forecast_linear_decomposition(const string &plan, const string &dset);
//! Smoother on calibrated models //! Smoother on calibrated models
void calib_smoother(); void calib_smoother();
//! Extended path //! Extended path
......
/* /*
* Copyright © 2006-2019 Dynare Team * Copyright © 2006-2020 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -53,8 +53,8 @@ void ...@@ -53,8 +53,8 @@ void
NativeStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const NativeStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
{ {
using namespace boost::xpressive; using namespace boost::xpressive;
string date_regex = R"((-?\d+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4]\d|5[0-2]))))"; string date_regex = R"((-?\d+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4])))";
sregex regex_lookbehind = sregex::compile(R"((?<!\$|\d|[a-zA-Z_]|\'))" + date_regex); sregex regex_lookbehind = sregex::compile(R"((?<!\$|\d|[a-zA-Z_]|-|'))" + date_regex);
sregex regex_dollar = sregex::compile(R"((\$))" + date_regex); sregex regex_dollar = sregex::compile(R"((\$))" + date_regex);
string ns = regex_replace(native_statement, regex_lookbehind, "dates('$&')"); string ns = regex_replace(native_statement, regex_lookbehind, "dates('$&')");
......
/* /*
* Copyright © 2006-2019 Dynare Team * Copyright © 2006-2020 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -134,6 +134,9 @@ public: ...@@ -134,6 +134,9 @@ public:
/* Whether any of shock_decomposition, realtime_shock_decomposition and /* Whether any of shock_decomposition, realtime_shock_decomposition and
initial_condition_decomposition has the “with_epilogue” option */ initial_condition_decomposition has the “with_epilogue” option */
bool with_epilogue_option{false}; bool with_epilogue_option{false};
/* Lists symbol IDs of parameters that appear in a “planner_discount” option.
See dynare#1173 for more details. */
set<int> parameters_in_planner_discount;
}; };
class Statement class Statement
......
...@@ -164,7 +164,7 @@ StaticModel::StaticModel(const DynamicModel &m) : ...@@ -164,7 +164,7 @@ StaticModel::StaticModel(const DynamicModel &m) :
// Detect if equation is marked [dynamic] // Detect if equation is marked [dynamic]
bool is_dynamic_only = false; bool is_dynamic_only = false;
vector<pair<string, string>> eq_tags; vector<pair<string, string>> eq_tags;
for (const auto & [tagged_eq, tag_pair] : equation_tags) for (const auto & [tagged_eq, tag_pair] : m.equation_tags)
if (tagged_eq == i) if (tagged_eq == i)
{ {
eq_tags.push_back(tag_pair); eq_tags.push_back(tag_pair);
...@@ -410,7 +410,7 @@ StaticModel::writeModelEquationsOrdered_M(const string &basename) const ...@@ -410,7 +410,7 @@ StaticModel::writeModelEquationsOrdered_M(const string &basename) const
output << " global options_;" << endl; output << " global options_;" << endl;
//The Temporary terms //The Temporary terms
if (simulation_type != EVALUATE_BACKWARD && simulation_type != EVALUATE_FORWARD) if (simulation_type != EVALUATE_BACKWARD && simulation_type != EVALUATE_FORWARD)
output << " g1 = spalloc(" << block_mfs << ", " << block_mfs << ", " << derivative_endo[block].size() << ");" << endl; output << " g1 = spalloc(" << block_mfs << ", " << block_mfs << ", " << blocks_derivatives[block].size() << ");" << endl;
if (v_temporary_terms_inuse[block].size()) if (v_temporary_terms_inuse[block].size())
{ {
...@@ -2107,6 +2107,14 @@ StaticModel::writeOutput(ostream &output, bool block) const ...@@ -2107,6 +2107,14 @@ StaticModel::writeOutput(ostream &output, bool block) const
output << temporary_terms_derivative.size() << "; "; output << temporary_terms_derivative.size() << "; ";
output << "];" << endl; output << "];" << endl;
/* Write mapping between model local variables and indices in the temporary
terms vector (dynare#1722) */
output << "M_.model_local_variables_static_tt_idxs = {" << endl;
for (auto [mlv, value] : temporary_terms_mlv)
output << " '" << symbol_table.getName(mlv->symb_id) << "', "
<< temporary_terms_idxs.at(mlv)+1 << ';' << endl;
output << "};" << endl;
if (!block) if (!block)
return; return;
...@@ -2125,7 +2133,7 @@ StaticModel::writeOutput(ostream &output, bool block) const ...@@ -2125,7 +2133,7 @@ StaticModel::writeOutput(ostream &output, bool block) const
} }
output << "block_structure_stat.block(" << b+1 << ").Simulation_Type = " << simulation_type << ";" << endl output << "block_structure_stat.block(" << b+1 << ").Simulation_Type = " << simulation_type << ";" << endl
<< "block_structure_stat.block(" << b+1 << ").endo_nbr = " << block_size << ";" << endl << "block_structure_stat.block(" << b+1 << ").endo_nbr = " << block_size << ";" << endl
<< "block_structure_stat.block(" << b+1 << ").mfs = " << getBlockMfs(block) << ";" << endl << "block_structure_stat.block(" << b+1 << ").mfs = " << getBlockMfs(b) << ";" << endl
<< "block_structure_stat.block(" << b+1 << ").equation = [" << tmp_s_eq.str() << "];" << endl << "block_structure_stat.block(" << b+1 << ").equation = [" << tmp_s_eq.str() << "];" << endl
<< "block_structure_stat.block(" << b+1 << ").variable = [" << tmp_s.str() << "];" << endl; << "block_structure_stat.block(" << b+1 << ").variable = [" << tmp_s.str() << "];" << endl;
} }
...@@ -2753,6 +2761,9 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons ...@@ -2753,6 +2761,9 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
void void
StaticModel::writeJsonOutput(ostream &output) const StaticModel::writeJsonOutput(ostream &output) const
{ {
deriv_node_temp_terms_t tef_terms;
writeJsonModelLocalVariables(output, false, tef_terms);
output << ", ";
writeJsonModelEquations(output, false); writeJsonModelEquations(output, false);
} }
...@@ -2765,7 +2776,7 @@ StaticModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) co ...@@ -2765,7 +2776,7 @@ StaticModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) co
deriv_node_temp_terms_t tef_terms; deriv_node_temp_terms_t tef_terms;
temporary_terms_t temp_term_union; temporary_terms_t temp_term_union;
writeJsonModelLocalVariables(model_local_vars_output, tef_terms); writeJsonModelLocalVariables(model_local_vars_output, true, tef_terms);
writeJsonTemporaryTerms(temporary_terms_derivatives[0], temp_term_union, d_output[0], tef_terms, ""); writeJsonTemporaryTerms(temporary_terms_derivatives[0], temp_term_union, d_output[0], tef_terms, "");
d_output[0] << ", "; d_output[0] << ", ";
...@@ -2852,7 +2863,7 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) ...@@ -2852,7 +2863,7 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
ostringstream third_derivs1_output; // Used for storing third order derivatives equations ostringstream third_derivs1_output; // Used for storing third order derivatives equations
deriv_node_temp_terms_t tef_terms; deriv_node_temp_terms_t tef_terms;
writeJsonModelLocalVariables(model_local_vars_output, tef_terms); writeJsonModelLocalVariables(model_local_vars_output, true, tef_terms);
temporary_terms_t temp_term_union; temporary_terms_t temp_term_union;
for (const auto &it : params_derivs_temporary_terms) for (const auto &it : params_derivs_temporary_terms)
......
/* /*
* Copyright © 2003-2019 Dynare Team * Copyright © 2003-2020 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -34,10 +34,21 @@ SymbolList::addSymbol(const string &symbol) ...@@ -34,10 +34,21 @@ SymbolList::addSymbol(const string &symbol)
} }
void void
SymbolList::checkPass(WarningConsolidation &warnings) const noexcept(false) SymbolList::checkPass(WarningConsolidation &warnings,
const vector<SymbolType> &types) const noexcept(false)
{ {
if (types.empty())
return;
smatch m; smatch m;
regex re("^(AUX_EXPECT_|AUX_ENDO_|MULT_)"); string regex_str = "AUX_EXPECT_|MULT_";
for (auto type : types)
if (type == SymbolType::endogenous)
{
regex_str += "|AUX_ENDO_";
break;
}
regex re("^(" + regex_str +")");
for (const auto &symbol : symbols) for (const auto &symbol : symbols)
{ {
if (!symbol_table->exists(symbol)) if (!symbol_table->exists(symbol))
...@@ -53,8 +64,64 @@ SymbolList::checkPass(WarningConsolidation &warnings) const noexcept(false) ...@@ -53,8 +64,64 @@ SymbolList::checkPass(WarningConsolidation &warnings) const noexcept(false)
throw SymbolListException{"Variable " + symbol + " was not declared."}; throw SymbolListException{"Variable " + symbol + " was not declared."};
} }
if (symbol_table->getType(symbol) != SymbolType::endogenous) bool type_found = false;
throw SymbolListException{"Variable " + symbol + " is not endogenous."}; for (auto type : types)
if (symbol_table->getType(symbol) == type)
{
type_found = true;
break;
}
if (!type_found)
{
string valid_types;
for (auto type : types)
switch(type)
{
case SymbolType::endogenous:
valid_types += "endogenous, ";
break;
case SymbolType::exogenous:
valid_types += "exogenous, ";
break;
case SymbolType::epilogue:
valid_types += "epilogue, ";
break;
case SymbolType::parameter:
valid_types += "parameter, ";
break;
case SymbolType::exogenousDet:
valid_types += "exogenousDet, ";
break;
case SymbolType::trend:
valid_types += "trend, ";
break;
case SymbolType::logTrend:
valid_types += "logTrend, ";
break;
case SymbolType::modFileLocalVariable:
valid_types += "modFileLocalVariable, ";
break;
case SymbolType::modelLocalVariable:
valid_types += "modelLocalVariable, ";
break;
case SymbolType::externalFunction:
valid_types += "externalFunction, ";
break;
case SymbolType::statementDeclaredVariable:
valid_types += "statementDeclaredVariable, ";
break;
case SymbolType::unusedEndogenous:
valid_types += "unusedEndogenous, ";
break;
case SymbolType::endogenousVAR:
valid_types += "endogenousVAR, ";
break;
case SymbolType::excludedVariable:
valid_types += "excludedVariable, ";
}
valid_types = valid_types.erase(valid_types.size()-2, 2);
throw SymbolListException{"Variable " + symbol + " is not one of {" + valid_types + "}"};
}
} }
} }
...@@ -111,6 +178,6 @@ SymbolList::removeDuplicates(const string &dynare_command, WarningConsolidation ...@@ -111,6 +178,6 @@ SymbolList::removeDuplicates(const string &dynare_command, WarningConsolidation
unique_symbols.push_back(it); unique_symbols.push_back(it);
else else
warnings << "WARNING: In " << dynare_command << ": " << it warnings << "WARNING: In " << dynare_command << ": " << it
<< " found more than once in symbol list. Removing all but first occurence." << endl; << " found more than once in symbol list. Removing all but first occurrence." << endl;
symbols = unique_symbols; symbols = unique_symbols;
} }
...@@ -54,7 +54,7 @@ public: ...@@ -54,7 +54,7 @@ public:
//! Removed duplicate symbols //! Removed duplicate symbols
void removeDuplicates(const string &dynare_command, WarningConsolidation &warnings); void removeDuplicates(const string &dynare_command, WarningConsolidation &warnings);
//! Check symbols to ensure variables have been declared and are endogenous //! Check symbols to ensure variables have been declared and are endogenous
void checkPass(WarningConsolidation &warnings) const noexcept(false); void checkPass(WarningConsolidation &warnings, const vector<SymbolType> &types) const noexcept(false);
//! Output content in Matlab format //! Output content in Matlab format
/*! Creates a string array for Matlab, stored in variable "varname" */ /*! Creates a string array for Matlab, stored in variable "varname" */
void writeOutput(const string &varname, ostream &output) const; void writeOutput(const string &varname, ostream &output) const;
......
...@@ -1096,3 +1096,12 @@ SymbolTable::getUltimateOrigSymbID(int symb_id) const ...@@ -1096,3 +1096,12 @@ SymbolTable::getUltimateOrigSymbID(int symb_id) const
} }
return symb_id; return symb_id;
} }
int
SymbolTable::getEquationNumberForMultiplier(int symb_id) const
{
for (const auto &aux_var : aux_vars)
if (aux_var.get_symb_id() == symb_id && aux_var.get_type() == AuxVarType::multiplier)
return aux_var.get_equation_number_for_multiplier();
return -1;
}
...@@ -412,6 +412,8 @@ public: ...@@ -412,6 +412,8 @@ public:
repeatedly call getOrigSymbIDForAuxVar() until an original repeatedly call getOrigSymbIDForAuxVar() until an original
(non-auxiliary) variable is found. */ (non-auxiliary) variable is found. */
int getUltimateOrigSymbID(int symb_id) const; int getUltimateOrigSymbID(int symb_id) const;
//! If this is a Lagrange multiplier, return its associated equation number; otherwise return -1
int getEquationNumberForMultiplier(int symb_id) const;
}; };
inline void inline void
......
/* /*
* Copyright © 2019 Dynare Team * Copyright © 2019-2021 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
using namespace macro; using namespace macro;
void void
Eval::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) Eval::interpret(ostream &output, vector<filesystem::path> &paths)
{ {
try try
{ {
...@@ -43,7 +43,7 @@ Eval::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &p ...@@ -43,7 +43,7 @@ Eval::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &p
} }
void void
Include::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) Include::interpret(ostream &output, vector<filesystem::path> &paths)
{ {
using namespace filesystem; using namespace filesystem;
try try
...@@ -71,7 +71,7 @@ Include::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> ...@@ -71,7 +71,7 @@ Include::interpret(ostream &output, bool no_line_macro, vector<filesystem::path>
+". The following directories were searched:\n" + errmsg.str(), location)); +". The following directories were searched:\n" + errmsg.str(), location));
} }
} }
Driver m(env, no_line_macro); Driver m(env);
// Calling `string()` method on filename and filename.stem() because of bug in // Calling `string()` method on filename and filename.stem() because of bug in
// MinGW 8.3.0 that ignores implicit conversion to string from filename::path. // MinGW 8.3.0 that ignores implicit conversion to string from filename::path.
// Test if bug exists when version of MinGW is upgraded on Debian runners // Test if bug exists when version of MinGW is upgraded on Debian runners
...@@ -86,10 +86,11 @@ Include::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> ...@@ -86,10 +86,11 @@ Include::interpret(ostream &output, bool no_line_macro, vector<filesystem::path>
{ {
error(StackTrace("@#include", e.what(), location)); error(StackTrace("@#include", e.what(), location));
} }
printLineInfo(output);
} }
void void
IncludePath::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) IncludePath::interpret(ostream &output, vector<filesystem::path> &paths)
{ {
using namespace filesystem; using namespace filesystem;
try try
...@@ -116,7 +117,7 @@ IncludePath::interpret(ostream &output, bool no_line_macro, vector<filesystem::p ...@@ -116,7 +117,7 @@ IncludePath::interpret(ostream &output, bool no_line_macro, vector<filesystem::p
} }
void void
Define::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) Define::interpret(ostream &output, vector<filesystem::path> &paths)
{ {
try try
{ {
...@@ -139,7 +140,7 @@ Define::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> ...@@ -139,7 +140,7 @@ Define::interpret(ostream &output, bool no_line_macro, vector<filesystem::path>
} }
void void
Echo::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) Echo::interpret(ostream &output, vector<filesystem::path> &paths)
{ {
try try
{ {
...@@ -154,11 +155,11 @@ Echo::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &p ...@@ -154,11 +155,11 @@ Echo::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &p
{ {
error(StackTrace("@#echo", e.what(), location)); error(StackTrace("@#echo", e.what(), location));
} }
printEndLineInfo(output, no_line_macro); printEndLineInfo(output);
} }
void void
Error::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) Error::interpret(ostream &output, vector<filesystem::path> &paths)
{ {
try try
{ {
...@@ -176,17 +177,17 @@ Error::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> & ...@@ -176,17 +177,17 @@ Error::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &
} }
void void
EchoMacroVars::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) EchoMacroVars::interpret(ostream &output, vector<filesystem::path> &paths)
{ {
if (save) if (save)
env.print(output, vars, location.begin.line, true); env.print(output, vars, location.begin.line, true);
else else
env.print(cout, vars); env.print(cout, vars);
printEndLineInfo(output, no_line_macro); printEndLineInfo(output);
} }
void void
For::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) For::interpret(ostream &output, vector<filesystem::path> &paths)
{ {
ArrayPtr ap; ArrayPtr ap;
try try
...@@ -232,20 +233,37 @@ For::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &pa ...@@ -232,20 +233,37 @@ For::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &pa
{ {
if (printLine) if (printLine)
{ {
statement->printLineInfo(output, no_line_macro); statement->printLineInfo(output);
printLine = false; printLine = false;
} }
statement->interpret(output, no_line_macro, paths); statement->interpret(output, paths);
} }
} }
printEndLineInfo(output, no_line_macro); printEndLineInfo(output);
} }
void void
If::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) If::interpret(ostream &output, vector<filesystem::path> &paths)
{ {
bool first_clause = true;
for (const auto & [expr, body] : expr_and_body) for (const auto & [expr, body] : expr_and_body)
try try
{
if ((ifdef || ifndef) && first_clause)
{
first_clause = false;
VariablePtr vp = dynamic_pointer_cast<Variable>(expr);
if (!vp)
error(StackTrace(ifdef ? "@#ifdef" : "@#ifndef",
"The condition must be a variable name", location));
if ((ifdef && env.isVariableDefined(vp->getName()))
|| (ifndef && !env.isVariableDefined(vp->getName())))
{
interpretBody(body, output, paths);
break;
}
}
else
{ {
auto tmp = expr->eval(); auto tmp = expr->eval();
RealPtr dp = dynamic_pointer_cast<Real>(tmp); RealPtr dp = dynamic_pointer_cast<Real>(tmp);
...@@ -255,10 +273,11 @@ If::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &pat ...@@ -255,10 +273,11 @@ If::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &pat
"The condition must evaluate to a boolean or a double", location)); "The condition must evaluate to a boolean or a double", location));
if ((bp && *bp) || (dp && *dp)) if ((bp && *bp) || (dp && *dp))
{ {
interpretBody(body, output, no_line_macro, paths); interpretBody(body, output, paths);
break; break;
} }
} }
}
catch (StackTrace &ex) catch (StackTrace &ex)
{ {
ex.push("@#if", location); ex.push("@#if", location);
...@@ -268,48 +287,20 @@ If::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &pat ...@@ -268,48 +287,20 @@ If::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &pat
{ {
error(StackTrace("@#if", e.what(), location)); error(StackTrace("@#if", e.what(), location));
} }
printEndLineInfo(output, no_line_macro); printEndLineInfo(output);
} }
void void
If::interpretBody(const vector<DirectivePtr> &body, ostream &output, bool no_line_macro, vector<filesystem::path> &paths) If::interpretBody(const vector<DirectivePtr> &body, ostream &output, vector<filesystem::path> &paths)
{ {
bool printLine = !no_line_macro; bool printLine = true;
for (const auto &statement : body) for (const auto &statement : body)
{ {
if (printLine) if (printLine)
{ {
statement->printLineInfo(output, no_line_macro); statement->printLineInfo(output);
printLine = false; printLine = false;
} }
statement->interpret(output, no_line_macro, paths); statement->interpret(output, paths);
}
}
void
Ifdef::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths)
{
for (const auto & [expr, body] : expr_and_body)
if (VariablePtr vp = dynamic_pointer_cast<Variable>(expr);
dynamic_pointer_cast<BaseType>(expr)
|| (vp && env.isVariableDefined(vp->getName())))
{
interpretBody(body, output, no_line_macro, paths);
break;
}
printEndLineInfo(output, no_line_macro);
}
void
Ifndef::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths)
{
for (const auto & [expr, body] : expr_and_body)
if (VariablePtr vp = dynamic_pointer_cast<Variable>(expr);
!(dynamic_pointer_cast<BaseType>(expr)
|| (vp && env.isVariableDefined(vp->getName()))))
{
interpretBody(body, output, no_line_macro, paths);
break;
} }
printEndLineInfo(output, no_line_macro);
} }
/* /*
* Copyright (C) 2019 Dynare Team * Copyright (C) 2019-2020 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -30,13 +30,13 @@ namespace macro ...@@ -30,13 +30,13 @@ namespace macro
{ {
// A Parent class just for clarity // A Parent class just for clarity
public: public:
Directive(Environment &env_arg, Tokenizer::location location_arg) : Node(env_arg, move(location_arg)) Directive(Environment &env_arg, Tokenizer::location location_arg) :
{ Node(env_arg, move(location_arg)) { }
}
// Directives can be interpreted // Directives can be interpreted
virtual void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) = 0; virtual void interpret(ostream &output, vector<filesystem::path> &paths) = 0;
}; };
class TextNode : public Directive class TextNode : public Directive
{ {
// Class for text not interpreted by macroprocessor // Class for text not interpreted by macroprocessor
...@@ -46,16 +46,11 @@ namespace macro ...@@ -46,16 +46,11 @@ namespace macro
const string text; const string text;
public: public:
TextNode(string text_arg, Environment &env_arg, Tokenizer::location location_arg) : TextNode(string text_arg, Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), text{move(text_arg)} Directive(env_arg, move(location_arg)), text{move(text_arg)} { }
{ inline void interpret(ostream &output, vector<filesystem::path> &paths) override { output << text; }
}
inline void
interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override
{
output << text;
}
}; };
class Eval : public Directive class Eval : public Directive
{ {
// Class for @{} statements // Class for @{} statements
...@@ -65,36 +60,33 @@ namespace macro ...@@ -65,36 +60,33 @@ namespace macro
const ExpressionPtr expr; const ExpressionPtr expr;
public: public:
Eval(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) : Eval(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
{ void interpret(ostream &output, vector<filesystem::path> &paths) override;
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
}; };
class Include : public Directive class Include : public Directive
{ {
private: private:
const ExpressionPtr expr; const ExpressionPtr expr;
public: public:
Include(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) : Include(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
{ void interpret(ostream &output, vector<filesystem::path> &paths) override;
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
}; };
class IncludePath : public Directive class IncludePath : public Directive
{ {
private: private:
const ExpressionPtr expr; const ExpressionPtr expr;
public: public:
IncludePath(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) : IncludePath(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
{ void interpret(ostream &output, vector<filesystem::path> &paths) override;
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
}; };
class Define : public Directive class Define : public Directive
{ {
private: private:
...@@ -105,18 +97,15 @@ namespace macro ...@@ -105,18 +97,15 @@ namespace macro
Define(VariablePtr var_arg, Define(VariablePtr var_arg,
ExpressionPtr value_arg, ExpressionPtr value_arg,
Environment &env_arg, Tokenizer::location location_arg) : Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), var{move(var_arg)}, value{move(value_arg)} Directive(env_arg, move(location_arg)), var{move(var_arg)}, value{move(value_arg)} { }
{
}
Define(FunctionPtr func_arg, Define(FunctionPtr func_arg,
ExpressionPtr value_arg, ExpressionPtr value_arg,
Environment &env_arg, Tokenizer::location location_arg) : Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), func{move(func_arg)}, value{move(value_arg)} Directive(env_arg, move(location_arg)), func{move(func_arg)}, value{move(value_arg)} { }
{ void interpret(ostream &output, vector<filesystem::path> &paths) override;
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
}; };
class Echo : public Directive class Echo : public Directive
{ {
private: private:
...@@ -124,12 +113,11 @@ namespace macro ...@@ -124,12 +113,11 @@ namespace macro
public: public:
Echo(ExpressionPtr expr_arg, Echo(ExpressionPtr expr_arg,
Environment &env_arg, Tokenizer::location location_arg) : Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
{ void interpret(ostream &output, vector<filesystem::path> &paths) override;
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
}; };
class Error : public Directive class Error : public Directive
{ {
private: private:
...@@ -137,12 +125,11 @@ namespace macro ...@@ -137,12 +125,11 @@ namespace macro
public: public:
Error(ExpressionPtr expr_arg, Error(ExpressionPtr expr_arg,
Environment &env_arg, Tokenizer::location location_arg) : Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
{ void interpret(ostream &output, vector<filesystem::path> &paths) override;
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
}; };
class EchoMacroVars : public Directive class EchoMacroVars : public Directive
{ {
private: private:
...@@ -151,17 +138,14 @@ namespace macro ...@@ -151,17 +138,14 @@ namespace macro
public: public:
EchoMacroVars(bool save_arg, EchoMacroVars(bool save_arg,
Environment &env_arg, Tokenizer::location location_arg) : Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), save{save_arg} Directive(env_arg, move(location_arg)), save{save_arg} { }
{
}
EchoMacroVars(bool save_arg, vector<string> vars_arg, EchoMacroVars(bool save_arg, vector<string> vars_arg,
Environment &env_arg, Tokenizer::location location_arg) : Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), save{save_arg}, vars{move(vars_arg)} Directive(env_arg, move(location_arg)), save{save_arg}, vars{move(vars_arg)} { }
{ void interpret(ostream &output, vector<filesystem::path> &paths) override;
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
}; };
class For : public Directive class For : public Directive
{ {
private: private:
...@@ -174,12 +158,11 @@ namespace macro ...@@ -174,12 +158,11 @@ namespace macro
vector<DirectivePtr> statements_arg, vector<DirectivePtr> statements_arg,
Environment &env_arg, Tokenizer::location location_arg) : Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), index_vec{move(index_vec_arg)}, Directive(env_arg, move(location_arg)), index_vec{move(index_vec_arg)},
index_vals{move(index_vals_arg)}, statements{move(statements_arg)} index_vals{move(index_vals_arg)}, statements{move(statements_arg)} { }
{ void interpret(ostream &output, vector<filesystem::path> &paths) override;
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
}; };
class If : public Directive class If : public Directive
{ {
protected: protected:
...@@ -192,15 +175,17 @@ namespace macro ...@@ -192,15 +175,17 @@ namespace macro
* If there is an `else` statement it is the last element in the vector. Its condition is true. * If there is an `else` statement it is the last element in the vector. Its condition is true.
*/ */
const vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body; const vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body;
const bool ifdef, ifndef;
public: public:
If(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg, If(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
Environment &env_arg, Tokenizer::location location_arg) : Environment &env_arg, Tokenizer::location location_arg,
Directive(env_arg, move(location_arg)), expr_and_body{move(expr_and_body_arg)} bool ifdef_arg = false, bool ifndef_arg = false) :
{ Directive(env_arg, move(location_arg)), expr_and_body{move(expr_and_body_arg)},
} ifdef{ifdef_arg}, ifndef{ifndef_arg} { }
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override; void interpret(ostream &output, vector<filesystem::path> &paths) override;
protected: protected:
void interpretBody(const vector<DirectivePtr> &body, ostream &output, bool no_line_macro, vector<filesystem::path> &paths); void interpretBody(const vector<DirectivePtr> &body, ostream &output,
vector<filesystem::path> &paths);
}; };
class Ifdef : public If class Ifdef : public If
...@@ -208,21 +193,16 @@ namespace macro ...@@ -208,21 +193,16 @@ namespace macro
public: public:
Ifdef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg, Ifdef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
Environment &env_arg, Tokenizer::location location_arg) : Environment &env_arg, Tokenizer::location location_arg) :
If(move(expr_and_body_arg), env_arg, move(location_arg)) If(move(expr_and_body_arg), env_arg, move(location_arg), true, false) { }
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
}; };
class Ifndef : public If class Ifndef : public If
{ {
public: public:
Ifndef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg, Ifndef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
Environment &env_arg, Tokenizer::location location_arg) : Environment &env_arg, Tokenizer::location location_arg) :
If(move(expr_and_body_arg), env_arg, move(location_arg)) If(move(expr_and_body_arg), env_arg, move(location_arg), false, true) { }
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
}; };
} }
#endif #endif
/* /*
* Copyright © 2019 Dynare Team * Copyright © 2019-2020 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
*/ */
#include "Driver.hh" #include "Driver.hh"
#include <regex>
using namespace macro; using namespace macro;
...@@ -33,20 +34,8 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi ...@@ -33,20 +34,8 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
{ {
stringstream command_line_defines_with_endl; stringstream command_line_defines_with_endl;
for (const auto & [var, val] : defines) for (const auto & [var, val] : defines)
try
{
stoi(val);
command_line_defines_with_endl << "@#define " << var << " = " << val << endl; command_line_defines_with_endl << "@#define " << var << " = " << val << endl;
} Driver m(env);
catch (const invalid_argument &)
{
if (!val.empty() && val.at(0) == '[' && val.at(val.length()-1) == ']')
// If the input is an array. Issue #1578
command_line_defines_with_endl << "@#define " << var << " = " << val << endl;
else
command_line_defines_with_endl << "@#define " << var << R"( = ")" << val << '"' << endl;
}
Driver m(env, true);
istream is(command_line_defines_with_endl.rdbuf()); istream is(command_line_defines_with_endl.rdbuf());
m.parse("command_line_defines", "command_line_defines", is, output, debug, vector<pair<string, string>>{}, paths); m.parse("command_line_defines", "command_line_defines", is, output, debug, vector<pair<string, string>>{}, paths);
} }
...@@ -73,10 +62,10 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi ...@@ -73,10 +62,10 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
{ {
if (printLine) if (printLine)
{ {
statement->printLineInfo(output, no_line_macro); statement->printLineInfo(output);
printLine = false; printLine = false;
} }
statement->interpret(output, no_line_macro, paths); statement->interpret(output, paths);
} }
} }
......
/* /*
* Copyright © 2019 Dynare Team * Copyright © 2019-2020 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -46,9 +46,7 @@ namespace macro ...@@ -46,9 +46,7 @@ namespace macro
class TokenizerFlex : public TokenizerFlexLexer class TokenizerFlex : public TokenizerFlexLexer
{ {
public: public:
TokenizerFlex(istream *in) : TokenizerFlexLexer{in} TokenizerFlex(istream *in) : TokenizerFlexLexer{in} { }
{
}
TokenizerFlex(const TokenizerFlex &) = delete; TokenizerFlex(const TokenizerFlex &) = delete;
TokenizerFlex(TokenizerFlex &&) = delete; TokenizerFlex(TokenizerFlex &&) = delete;
TokenizerFlex &operator=(const TokenizerFlex &) = delete; TokenizerFlex &operator=(const TokenizerFlex &) = delete;
...@@ -66,14 +64,11 @@ namespace macro ...@@ -66,14 +64,11 @@ namespace macro
public: public:
Environment &env; Environment &env;
private: private:
bool no_line_macro;
vector<DirectivePtr> statements; vector<DirectivePtr> statements;
stack<vector<DirectivePtr>> directive_stack; stack<vector<DirectivePtr>> directive_stack;
public: public:
Driver(Environment &env_arg, bool no_line_macro_arg) : Driver(Environment &env_arg) :
env{env_arg}, no_line_macro(no_line_macro_arg) env{env_arg} { }
{
}
Driver(const Driver &) = delete; Driver(const Driver &) = delete;
Driver(Driver &&) = delete; Driver(Driver &&) = delete;
Driver &operator=(const Driver &) = delete; Driver &operator=(const Driver &) = delete;
......
...@@ -67,7 +67,7 @@ Environment::getFunction(const string &name) const ...@@ -67,7 +67,7 @@ Environment::getFunction(const string &name) const
} }
codes::BaseType codes::BaseType
Environment::getType(const string &name) Environment::getType(const string &name) const
{ {
return getVariable(name)->eval()->getType(); return getVariable(name)->eval()->getType();
} }
......
...@@ -34,37 +34,21 @@ namespace macro ...@@ -34,37 +34,21 @@ namespace macro
map<string, ExpressionPtr> variables; map<string, ExpressionPtr> variables;
map<string, tuple<FunctionPtr, ExpressionPtr>> functions; map<string, tuple<FunctionPtr, ExpressionPtr>> functions;
public: public:
Environment() : parent{nullptr} Environment() : parent{nullptr} { }
{ Environment(const Environment *parent_arg) : parent{parent_arg} { }
}
Environment(const Environment *parent_arg) : parent{parent_arg}
{
}
void define(VariablePtr var, ExpressionPtr value); void define(VariablePtr var, ExpressionPtr value);
void define(FunctionPtr func, ExpressionPtr value); void define(FunctionPtr func, ExpressionPtr value);
ExpressionPtr getVariable(const string &name) const; ExpressionPtr getVariable(const string &name) const;
tuple<FunctionPtr, ExpressionPtr> getFunction(const string &name) const; tuple<FunctionPtr, ExpressionPtr> getFunction(const string &name) const;
codes::BaseType getType(const string &name); codes::BaseType getType(const string &name) const;
bool isVariableDefined(const string &name) const noexcept; bool isVariableDefined(const string &name) const noexcept;
bool isFunctionDefined(const string &name) const noexcept; bool isFunctionDefined(const string &name) const noexcept;
inline bool inline bool isSymbolDefined(const string &name) const noexcept { return isVariableDefined(name) || isFunctionDefined(name); }
isSymbolDefined(const string &name) const noexcept
{
return isVariableDefined(name) || isFunctionDefined(name);
}
void print(ostream &output, const vector<string> &vars, 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 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; void printFunction(ostream &output, const tuple<FunctionPtr, ExpressionPtr> &function, int line, bool save) const;
inline size_t inline size_t size() const noexcept { return variables.size() + functions.size(); }
size() const noexcept inline const Environment *getGlobalEnv() const noexcept { return parent == nullptr ? this : parent->getGlobalEnv(); }
{
return variables.size() + functions.size();
}
inline const Environment *
getGlobalEnv() const noexcept
{
return parent == nullptr ? this : parent->getGlobalEnv();
}
}; };
} }
#endif #endif
This diff is collapsed.