diff --git a/preprocessor/DataTree.cc b/preprocessor/DataTree.cc index b970df20d..69adc2e68 100644 --- a/preprocessor/DataTree.cc +++ b/preprocessor/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/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index 282dde822..599b6a0f4 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -72,6 +72,8 @@ class ParsingDriver; { string *string_val; NodeID node_val; + SymbolType symbol_type_val; + vector *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 value value1 vec_int_elem vec_int_1 vec_int %type vec_value_1 vec_value %type calib_arg2 range number +%type change_type_arg +%type 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(); $$->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/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll index df7c9bb0f..7aedffccf 100644 --- a/preprocessor/DynareFlex.ll +++ b/preprocessor/DynareFlex.ll @@ -113,7 +113,7 @@ int sigma_e = 0; dynatype {BEGIN DYNARE_STATEMENT; return token::DYNATYPE;} dynasave {BEGIN DYNARE_STATEMENT; return token::DYNASAVE;} model_comparison {BEGIN DYNARE_STATEMENT; return token::MODEL_COMPARISON;} - +change_type {BEGIN DYNARE_STATEMENT; return token::CHANGE_TYPE;} load_params_and_steady_state {BEGIN DYNARE_STATEMENT; return token::LOAD_PARAMS_AND_STEADY_STATE;} save_params_and_steady_state {BEGIN DYNARE_STATEMENT; return token::SAVE_PARAMS_AND_STEADY_STATE;} @@ -214,6 +214,12 @@ int sigma_e = 0; diffuse_filter {return token::DIFFUSE_FILTER;} plot_priors {return token::PLOT_PRIORS;} + /* These four (var, varexo, varexo_det, parameters) are for change_type */ +var { return token::VAR; } +varexo { return token::VAREXO; } +varexo_det { return token::VAREXO_DET; } +parameters { return token::PARAMETERS; } + bvar_prior_tau { return token::BVAR_PRIOR_TAU; } bvar_prior_decay { return token::BVAR_PRIOR_DECAY; } bvar_prior_lambda { return token::BVAR_PRIOR_LAMBDA; } diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index 81d095f52..159e9efce 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/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 *var_list) +{ + for(vector::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/preprocessor/include/DataTree.hh b/preprocessor/include/DataTree.hh index 0b25a8924..16195a40f 100644 --- a/preprocessor/include/DataTree.hh +++ b/preprocessor/include/DataTree.hh @@ -164,6 +164,8 @@ public: NodeID AddUnknownFunction(const string &function_name, const vector &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/preprocessor/include/ParsingDriver.hh b/preprocessor/include/ParsingDriver.hh index dcf2c2ed4..9976a4631 100644 --- a/preprocessor/include/ParsingDriver.hh +++ b/preprocessor/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 *var_list); //! Adds a constant to DataTree NodeID add_constant(string *constant); //! Adds a NaN constant to DataTree