From aad8414f94b30a3024bdb759897f100036bf3e95 Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Mon, 10 Dec 2018 16:11:21 +0100
Subject: [PATCH] allow the use of previously assigned variables in epilogue
 block in later equations in epilogue block

---
 src/CodeInterpreter.hh    |  3 ++-
 src/ExprNode.cc           | 20 ++++++++++++++++++++
 src/ModelEquationBlock.cc |  8 ++++----
 src/ModelEquationBlock.hh |  4 ++--
 src/ParsingDriver.cc      |  5 +++--
 5 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/src/CodeInterpreter.hh b/src/CodeInterpreter.hh
index a29f03bc..e347588b 100644
--- a/src/CodeInterpreter.hh
+++ b/src/CodeInterpreter.hh
@@ -152,7 +152,8 @@ enum class SymbolType
     statementDeclaredVariable = 14, //!< Local variable assigned within a Statement (see subsample statement for example)
     logTrend = 15,                 //!< Log-trend variable
     unusedEndogenous = 16,
-    endogenousVAR = 17             //!< Variables declared in a var_model statement
+    endogenousVAR = 17,            //!< Variables declared in a var_model statement
+    epilogue = 18                  //!< Variables created in epilogue block
   };
 
 enum ExpressionType
diff --git a/src/ExprNode.cc b/src/ExprNode.cc
index ba901edc..3ae2cde1 100644
--- a/src/ExprNode.cc
+++ b/src/ExprNode.cc
@@ -755,6 +755,7 @@ VariableNode::prepareForDerivation()
       break;
     case SymbolType::externalFunction:
     case SymbolType::endogenousVAR:
+    case SymbolType::epilogue:
       cerr << "VariableNode::prepareForDerivation: impossible case" << endl;
       exit(EXIT_FAILURE);
     }
@@ -788,6 +789,7 @@ VariableNode::computeDerivative(int deriv_id)
       exit(EXIT_FAILURE);
     case SymbolType::externalFunction:
     case SymbolType::endogenousVAR:
+    case SymbolType::epilogue:
       cerr << "VariableNode::computeDerivative: Impossible case!" << endl;
       exit(EXIT_FAILURE);
     }
@@ -854,6 +856,9 @@ VariableNode::writeJsonAST(ostream &output) const
     case SymbolType::endogenousVAR:
       output << "endogenousVAR";
       break;
+    case SymbolType::epilogue:
+      output << "epilogue";
+      break;
     }
   output << "\", \"lag\" : " << lag << "}";
 }
@@ -1108,6 +1113,19 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
           exit(EXIT_FAILURE);
         }
       break;
+    case SymbolType::epilogue:
+      if (output_type == ExprNodeOutputType::epilogueFile)
+        {
+          output << "dseries__." << datatree.symbol_table.getName(symb_id);
+          if (lag != 0)
+            output << LEFT_ARRAY_SUBSCRIPT(output_type) << lag << RIGHT_ARRAY_SUBSCRIPT(output_type);
+          break;
+        }
+      else
+        {
+          cerr << "VariableNode::writeOutput: Impossible case" << endl;
+          exit(EXIT_FAILURE);
+        }
     case SymbolType::externalFunction:
     case SymbolType::trend:
     case SymbolType::logTrend:
@@ -1334,6 +1352,7 @@ VariableNode::getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recur
       exit(EXIT_FAILURE);
     case SymbolType::externalFunction:
     case SymbolType::endogenousVAR:
+    case SymbolType::epilogue:
       cerr << "VariableNode::getChainRuleDerivative: Impossible case" << endl;
       exit(EXIT_FAILURE);
     }
@@ -1372,6 +1391,7 @@ VariableNode::computeXrefs(EquationInfo &ei) const
     case SymbolType::unusedEndogenous:
     case SymbolType::externalFunction:
     case SymbolType::endogenousVAR:
+    case SymbolType::epilogue:
       break;
     }
 }
diff --git a/src/ModelEquationBlock.cc b/src/ModelEquationBlock.cc
index cdd5d123..ee153b42 100644
--- a/src/ModelEquationBlock.cc
+++ b/src/ModelEquationBlock.cc
@@ -314,9 +314,9 @@ Epilogue::operator=(const Epilogue &m)
 }
 
 void
-Epilogue::addDefinition(string varname, expr_t expr)
+Epilogue::addDefinition(int symb_id, expr_t expr)
 {
-  def_table.emplace_back(varname, expr);
+  def_table.emplace_back(symb_id, expr);
 }
 
 void
@@ -325,7 +325,7 @@ Epilogue::checkPass(WarningConsolidation &warnings) const
   if (def_table.size() == 0)
     return;
 
-  vector<string> so_far_defined;
+  vector<int> so_far_defined;
   for (const auto & it : def_table)
     if (find(so_far_defined.begin(), so_far_defined.end(), it.first) != so_far_defined.end())
       {
@@ -366,7 +366,7 @@ Epilogue::writeEpilogueFile(const string &basename) const
   output << endl;
   for (const auto & it : def_table)
     {
-      output << "dseries__." << it.first << " = ";
+      output << "dseries__." << symbol_table.getName(it.first) << " = ";
       it.second->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms);
       output << ";" << endl;
     }
diff --git a/src/ModelEquationBlock.hh b/src/ModelEquationBlock.hh
index d9cdeb2c..cb6cc606 100644
--- a/src/ModelEquationBlock.hh
+++ b/src/ModelEquationBlock.hh
@@ -70,7 +70,7 @@ class Epilogue : public DynamicModel
 {
 private:
   //! Associates a set of symbol IDs (the variable(s) assigned in a given statement) to an expression (their assigned value)
-  vector<pair<string, expr_t>> def_table;
+  vector<pair<int, expr_t>> def_table;
 public:
   Epilogue(SymbolTable &symbol_table_arg,
            NumericalConstants &num_constants_arg,
@@ -84,7 +84,7 @@ public:
   Epilogue & operator=(Epilogue &&) = delete;
 
   //! Add an expression of the form "var = expr;"
-  void addDefinition(string varname, expr_t expr);
+  void addDefinition(int symb_id, expr_t expr);
 
   //! Checks that no variable is declared twice
   void checkPass(WarningConsolidation &warnings) const;
diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc
index 25efbb73..5714c81b 100644
--- a/src/ParsingDriver.cc
+++ b/src/ParsingDriver.cc
@@ -833,9 +833,10 @@ ParsingDriver::end_epilogue()
 }
 
 void
-ParsingDriver::add_epilogue_equal(const string &varname, expr_t expr)
+ParsingDriver::add_epilogue_equal(const string &name, expr_t expr)
 {
-  mod_file->epilogue.addDefinition(varname, expr);
+  declare_symbol(name, SymbolType::epilogue, "", {});
+  mod_file->epilogue.addDefinition(mod_file->symbol_table.getID(name), expr);
 }
 
 void
-- 
GitLab