From 80aa9562ec87ca2fc8f0ffd1463faa9d451aa7e9 Mon Sep 17 00:00:00 2001
From: sebastien <sebastien@ac1d8469-bf42-47a9-8791-bf33cf982152>
Date: Wed, 11 Mar 2009 11:43:18 +0000
Subject: [PATCH] trunk preprocessor: added new "change_type" command

git-svn-id: https://www.dynare.org/svn/dynare/trunk@2452 ac1d8469-bf42-47a9-8791-bf33cf982152
---
 DataTree.cc              | 15 +++++++++++++++
 DynareBison.yy           | 41 +++++++++++++++++++++++++++++++---------
 DynareFlex.ll            |  8 +++++++-
 ParsingDriver.cc         | 28 +++++++++++++++++++++++++++
 include/DataTree.hh      |  2 ++
 include/ParsingDriver.hh |  2 ++
 6 files changed, 86 insertions(+), 10 deletions(-)

diff --git a/DataTree.cc b/DataTree.cc
index b970df20..69adc2e6 100644
--- a/DataTree.cc
+++ b/DataTree.cc
@@ -441,3 +441,18 @@ DataTree::fillEvalContext(eval_context_type &eval_context) const
         }
     }
 }
+
+bool
+DataTree::isSymbolUsed(int symb_id) const
+{
+  for(variable_node_map_type::const_iterator it = variable_node_map.begin();
+      it != variable_node_map.end(); it++)
+    if (it->first.first == symb_id)
+      return true;
+
+  if (local_variables_table.find(symb_id) != local_variables_table.end())
+    return true;
+
+  return false;
+}
+
diff --git a/DynareBison.yy b/DynareBison.yy
index 282dde82..599b6a0f 100644
--- a/DynareBison.yy
+++ b/DynareBison.yy
@@ -72,6 +72,8 @@ class ParsingDriver;
 {
   string *string_val;
   NodeID node_val;
+  SymbolType symbol_type_val;
+  vector<string *> *vector_string_val;
 };
 
 %{
@@ -90,7 +92,7 @@ class ParsingDriver;
 %token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA
 %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN
 %token BVAR_REPLIC
-%token CALIB CALIB_VAR CHECK CONF_SIG CONSTANT CORR COVAR CUTOFF
+%token CALIB CALIB_VAR CHANGE_TYPE CHECK CONF_SIG CONSTANT CORR COVAR CUTOFF
 %token DATAFILE DR_ALGO DROP DSAMPLE DYNASAVE DYNATYPE
 %token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT
 %token FILENAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS
@@ -147,6 +149,8 @@ class ParsingDriver;
 %type <string_val> value value1 vec_int_elem vec_int_1 vec_int
 %type <string_val> vec_value_1 vec_value
 %type <string_val> calib_arg2 range number
+%type <symbol_type_val> change_type_arg
+%type <vector_string_val> change_type_var_list
 
 %%
 
@@ -156,7 +160,11 @@ statement_list : statement
                | statement_list statement
                ;
 
-statement : declaration
+statement : parameters
+          | var
+          | varexo
+          | varexo_det
+          | change_type
           | periods
           | cutoff
           | markowitz
@@ -204,13 +212,6 @@ statement : declaration
           | save_params_and_steady_state
           ;
 
-declaration : parameters
-            | var
-            | varexo
-            | varexo_det
-            ;
-
-
 dsample : DSAMPLE INT_NUMBER ';'
           { driver.dsample($2); }
         | DSAMPLE INT_NUMBER INT_NUMBER ';'
@@ -283,6 +284,28 @@ parameter_list : parameter_list NAME
                  { driver.declare_parameter($1, $2); }
                ;
 
+change_type : CHANGE_TYPE '(' change_type_arg ')' change_type_var_list ';'
+              { driver.change_type($3, $5); }
+            ;
+
+change_type_arg : PARAMETERS
+                  { $$ = eParameter; }
+                | VAR
+                  { $$ = eEndogenous; }
+                | VAREXO
+                  { $$ = eExogenous; }
+                | VAREXO_DET
+                  { $$ = eExogenousDet; }
+                ;
+
+change_type_var_list : NAME
+                       { $$ = new vector<string *>(); $$->push_back($1); }
+                     | change_type_var_list NAME
+                       { $$ = $1; $1->push_back($2); }
+                     | change_type_var_list COMMA NAME
+                       { $$ = $1; $1->push_back($3); }
+                     ;
+
 periods : PERIODS INT_NUMBER ';'
           { driver.periods($2); }
         | PERIODS EQUAL INT_NUMBER ';'
diff --git a/DynareFlex.ll b/DynareFlex.ll
index df7c9bb0..7aedffcc 100644
--- a/DynareFlex.ll
+++ b/DynareFlex.ll
@@ -113,7 +113,7 @@ int sigma_e = 0;
 <INITIAL>dynatype	{BEGIN DYNARE_STATEMENT; return token::DYNATYPE;}
 <INITIAL>dynasave 	{BEGIN DYNARE_STATEMENT; return token::DYNASAVE;}
 <INITIAL>model_comparison 	{BEGIN DYNARE_STATEMENT; return token::MODEL_COMPARISON;}
-
+<INITIAL>change_type  {BEGIN DYNARE_STATEMENT; return token::CHANGE_TYPE;}
 <INITIAL>load_params_and_steady_state  {BEGIN DYNARE_STATEMENT; return token::LOAD_PARAMS_AND_STEADY_STATE;}
 <INITIAL>save_params_and_steady_state  {BEGIN DYNARE_STATEMENT; return token::SAVE_PARAMS_AND_STEADY_STATE;}
 
@@ -214,6 +214,12 @@ int sigma_e = 0;
 <DYNARE_STATEMENT>diffuse_filter {return token::DIFFUSE_FILTER;}
 <DYNARE_STATEMENT>plot_priors   {return token::PLOT_PRIORS;}
 
+ /* These four (var, varexo, varexo_det, parameters) are for change_type */
+<DYNARE_STATEMENT>var { return token::VAR; }
+<DYNARE_STATEMENT>varexo { return token::VAREXO; }
+<DYNARE_STATEMENT>varexo_det { return token::VAREXO_DET; }
+<DYNARE_STATEMENT>parameters { return token::PARAMETERS; }
+
 <DYNARE_STATEMENT>bvar_prior_tau { return token::BVAR_PRIOR_TAU; }
 <DYNARE_STATEMENT>bvar_prior_decay { return token::BVAR_PRIOR_DECAY; }
 <DYNARE_STATEMENT>bvar_prior_lambda { return token::BVAR_PRIOR_LAMBDA; }
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index 81d095f5..159e9efc 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -1102,6 +1102,34 @@ ParsingDriver::declare_and_init_model_local_variable(string *name, NodeID rhs)
   delete name;
 }
 
+void
+ParsingDriver::change_type(SymbolType new_type, vector<string *> *var_list)
+{
+  for(vector<string *>::iterator it = var_list->begin();
+      it != var_list->end(); it++)
+    {
+      int id;
+      try
+        {
+          id = mod_file->symbol_table.getID(**it);
+        }
+      catch(SymbolTable::UnknownSymbolNameException &e)
+        {
+          error("Unknown variable " + **it);
+        }
+
+      // Check if symbol already used in a VariableNode
+      if (mod_file->expressions_tree.isSymbolUsed(id)
+          || mod_file->model_tree.isSymbolUsed(id))
+        error("You cannot modify the type of symbol " + **it + " after having used it in an expression");
+
+      mod_file->symbol_table.changeType(id, new_type);
+
+      delete *it;
+    }
+  delete var_list;
+}
+
 NodeID
 ParsingDriver::add_plus(NodeID arg1, NodeID arg2)
 {
diff --git a/include/DataTree.hh b/include/DataTree.hh
index 0b25a892..16195a40 100644
--- a/include/DataTree.hh
+++ b/include/DataTree.hh
@@ -164,6 +164,8 @@ public:
   NodeID AddUnknownFunction(const string &function_name, const vector<NodeID> &arguments);
   //! Fill eval context with values of local variables
   void fillEvalContext(eval_context_type &eval_context) const;
+  //! Checks if a given symbol is used somewhere in the data tree
+  bool isSymbolUsed(int symb_id) const;
 };
 
 inline NodeID
diff --git a/include/ParsingDriver.hh b/include/ParsingDriver.hh
index dcf2c2ed..9976a463 100644
--- a/include/ParsingDriver.hh
+++ b/include/ParsingDriver.hh
@@ -187,6 +187,8 @@ public:
   void declare_parameter(string *name, string *tex_name = new string);
   //! Declares and initializes a local parameter
   void declare_and_init_model_local_variable(string *name, NodeID rhs);
+  //! Changes type of a symbol
+  void change_type(SymbolType new_type, vector<string *> *var_list);
   //! Adds a constant to DataTree
   NodeID add_constant(string *constant);
   //! Adds a NaN constant to DataTree
-- 
GitLab