From 301c9691d99042903f3b25a15521efc74b34414d Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Mon, 27 Feb 2017 15:40:34 +0100
Subject: [PATCH] preprocessor: JSON output aesthetic fixes, support planner
 objective. #1387

---
 ComputingTasks.cc | 18 ++++++++-----
 ComputingTasks.hh |  1 +
 DynamicModel.cc   |  2 +-
 ModFile.cc        |  4 +--
 ModelTree.cc      |  4 +--
 StaticModel.cc    |  8 +++++-
 StaticModel.hh    |  3 +++
 SymbolTable.cc    | 68 +++++++++++------------------------------------
 8 files changed, 43 insertions(+), 65 deletions(-)

diff --git a/ComputingTasks.cc b/ComputingTasks.cc
index ae5a6f22..8240e9fc 100644
--- a/ComputingTasks.cc
+++ b/ComputingTasks.cc
@@ -668,9 +668,8 @@ RamseyPolicyStatement::writeJsonOutput(ostream &output) const
     {
       output << ", ";
       options_list.writeJsonOutput(output);
-      output << ", ";
     }
-  output << "\"ramsey_policy_list\": [";
+  output << ", \"ramsey_policy_list\": [";
   for (vector<string>::const_iterator it = ramsey_policy_list.begin();
        it != ramsey_policy_list.end(); ++it)
     {
@@ -1827,7 +1826,8 @@ ModelComparisonStatement::writeJsonOutput(ostream &output) const
 }
 
 PlannerObjectiveStatement::PlannerObjectiveStatement(StaticModel *model_tree_arg) :
-  model_tree(model_tree_arg)
+  model_tree(model_tree_arg),
+  computing_pass_called(false)
 {
 }
 
@@ -1860,6 +1860,7 @@ void
 PlannerObjectiveStatement::computingPass()
 {
   model_tree->computingPass(eval_context_t(), false, true, true, none, false, false);
+  computing_pass_called = true;
 }
 
 void
@@ -1871,9 +1872,14 @@ PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename,
 void
 PlannerObjectiveStatement::writeJsonOutput(ostream &output) const
 {
-  cerr << "ERROR: writeJsonOutput not yet implemented for Planner Objective Statement" << endl;
-  exit(EXIT_FAILURE);
-  //  model_tree->writeStaticJsonFile(basename + "_objective", false, false, false, false);
+  output << "{\"statementName\": \"planner_objective\""
+         << ", ";
+  if (computing_pass_called)
+    model_tree->writeJsonComputingPassOutput(output);
+  else
+    model_tree->writeJsonOutput(output);
+
+  output << "}";
 }
 
 BVARDensityStatement::BVARDensityStatement(int maxnlags_arg, const OptionsList &options_list_arg) :
diff --git a/ComputingTasks.hh b/ComputingTasks.hh
index 49dcdbe8..6cec3e38 100644
--- a/ComputingTasks.hh
+++ b/ComputingTasks.hh
@@ -449,6 +449,7 @@ class PlannerObjectiveStatement : public Statement
 {
 private:
   StaticModel *model_tree;
+  bool computing_pass_called;
 public:
   //! Constructor
   /*! \param model_tree_arg the model tree used to store the objective function.
diff --git a/DynamicModel.cc b/DynamicModel.cc
index edcc5f3a..1c35f3cb 100644
--- a/DynamicModel.cc
+++ b/DynamicModel.cc
@@ -5364,7 +5364,7 @@ DynamicModel::writeJsonComputingPassOutput(ostream &output) const
   writeJsonModelLocalVariables(model_local_vars_output, tef_terms);
 
   writeJsonTemporaryTerms(temporary_terms_res, temp_term_union_m_1, model_output, tef_terms, concat);
-
+  model_output << ", ";
   writeJsonModelEquations(model_output, true);
 
   // Writing Jacobian
diff --git a/ModFile.cc b/ModFile.cc
index 4cf0ba1b..4228a393 100644
--- a/ModFile.cc
+++ b/ModFile.cc
@@ -1291,11 +1291,12 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType
   output << "{" << endl;
 
   symbol_table.writeJsonOutput(output);
+  output << ", ";
   dynamic_model.writeJsonOutput(output);
 
   if (!statements.empty())
     {
-      output << ",\"statements\": [";
+      output << ", \"statements\": [";
       for (vector<Statement *>::const_iterator it = statements.begin();
            it != statements.end(); it++)
         {
@@ -1305,7 +1306,6 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType
         }
       output << "]" << endl;
     }
-
   output << "}" << endl;
 
   if (json_output_mode == standardout)
diff --git a/ModelTree.cc b/ModelTree.cc
index a2cc7df3..02b4c93d 100644
--- a/ModelTree.cc
+++ b/ModelTree.cc
@@ -2028,9 +2028,9 @@ ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const
   vector<pair<string,string> > eqtags;
   temporary_terms_t tt_empty;
   if (residuals)
-    output << endl << ",\"residuals\":[" << endl;
+    output << endl << "\"residuals\":[" << endl;
   else
-    output << endl << ",\"model\":[" << endl;
+    output << endl << "\"model\":[" << endl;
   for (int eq = 0; eq < (int) equations.size(); eq++)
     {
       if (eq > 0)
diff --git a/StaticModel.cc b/StaticModel.cc
index 4516a886..71e631ee 100644
--- a/StaticModel.cc
+++ b/StaticModel.cc
@@ -2415,6 +2415,12 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
   paramsDerivsFile.close();
 }
 
+void
+StaticModel::writeJsonOutput(ostream &output) const
+{
+  writeJsonModelEquations(output, false);
+}
+
 void
 StaticModel::writeJsonComputingPassOutput(ostream &output) const
 {
@@ -2434,7 +2440,7 @@ StaticModel::writeJsonComputingPassOutput(ostream &output) const
   writeJsonModelLocalVariables(model_local_vars_output, tef_terms);
 
   writeJsonTemporaryTerms(temporary_terms_res, temp_term_union_m_1, model_output, tef_terms, concat);
-
+  model_output << ", ";
   writeJsonModelEquations(model_output, true);
 
   int nrows = equations.size();
diff --git a/StaticModel.hh b/StaticModel.hh
index 04d41e14..75ab0b3f 100644
--- a/StaticModel.hh
+++ b/StaticModel.hh
@@ -173,6 +173,9 @@ public:
   //! Writes static model file
   void writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, bool julia) const;
 
+  //! Write JSON Output (used by PlannerObjectiveStatement)
+  void writeJsonOutput(ostream &output) const;
+
   //! Write JSON representation of static model
   void writeJsonComputingPassOutput(ostream &output) const;
 
diff --git a/SymbolTable.cc b/SymbolTable.cc
index d6150183..9db683db 100644
--- a/SymbolTable.cc
+++ b/SymbolTable.cc
@@ -965,57 +965,18 @@ SymbolTable::writeJuliaOutput(ostream &output) const throw (NotYetFrozenExceptio
 
 void
 SymbolTable::writeJsonOutput(ostream &output) const
-{/*
-  vector<int> endos, exos, exo_dets, params;
-  for (int i = 0; i < size; i++)
-    {
-      switch (getType(i))
-        {
-        case eEndogenous:
-          endos.push_back(i);
-          break;
-        case eExogenous:
-          exos.push_back(i);
-          break;
-        case eExogenousDet:
-          exo_dets.push_back(i);
-          break;
-        case eParameter:
-          params.push_back(i);
-          break;
-        default:
-          break;
-        }
-    }
- */
-
-  if (!endo_ids.empty())
-    {
-      output << "\"endogenous\":";
-      writeJsonVarVector(output, endo_ids);
-      output << endl;
-    }
+{
+  output << "\"endogenous\": ";
+  writeJsonVarVector(output, endo_ids);
 
-  if (!exo_ids.empty())
-    {
-      output << ",\"exogenous\":";
-      writeJsonVarVector(output, exo_ids);
-      output << endl;
-    }
+  output << ", \"exogenous\":" ;
+  writeJsonVarVector(output, exo_ids);
 
-  if (!exo_det_ids.empty())
-    {
-      output << ",\"exogenous_deterministic\":";
-      writeJsonVarVector(output, exo_det_ids);
-      output << endl;
-    }
+  output << ", \"exogenous_deterministic\": ";
+  writeJsonVarVector(output, exo_det_ids);
 
-  if (!param_ids.empty())
-    {
-      output << ",\"parameters\":";
-      writeJsonVarVector(output, param_ids);
-      cout << endl;
-    }
+  output << ", \"parameters\": ";
+  writeJsonVarVector(output, param_ids);
 }
 
 void
@@ -1024,12 +985,13 @@ SymbolTable::writeJsonVarVector(ostream &output, const vector<int> &varvec) cons
   output << "[";
   for (size_t i = 0; i < varvec.size(); i++)
     {
-      output << endl << "{"
+      if (i != 0)
+        output << ", ";
+      output << "{"
              << "\"name\":\"" << getName(varvec[i]) << "\", "
              << "\"texName\":\"" << boost::replace_all_copy(getTeXName(varvec[i]), "\\", "\\\\") << "\", "
-             << "\"longName\":\"" << boost::replace_all_copy(getLongName(varvec[i]), "\\", "\\\\") << "\"}";
-      if (i < varvec.size() - 1)
-        output << ", ";
+             << "\"longName\":\"" << boost::replace_all_copy(getLongName(varvec[i]), "\\", "\\\\") << "\"}"
+             << endl;
     }
-  output << endl << "]";
+  output << "]" << endl;
 }
-- 
GitLab