From 90b9b6a1e4dd5be0fd8d44cf86ac7f664698d68b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Fri, 5 Jun 2020 16:07:52 +0200
Subject: [PATCH] JSON output: write model local variables in parsed model
 (modfile.json)

Ref. dynare#1723
---
 src/DynamicModel.cc |  7 +++++--
 src/ModelTree.cc    | 21 ++++++++++++---------
 src/ModelTree.hh    |  4 +++-
 src/StaticModel.cc  |  7 +++++--
 4 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index b1e3af60..629b3ec3 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -5603,6 +5603,9 @@ DynamicModel::isChecksumMatching(const string &basename, bool block) const
 void
 DynamicModel::writeJsonOutput(ostream &output) const
 {
+  deriv_node_temp_terms_t tef_terms;
+  writeJsonModelLocalVariables(output, false, tef_terms);
+  output << ", ";
   writeJsonModelEquations(output, false);
   output << ", ";
   writeJsonXrefs(output);
@@ -5778,7 +5781,7 @@ DynamicModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) c
   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] << ", ";
@@ -5866,7 +5869,7 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
   ostringstream g3p_output; // 1st deriv. of 3rd deriv. matrix w.r.t. parameters
 
   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)
diff --git a/src/ModelTree.cc b/src/ModelTree.cc
index 2545cafe..5fbd7fd8 100644
--- a/src/ModelTree.cc
+++ b/src/ModelTree.cc
@@ -1356,7 +1356,7 @@ ModelTree::compileTemporaryTerms(ostream &code_file, unsigned int &instruction_n
 }
 
 void
-ModelTree::writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t &tef_terms) const
+ModelTree::writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, deriv_node_temp_terms_t &tef_terms) const
 {
   /* Collect all model local variables appearing in equations, and print only
      them. Printing unused model local variables can lead to a crash (see
@@ -1380,19 +1380,22 @@ ModelTree::writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t
           printed = true;
 
         int id = it;
-        vector<string> efout;
         expr_t value = local_variables_table.find(id)->second;
-        value->writeJsonExternalFunctionOutput(efout, tt, tef_terms);
-        for (auto it1 = efout.begin(); it1 != efout.end(); ++it1)
+        if (write_tef_terms)
           {
-            if (it1 != efout.begin())
+            vector<string> efout;
+            value->writeJsonExternalFunctionOutput(efout, tt, tef_terms);
+            for (auto it1 = efout.begin(); it1 != efout.end(); ++it1)
+              {
+                if (it1 != efout.begin())
+                  output << ", ";
+                output << *it1;
+              }
+
+            if (!efout.empty())
               output << ", ";
-            output << *it1;
           }
 
-        if (!efout.empty())
-          output << ", ";
-
         output << R"({"variable": ")" << symbol_table.getName(id)
                << R"(", "value": ")";
         value->writeJsonOutput(output, tt, tef_terms);
diff --git a/src/ModelTree.hh b/src/ModelTree.hh
index 77741fa9..a5cc30c8 100644
--- a/src/ModelTree.hh
+++ b/src/ModelTree.hh
@@ -257,7 +257,9 @@ protected:
   //! if residuals = true, we are writing the dynamic/static model.
   //! Otherwise, just the model equations (with line numbers, no tmp terms)
   void writeJsonModelEquations(ostream &output, bool residuals) const;
-  void writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t &tef_terms) const;
+  /* Writes JSON model local variables.
+     Optionally put the external function variable calls into TEF terms */
+  void writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, deriv_node_temp_terms_t &tef_terms) const;
   //! Compiles model equations
   void compileModelEquations(ostream &code_file, unsigned int &instruction_number, bool dynamic, bool steady_dynamic, const temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs) const;
 
diff --git a/src/StaticModel.cc b/src/StaticModel.cc
index ebfb747d..ad5fd35d 100644
--- a/src/StaticModel.cc
+++ b/src/StaticModel.cc
@@ -2245,6 +2245,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);
 }
 
@@ -2257,7 +2260,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] << ", ";
@@ -2344,7 +2347,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)
-- 
GitLab