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.
*
......@@ -1413,8 +1413,12 @@ ParsingDriver::option_symbol_list(string name_option)
{
vector<string> shocks = symbol_list.get_symbols();
for (auto &shock : shocks)
if (mod_file->symbol_table.getType(shock) != SymbolType::exogenous)
error("Variables passed to irf_shocks must be exogenous. Caused by: " + shock);
{
if (!mod_file->symbol_table.exists(shock))
error("Unknown symbol: " + shock);
if (mod_file->symbol_table.getType(shock) != SymbolType::exogenous)
error("Variables passed to irf_shocks must be exogenous. Caused by: " + shock);
}
}
if (name_option.compare("ms.parameters") == 0)
......@@ -1931,7 +1935,7 @@ ParsingDriver::set_corr_options(const string &name1, const string &name2, const
void
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();
options_list.clear();
}
......@@ -2222,14 +2226,20 @@ ParsingDriver::evaluate_planner_objective()
void
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"))
{
declare_parameter("optimal_policy_discount_factor");
init_param("optimal_policy_discount_factor", data_tree->One);
}
declare_parameter("optimal_policy_discount_factor");
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));
symbol_list.clear();
options_list.clear();
planner_discount = nullptr;
}
void
......@@ -2446,27 +2456,6 @@ ParsingDriver::conditional_forecast_paths()
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
ParsingDriver::calib_smoother()
{
......@@ -2532,7 +2521,9 @@ ParsingDriver::declare_and_init_model_local_variable(const string &name, expr_t
}
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);
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");
......
......@@ -716,9 +716,6 @@ public:
void conditional_forecast_paths();
//! Plot conditional forecast statement
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
void calib_smoother();
//! Extended path
......
/*
* Copyright © 2006-2019 Dynare Team
* Copyright © 2006-2020 Dynare Team
*
* This file is part of Dynare.
*
......@@ -53,9 +53,9 @@ void
NativeStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
{
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]))))";
sregex regex_lookbehind = sregex::compile(R"((?<!\$|\d|[a-zA-Z_]|\'))" + date_regex);
sregex regex_dollar = sregex::compile(R"((\$))"+date_regex);
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_dollar = sregex::compile(R"((\$))" + date_regex);
string ns = regex_replace(native_statement, regex_lookbehind, "dates('$&')");
ns = regex_replace(ns, regex_dollar, "$2"); //replace $DATE with DATE
......
/*
* Copyright © 2006-2019 Dynare Team
* Copyright © 2006-2020 Dynare Team
*
* This file is part of Dynare.
*
......@@ -134,6 +134,9 @@ public:
/* Whether any of shock_decomposition, realtime_shock_decomposition and
initial_condition_decomposition has the “with_epilogue” option */
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
......
......@@ -164,7 +164,7 @@ StaticModel::StaticModel(const DynamicModel &m) :
// Detect if equation is marked [dynamic]
bool is_dynamic_only = false;
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)
{
eq_tags.push_back(tag_pair);
......@@ -410,7 +410,7 @@ StaticModel::writeModelEquationsOrdered_M(const string &basename) const
output << " global options_;" << endl;
//The Temporary terms
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())
{
......@@ -2107,6 +2107,14 @@ StaticModel::writeOutput(ostream &output, bool block) const
output << temporary_terms_derivative.size() << "; ";
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)
return;
......@@ -2125,7 +2133,7 @@ StaticModel::writeOutput(ostream &output, bool block) const
}
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 << ").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 << ").variable = [" << tmp_s.str() << "];" << endl;
}
......@@ -2753,6 +2761,9 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
void
StaticModel::writeJsonOutput(ostream &output) const
{
deriv_node_temp_terms_t tef_terms;
writeJsonModelLocalVariables(output, false, tef_terms);
output << ", ";
writeJsonModelEquations(output, false);
}
......@@ -2765,7 +2776,7 @@ StaticModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) co
deriv_node_temp_terms_t tef_terms;
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, "");
d_output[0] << ", ";
......@@ -2852,7 +2863,7 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
ostringstream third_derivs1_output; // Used for storing third order derivatives equations
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;
for (const auto &it : params_derivs_temporary_terms)
......
/*
* Copyright © 2003-2019 Dynare Team
* Copyright © 2003-2020 Dynare Team
*
* This file is part of Dynare.
*
......@@ -34,10 +34,21 @@ SymbolList::addSymbol(const string &symbol)
}
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;
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)
{
if (!symbol_table->exists(symbol))
......@@ -53,8 +64,64 @@ SymbolList::checkPass(WarningConsolidation &warnings) const noexcept(false)
throw SymbolListException{"Variable " + symbol + " was not declared."};
}
if (symbol_table->getType(symbol) != SymbolType::endogenous)
throw SymbolListException{"Variable " + symbol + " is not endogenous."};
bool type_found = false;
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
unique_symbols.push_back(it);
else
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;
}
......@@ -54,7 +54,7 @@ public:
//! Removed duplicate symbols
void removeDuplicates(const string &dynare_command, WarningConsolidation &warnings);
//! 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
/*! Creates a string array for Matlab, stored in variable "varname" */
void writeOutput(const string &varname, ostream &output) const;
......
......@@ -1096,3 +1096,12 @@ SymbolTable::getUltimateOrigSymbID(int symb_id) const
}
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:
repeatedly call getOrigSymbIDForAuxVar() until an original
(non-auxiliary) variable is found. */
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
......
/*
* Copyright © 2019 Dynare Team
* Copyright © 2019-2021 Dynare Team
*
* This file is part of Dynare.
*
......@@ -25,7 +25,7 @@
using namespace macro;
void
Eval::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths)
Eval::interpret(ostream &output, vector<filesystem::path> &paths)
{
try
{
......@@ -43,7 +43,7 @@ Eval::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &p
}
void
Include::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths)
Include::interpret(ostream &output, vector<filesystem::path> &paths)
{
using namespace filesystem;
try
......@@ -71,7 +71,7 @@ Include::interpret(ostream &output, bool no_line_macro, vector<filesystem::path>
+". 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
// 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
......@@ -86,10 +86,11 @@ Include::interpret(ostream &output, bool no_line_macro, vector<filesystem::path>
{
error(StackTrace("@#include", e.what(), location));
}
printLineInfo(output);
}
void
IncludePath::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths)
IncludePath::interpret(ostream &output, vector<filesystem::path> &paths)
{
using namespace filesystem;
try
......@@ -116,7 +117,7 @@ IncludePath::interpret(ostream &output, bool no_line_macro, vector<filesystem::p
}
void
Define::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths)
Define::interpret(ostream &output, vector<filesystem::path> &paths)
{
try
{
......@@ -139,7 +140,7 @@ Define::interpret(ostream &output, bool no_line_macro, vector<filesystem::path>
}
void
Echo::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths)
Echo::interpret(ostream &output, vector<filesystem::path> &paths)
{
try
{
......@@ -154,11 +155,11 @@ Echo::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &p
{
error(StackTrace("@#echo", e.what(), location));
}
printEndLineInfo(output, no_line_macro);
printEndLineInfo(output);
}
void
Error::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths)
Error::interpret(ostream &output, vector<filesystem::path> &paths)
{
try
{
......@@ -176,17 +177,17 @@ Error::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &
}
void
EchoMacroVars::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths)
EchoMacroVars::interpret(ostream &output, vector<filesystem::path> &paths)
{
if (save)
env.print(output, vars, location.begin.line, true);
else
env.print(cout, vars);
printEndLineInfo(output, no_line_macro);
printEndLineInfo(output);
}
void
For::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths)
For::interpret(ostream &output, vector<filesystem::path> &paths)
{
ArrayPtr ap;
try
......@@ -232,31 +233,49 @@ For::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &pa
{
if (printLine)
{
statement->printLineInfo(output, no_line_macro);
statement->printLineInfo(output);
printLine = false;
}
statement->interpret(output, no_line_macro, paths);
statement->interpret(output, paths);
}
}
printEndLineInfo(output, no_line_macro);
printEndLineInfo(output);
}
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)
try
{
auto tmp = expr->eval();
RealPtr dp = dynamic_pointer_cast<Real>(tmp);
BoolPtr bp = dynamic_pointer_cast<Bool>(tmp);
if (!bp && !dp)
error(StackTrace("@#if",
"The condition must evaluate to a boolean or a double", location));
if ((bp && *bp) || (dp && *dp))
if ((ifdef || ifndef) && first_clause)
{
interpretBody(body, output, no_line_macro, paths);
break;
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();
RealPtr dp = dynamic_pointer_cast<Real>(tmp);
BoolPtr bp = dynamic_pointer_cast<Bool>(tmp);
if (!bp && !dp)
error(StackTrace("@#if",
"The condition must evaluate to a boolean or a double", location));
if ((bp && *bp) || (dp && *dp))
{
interpretBody(body, output, paths);
break;
}
}
}
catch (StackTrace &ex)
......@@ -268,48 +287,20 @@ If::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &pat
{
error(StackTrace("@#if", e.what(), location));
}
printEndLineInfo(output, no_line_macro);
printEndLineInfo(output);
}
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)
{
if (printLine)
{
statement->printLineInfo(output, no_line_macro);
statement->printLineInfo(output);
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.
*
......@@ -30,13 +30,13 @@ namespace macro
{
// A Parent class just for clarity
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
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 for text not interpreted by macroprocessor
......@@ -46,16 +46,11 @@ namespace macro
const string text;
public:
TextNode(string text_arg, Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), text{move(text_arg)}
{
}
inline void
interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override
{
output << text;
}
Directive(env_arg, move(location_arg)), text{move(text_arg)} { }
inline void interpret(ostream &output, vector<filesystem::path> &paths) override { output << text; }
};
class Eval : public Directive
{
// Class for @{} statements
......@@ -65,36 +60,33 @@ namespace macro
const ExpressionPtr expr;
public:
Eval(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)}
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
void interpret(ostream &output, vector<filesystem::path> &paths) override;
};
class Include : public Directive
{
private:
const ExpressionPtr expr;
public:
Include(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)}
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
void interpret(ostream &output, vector<filesystem::path> &paths) override;
};
class IncludePath : public Directive
{
private:
const ExpressionPtr expr;
public:
IncludePath(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)}
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
void interpret(ostream &output, vector<filesystem::path> &paths) override;
};
class Define : public Directive
{
private:
......@@ -105,18 +97,15 @@ namespace macro
Define(VariablePtr var_arg,
ExpressionPtr value_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,
ExpressionPtr value_arg,
Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), func{move(func_arg)}, value{move(value_arg)}
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
Directive(env_arg, move(location_arg)), func{move(func_arg)}, value{move(value_arg)} { }
void interpret(ostream &output, vector<filesystem::path> &paths) override;
};
class Echo : public Directive
{
private:
......@@ -124,12 +113,11 @@ namespace macro
public:
Echo(ExpressionPtr expr_arg,
Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)}
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
void interpret(ostream &output, vector<filesystem::path> &paths) override;
};
class Error : public Directive
{
private:
......@@ -137,12 +125,11 @@ namespace macro
public:
Error(ExpressionPtr expr_arg,
Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)}
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
void interpret(ostream &output, vector<filesystem::path> &paths) override;
};
class EchoMacroVars : public Directive
{
private:
......@@ -151,17 +138,14 @@ namespace macro
public:
EchoMacroVars(bool save_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,
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, vector<filesystem::path> &paths) override;
Directive(env_arg, move(location_arg)), save{save_arg}, vars{move(vars_arg)} { }
void interpret(ostream &output, vector<filesystem::path> &paths) override;
};
class For : public Directive
{
private:
......@@ -174,12 +158,11 @@ namespace macro
vector<DirectivePtr> statements_arg,
Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), index_vec{move(index_vec_arg)},
index_vals{move(index_vals_arg)}, statements{move(statements_arg)}
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
index_vals{move(index_vals_arg)}, statements{move(statements_arg)} { }
void interpret(ostream &output, vector<filesystem::path> &paths) override;
};
class If : public Directive
{
protected:
......@@ -192,15 +175,17 @@ namespace macro
* 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 bool ifdef, ifndef;
public:
If(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr_and_body{move(expr_and_body_arg)}
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
Environment &env_arg, Tokenizer::location location_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, vector<filesystem::path> &paths) override;
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
......@@ -208,21 +193,16 @@ namespace macro
public:
Ifdef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
Environment &env_arg, Tokenizer::location location_arg) :
If(move(expr_and_body_arg), env_arg, move(location_arg))
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
If(move(expr_and_body_arg), env_arg, move(location_arg), true, false) { }
};
class Ifndef : public If
{
public:
Ifndef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
Environment &env_arg, Tokenizer::location location_arg) :
If(move(expr_and_body_arg), env_arg, move(location_arg))
{
}
void interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &paths) override;
If(move(expr_and_body_arg), env_arg, move(location_arg), false, true) { }
};
}
#endif
/*
* Copyright © 2019 Dynare Team
* Copyright © 2019-2020 Dynare Team
*
* This file is part of Dynare.
*
......@@ -18,6 +18,7 @@
*/
#include "Driver.hh"
#include <regex>
using namespace macro;
......@@ -33,20 +34,8 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
{
stringstream command_line_defines_with_endl;
for (const auto & [var, val] : defines)
try
{
stoi(val);
command_line_defines_with_endl << "@#define " << var << " = " << val << endl;
}
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);
command_line_defines_with_endl << "@#define " << var << " = " << val << endl;
Driver m(env);
istream is(command_line_defines_with_endl.rdbuf());
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
{
if (printLine)
{
statement->printLineInfo(output, no_line_macro);
statement->printLineInfo(output);
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.
*
......@@ -46,9 +46,7 @@ namespace macro
class TokenizerFlex : public TokenizerFlexLexer
{
public:
TokenizerFlex(istream *in) : TokenizerFlexLexer{in}
{
}
TokenizerFlex(istream *in) : TokenizerFlexLexer{in} { }
TokenizerFlex(const TokenizerFlex &) = delete;
TokenizerFlex(TokenizerFlex &&) = delete;
TokenizerFlex &operator=(const TokenizerFlex &) = delete;
......@@ -66,14 +64,11 @@ namespace macro
public:
Environment &env;
private:
bool no_line_macro;
vector<DirectivePtr> statements;
stack<vector<DirectivePtr>> directive_stack;
public:
Driver(Environment &env_arg, bool no_line_macro_arg) :
env{env_arg}, no_line_macro(no_line_macro_arg)
{
}
Driver(Environment &env_arg) :
env{env_arg} { }
Driver(const Driver &) = delete;
Driver(Driver &&) = delete;
Driver &operator=(const Driver &) = delete;
......
......@@ -67,7 +67,7 @@ Environment::getFunction(const string &name) const
}
codes::BaseType
Environment::getType(const string &name)
Environment::getType(const string &name) const
{
return getVariable(name)->eval()->getType();
}
......
......@@ -34,37 +34,21 @@ namespace macro
map<string, ExpressionPtr> variables;
map<string, tuple<FunctionPtr, ExpressionPtr>> functions;
public:
Environment() : parent{nullptr}
{
}
Environment(const Environment *parent_arg) : parent{parent_arg}
{
}
Environment() : parent{nullptr} { }
Environment(const Environment *parent_arg) : parent{parent_arg} { }
void define(VariablePtr var, ExpressionPtr value);
void define(FunctionPtr func, ExpressionPtr value);
ExpressionPtr getVariable(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 isFunctionDefined(const string &name) const noexcept;
inline bool
isSymbolDefined(const string &name) const noexcept
{
return isVariableDefined(name) || isFunctionDefined(name);
}
inline bool 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 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();
}
inline size_t size() const noexcept { return variables.size() + functions.size(); }
inline const Environment *getGlobalEnv() const noexcept { return parent == nullptr ? this : parent->getGlobalEnv(); }
};
}
#endif
This diff is collapsed.