2008-02-03 11:28:36 +01:00
/*
2010-02-22 17:33:38 +01:00
* Copyright ( C ) 2003 - 2010 Dynare Team
2008-02-03 11:28:36 +01:00
*
* This file is part of Dynare .
*
* Dynare is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Dynare is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with Dynare . If not , see < http : //www.gnu.org/licenses/>.
*/
2008-06-28 13:20:45 +02:00
# include <cstdlib>
2008-02-03 11:28:36 +01:00
# include <fstream>
# include <iostream>
2010-02-22 17:33:38 +01:00
# include <cassert>
2008-02-03 11:28:36 +01:00
# include "ParsingDriver.hh"
# include "Statement.hh"
2010-04-06 11:07:19 +02:00
# include "ExprNode.hh"
2008-02-03 11:28:36 +01:00
bool
2010-02-22 17:33:38 +01:00
ParsingDriver : : symbol_exists_and_is_not_modfile_local_or_external_function ( const char * s )
2008-02-03 11:28:36 +01:00
{
if ( ! mod_file - > symbol_table . exists ( s ) )
return false ;
2009-02-26 11:46:54 +01:00
SymbolType type = mod_file - > symbol_table . getType ( s ) ;
2010-02-22 17:33:38 +01:00
return ( type ! = eModFileLocalVariable & & type ! = eExternalFunction ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : check_symbol_existence ( const string & name )
{
if ( ! mod_file - > symbol_table . exists ( name ) )
error ( " Unknown symbol: " + name ) ;
}
void
ParsingDriver : : set_current_data_tree ( DataTree * data_tree_arg )
{
data_tree = data_tree_arg ;
model_tree = dynamic_cast < ModelTree * > ( data_tree_arg ) ;
2009-07-07 16:20:48 +02:00
dynamic_model = dynamic_cast < DynamicModel * > ( data_tree_arg ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : reset_data_tree ( )
{
set_current_data_tree ( & mod_file - > expressions_tree ) ;
}
2010-02-22 17:33:38 +01:00
void
ParsingDriver : : reset_current_external_function_options ( )
{
current_external_function_options . nargs = eExtFunSetDefaultNargs ;
current_external_function_options . firstDerivSymbID = eExtFunNotSet ;
current_external_function_options . secondDerivSymbID = eExtFunNotSet ;
2010-02-24 15:10:11 +01:00
current_external_function_id = eExtFunNotSet ;
2010-02-22 17:33:38 +01:00
}
2008-02-03 11:28:36 +01:00
ModFile *
2008-03-28 18:38:10 +01:00
ParsingDriver : : parse ( istream & in , bool debug )
2008-02-03 11:28:36 +01:00
{
mod_file = new ModFile ( ) ;
2008-04-07 15:14:40 +02:00
symbol_list . clear ( ) ;
2008-02-03 11:28:36 +01:00
reset_data_tree ( ) ;
2009-01-22 16:05:38 +01:00
estim_params . init ( * data_tree ) ;
2010-02-22 17:33:38 +01:00
reset_current_external_function_options ( ) ;
2008-02-03 11:28:36 +01:00
lexer = new DynareFlex ( & in ) ;
2008-03-28 18:21:45 +01:00
lexer - > set_debug ( debug ) ;
2008-02-03 11:28:36 +01:00
Dynare : : parser parser ( * this ) ;
2008-03-28 18:21:45 +01:00
parser . set_debug_level ( debug ) ;
2008-02-03 11:28:36 +01:00
parser . parse ( ) ;
delete lexer ;
return mod_file ;
}
void
ParsingDriver : : error ( const Dynare : : parser : : location_type & l , const string & m )
{
cerr < < " ERROR: " < < l < < " : " < < m < < endl ;
2008-10-29 16:33:16 +01:00
exit ( EXIT_FAILURE ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : error ( const string & m )
{
error ( location , m ) ;
}
void
ParsingDriver : : warning ( const string & m )
{
cerr < < " WARNING: " < < location < < " : " < < m < < endl ;
}
void
2010-02-23 19:08:54 +01:00
ParsingDriver : : declare_symbol ( const string * name , SymbolType type , const string * tex_name )
2008-02-03 11:28:36 +01:00
{
try
{
2009-04-30 15:14:33 +02:00
if ( tex_name = = NULL )
mod_file - > symbol_table . addSymbol ( * name , type ) ;
else
mod_file - > symbol_table . addSymbol ( * name , type , * tex_name ) ;
2008-02-03 11:28:36 +01:00
}
2009-12-16 18:13:23 +01:00
catch ( SymbolTable : : AlreadyDeclaredException & e )
2008-02-03 11:28:36 +01:00
{
if ( e . same_type )
warning ( " Symbol " + * name + " declared twice. " ) ;
else
error ( " Symbol " + * name + " declared twice with different types! " ) ;
}
}
void
ParsingDriver : : declare_endogenous ( string * name , string * tex_name )
{
declare_symbol ( name , eEndogenous , tex_name ) ;
2010-02-22 17:33:38 +01:00
delete name ;
if ( tex_name ! = NULL )
delete tex_name ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : declare_exogenous ( string * name , string * tex_name )
{
declare_symbol ( name , eExogenous , tex_name ) ;
2010-02-22 17:33:38 +01:00
delete name ;
if ( tex_name ! = NULL )
delete tex_name ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : declare_exogenous_det ( string * name , string * tex_name )
{
declare_symbol ( name , eExogenousDet , tex_name ) ;
2010-02-22 17:33:38 +01:00
delete name ;
if ( tex_name ! = NULL )
delete tex_name ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : declare_parameter ( string * name , string * tex_name )
{
declare_symbol ( name , eParameter , tex_name ) ;
2010-02-22 17:33:38 +01:00
delete name ;
if ( tex_name ! = NULL )
delete tex_name ;
2008-02-03 11:28:36 +01:00
}
2009-11-07 19:37:11 +01:00
void
ParsingDriver : : add_predetermined_variable ( string * name )
{
2009-11-09 12:03:18 +01:00
try
{
int symb_id = mod_file - > symbol_table . getID ( * name ) ;
if ( mod_file - > symbol_table . getType ( symb_id ) ! = eEndogenous )
error ( " Predetermined variables must be endogenous variables " ) ;
mod_file - > symbol_table . markPredetermined ( symb_id ) ;
}
2009-12-16 18:13:23 +01:00
catch ( SymbolTable : : UnknownSymbolNameException & e )
2009-11-09 12:03:18 +01:00
{
error ( " Undeclared symbol name: " + * name ) ;
}
2009-11-07 19:37:11 +01:00
delete name ;
}
2009-09-02 16:37:59 +02:00
void
ParsingDriver : : add_equation_tags ( string * key , string * value )
{
int n = model_tree - > equation_number ( ) ;
model_tree - > addEquationTags ( n , * key , * value ) ;
delete key ;
delete value ;
}
2008-02-03 11:28:36 +01:00
NodeID
ParsingDriver : : add_constant ( string * constant )
{
NodeID id = data_tree - > AddNumConstant ( * constant ) ;
delete constant ;
return id ;
}
2009-01-22 16:05:38 +01:00
NodeID
ParsingDriver : : add_nan_constant ( )
{
return data_tree - > NaN ;
}
NodeID
ParsingDriver : : add_inf_constant ( )
{
return data_tree - > Infinity ;
}
2008-02-03 11:28:36 +01:00
NodeID
ParsingDriver : : add_model_variable ( string * name )
{
2010-02-22 17:33:38 +01:00
check_symbol_existence ( * name ) ;
int symb_id = mod_file - > symbol_table . getID ( * name ) ;
delete name ;
return add_model_variable ( symb_id , 0 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
2010-02-22 17:33:38 +01:00
ParsingDriver : : add_model_variable ( int symb_id , int lag )
2008-02-03 11:28:36 +01:00
{
2010-02-22 17:33:38 +01:00
assert ( symb_id > = 0 ) ;
SymbolType type = mod_file - > symbol_table . getType ( symb_id ) ;
2008-02-03 11:28:36 +01:00
if ( type = = eModFileLocalVariable )
2010-02-22 17:33:38 +01:00
error ( " Variable " + mod_file - > symbol_table . getName ( symb_id ) + " not allowed inside model declaration. Its scope is only outside model. " ) ;
2008-02-03 11:28:36 +01:00
2010-02-22 17:33:38 +01:00
if ( type = = eExternalFunction )
error ( " Symbol " + mod_file - > symbol_table . getName ( symb_id ) + " is a function name external to Dynare. It cannot be used inside model. " ) ;
2008-10-13 18:44:20 +02:00
if ( type = = eModelLocalVariable & & lag ! = 0 )
2010-02-22 17:33:38 +01:00
error ( " Model local variable " + mod_file - > symbol_table . getName ( symb_id ) + " cannot be given a lead or a lag. " ) ;
2008-10-13 18:44:20 +02:00
// It makes sense to allow a lead/lag on parameters: during steady state calibration, endogenous and parameters can be swapped
2010-02-22 17:33:38 +01:00
return model_tree - > AddVariable ( symb_id , lag ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_expression_variable ( string * name )
{
// If symbol doesn't exist, then declare it as a mod file local variable
if ( ! mod_file - > symbol_table . exists ( * name ) )
mod_file - > symbol_table . addSymbol ( * name , eModFileLocalVariable ) ;
2008-10-17 14:22:35 +02:00
// This check must come after the previous one!
if ( mod_file - > symbol_table . getType ( * name ) = = eModelLocalVariable )
error ( " Variable " + * name + " not allowed outside model declaration. Its scope is only inside model. " ) ;
2010-03-16 12:23:59 +01:00
int symb_id = mod_file - > symbol_table . getID ( * name ) ;
NodeID id = data_tree - > AddVariable ( symb_id ) ;
2008-02-03 11:28:36 +01:00
delete name ;
return id ;
}
void
ParsingDriver : : periods ( string * periods )
{
2009-10-29 18:16:10 +01:00
warning ( " periods: this command is now deprecated and may be removed in a future version of Dynare. Please of the \" periods \" option of \" simul \" command instead. " ) ;
2008-02-03 11:28:36 +01:00
int periods_val = atoi ( periods - > c_str ( ) ) ;
mod_file - > addStatement ( new PeriodsStatement ( periods_val ) ) ;
delete periods ;
}
void
ParsingDriver : : dsample ( string * arg1 )
{
int arg1_val = atoi ( arg1 - > c_str ( ) ) ;
mod_file - > addStatement ( new DsampleStatement ( arg1_val ) ) ;
delete arg1 ;
}
void
ParsingDriver : : dsample ( string * arg1 , string * arg2 )
{
int arg1_val = atoi ( arg1 - > c_str ( ) ) ;
int arg2_val = atoi ( arg2 - > c_str ( ) ) ;
mod_file - > addStatement ( new DsampleStatement ( arg1_val , arg2_val ) ) ;
delete arg1 ;
delete arg2 ;
}
void
ParsingDriver : : init_param ( string * name , NodeID rhs )
{
check_symbol_existence ( * name ) ;
2009-02-27 13:19:25 +01:00
int symb_id = mod_file - > symbol_table . getID ( * name ) ;
if ( mod_file - > symbol_table . getType ( symb_id ) ! = eParameter )
2008-02-03 11:28:36 +01:00
error ( * name + " is not a parameter " ) ;
2009-02-27 13:19:25 +01:00
mod_file - > addStatement ( new InitParamStatement ( symb_id , rhs , mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
delete name ;
}
void
ParsingDriver : : init_val ( string * name , NodeID rhs )
{
check_symbol_existence ( * name ) ;
2009-02-27 13:19:25 +01:00
int symb_id = mod_file - > symbol_table . getID ( * name ) ;
SymbolType type = mod_file - > symbol_table . getType ( symb_id ) ;
2008-02-03 11:28:36 +01:00
if ( type ! = eEndogenous
& & type ! = eExogenous
& & type ! = eExogenousDet )
error ( " initval/endval: " + * name + " should be an endogenous or exogenous variable " ) ;
2009-02-27 13:19:25 +01:00
init_values . push_back ( make_pair ( symb_id , rhs ) ) ;
2008-02-03 11:28:36 +01:00
delete name ;
}
void
2008-04-14 09:22:10 +02:00
ParsingDriver : : initval_file ( string * filename )
2008-02-03 11:28:36 +01:00
{
2008-04-14 11:17:15 +02:00
mod_file - > addStatement ( new InitvalFileStatement ( * filename ) ) ;
2008-02-03 11:28:36 +01:00
delete filename ;
}
void
ParsingDriver : : hist_val ( string * name , string * lag , NodeID rhs )
{
check_symbol_existence ( * name ) ;
2009-02-27 13:19:25 +01:00
int symb_id = mod_file - > symbol_table . getID ( * name ) ;
SymbolType type = mod_file - > symbol_table . getType ( symb_id ) ;
2008-02-03 11:28:36 +01:00
if ( type ! = eEndogenous
& & type ! = eExogenous
& & type ! = eExogenousDet )
error ( " hist_val: " + * name + " should be an endogenous or exogenous variable " ) ;
int ilag = atoi ( lag - > c_str ( ) ) ;
2009-02-27 13:19:25 +01:00
pair < int , int > key ( symb_id , ilag ) ;
2008-02-03 11:28:36 +01:00
if ( hist_values . find ( key ) ! = hist_values . end ( ) )
error ( " hist_val: ( " + * name + " , " + * lag + " ) declared twice " ) ;
hist_values [ key ] = rhs ;
delete name ;
delete lag ;
}
void
ParsingDriver : : homotopy_val ( string * name , NodeID val1 , NodeID val2 )
{
check_symbol_existence ( * name ) ;
2009-02-27 13:19:25 +01:00
int symb_id = mod_file - > symbol_table . getID ( * name ) ;
SymbolType type = mod_file - > symbol_table . getType ( symb_id ) ;
2008-02-03 11:28:36 +01:00
if ( type ! = eParameter
& & type ! = eExogenous
& & type ! = eExogenousDet )
error ( " homotopy_val: " + * name + " should be a parameter or exogenous variable " ) ;
2009-02-27 13:19:25 +01:00
homotopy_values . push_back ( make_pair ( symb_id , make_pair ( val1 , val2 ) ) ) ;
2008-02-03 11:28:36 +01:00
delete name ;
}
2008-05-01 14:04:48 +02:00
void
ParsingDriver : : forecast ( )
{
mod_file - > addStatement ( new ForecastStatement ( symbol_list , options_list ) ) ;
symbol_list . clear ( ) ;
options_list . clear ( ) ;
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : use_dll ( )
{
2009-09-02 15:36:56 +02:00
mod_file - > use_dll = true ;
2008-02-03 11:28:36 +01:00
}
void
2009-08-29 17:04:11 +02:00
ParsingDriver : : block ( )
2008-02-03 11:28:36 +01:00
{
2009-08-29 17:04:11 +02:00
mod_file - > block = true ;
2008-02-03 11:28:36 +01:00
}
2010-01-08 12:06:25 +01:00
void
ParsingDriver : : no_static ( )
{
mod_file - > no_static = true ;
}
2008-02-03 11:28:36 +01:00
void
2009-08-29 17:04:11 +02:00
ParsingDriver : : byte_code ( )
2008-02-03 11:28:36 +01:00
{
2009-08-29 17:04:11 +02:00
mod_file - > byte_code = true ;
2008-02-03 11:28:36 +01:00
}
2009-09-03 12:10:06 +02:00
void
ParsingDriver : : cutoff ( string * value )
{
double val = atof ( value - > c_str ( ) ) ;
mod_file - > dynamic_model . cutoff = val ;
2009-12-16 14:21:31 +01:00
mod_file - > static_model . cutoff = val ;
2009-09-03 12:10:06 +02:00
delete value ;
}
void
ParsingDriver : : mfs ( string * value )
{
int val = atoi ( value - > c_str ( ) ) ;
mod_file - > dynamic_model . mfs = val ;
2009-12-16 14:21:31 +01:00
mod_file - > static_model . mfs = val ;
2009-09-03 12:10:06 +02:00
delete value ;
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : end_initval ( )
{
2009-02-27 13:19:25 +01:00
mod_file - > addStatement ( new InitValStatement ( init_values , mod_file - > symbol_table ) ) ;
init_values . clear ( ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : end_endval ( )
{
2009-02-27 13:19:25 +01:00
mod_file - > addStatement ( new EndValStatement ( init_values , mod_file - > symbol_table ) ) ;
init_values . clear ( ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : end_histval ( )
{
mod_file - > addStatement ( new HistValStatement ( hist_values , mod_file - > symbol_table ) ) ;
hist_values . clear ( ) ;
}
void
ParsingDriver : : end_homotopy ( )
{
mod_file - > addStatement ( new HomotopyStatement ( homotopy_values , mod_file - > symbol_table ) ) ;
homotopy_values . clear ( ) ;
}
void
ParsingDriver : : begin_model ( )
{
2009-04-14 16:39:53 +02:00
set_current_data_tree ( & mod_file - > dynamic_model ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : end_shocks ( )
{
mod_file - > addStatement ( new ShocksStatement ( det_shocks , var_shocks , std_shocks ,
covar_shocks , corr_shocks , mod_file - > symbol_table ) ) ;
det_shocks . clear ( ) ;
var_shocks . clear ( ) ;
std_shocks . clear ( ) ;
covar_shocks . clear ( ) ;
corr_shocks . clear ( ) ;
}
void
ParsingDriver : : end_mshocks ( )
{
2009-10-29 18:16:10 +01:00
mod_file - > addStatement ( new MShocksStatement ( det_shocks , mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
det_shocks . clear ( ) ;
}
void
2009-10-16 19:23:57 +02:00
ParsingDriver : : add_det_shock ( string * var , bool conditional_forecast )
2008-02-03 11:28:36 +01:00
{
check_symbol_existence ( * var ) ;
2010-04-14 15:03:41 +02:00
int symb_id = mod_file - > symbol_table . getID ( * var ) ;
SymbolType type = mod_file - > symbol_table . getType ( symb_id ) ;
2009-10-16 19:23:57 +02:00
if ( conditional_forecast )
{
if ( type ! = eEndogenous )
error ( " conditional_forecast_paths: shocks can only be applied to exogenous variables " ) ;
}
else
{
if ( type ! = eExogenous & & type ! = eExogenousDet )
error ( " shocks: shocks can only be applied to exogenous variables " ) ;
}
2008-02-03 11:28:36 +01:00
2010-04-14 15:03:41 +02:00
if ( det_shocks . find ( symb_id ) ! = det_shocks . end ( ) )
2009-10-16 19:23:57 +02:00
error ( " shocks/conditional_forecast_paths: variable " + * var + " declared twice " ) ;
2008-02-03 11:28:36 +01:00
if ( det_shocks_periods . size ( ) ! = det_shocks_values . size ( ) )
2009-10-16 19:23:57 +02:00
error ( " shocks/conditional_forecast_paths: variable " + * var + " : number of periods is different from number of shock values " ) ;
2008-02-03 11:28:36 +01:00
vector < ShocksStatement : : DetShockElement > v ;
2009-12-16 18:13:23 +01:00
for ( unsigned int i = 0 ; i < det_shocks_periods . size ( ) ; i + + )
2008-02-03 11:28:36 +01:00
{
ShocksStatement : : DetShockElement dse ;
dse . period1 = det_shocks_periods [ i ] . first ;
dse . period2 = det_shocks_periods [ i ] . second ;
dse . value = det_shocks_values [ i ] ;
v . push_back ( dse ) ;
}
2010-04-14 15:03:41 +02:00
det_shocks [ symb_id ] = v ;
2008-02-03 11:28:36 +01:00
det_shocks_periods . clear ( ) ;
det_shocks_values . clear ( ) ;
delete var ;
}
void
ParsingDriver : : add_stderr_shock ( string * var , NodeID value )
{
check_symbol_existence ( * var ) ;
2010-04-14 15:03:41 +02:00
int symb_id = mod_file - > symbol_table . getID ( * var ) ;
SymbolType type = mod_file - > symbol_table . getType ( symb_id ) ;
if ( type ! = eExogenous & & ! mod_file - > symbol_table . isObservedVariable ( symb_id ) )
error ( " shocks: standard error can only be specified for exogenous or observed endogenous variables " ) ;
if ( var_shocks . find ( symb_id ) ! = var_shocks . end ( )
| | std_shocks . find ( symb_id ) ! = std_shocks . end ( ) )
2008-02-03 11:28:36 +01:00
error ( " shocks: variance or stderr of shock on " + * var + " declared twice " ) ;
2010-04-14 15:03:41 +02:00
std_shocks [ symb_id ] = value ;
2008-02-03 11:28:36 +01:00
delete var ;
}
void
ParsingDriver : : add_var_shock ( string * var , NodeID value )
{
check_symbol_existence ( * var ) ;
2010-04-14 15:03:41 +02:00
int symb_id = mod_file - > symbol_table . getID ( * var ) ;
SymbolType type = mod_file - > symbol_table . getType ( symb_id ) ;
if ( type ! = eExogenous & & ! mod_file - > symbol_table . isObservedVariable ( symb_id ) )
error ( " shocks: variance can only be specified for exogenous or observed endogenous variables " ) ;
if ( var_shocks . find ( symb_id ) ! = var_shocks . end ( )
| | std_shocks . find ( symb_id ) ! = std_shocks . end ( ) )
2008-02-03 11:28:36 +01:00
error ( " shocks: variance or stderr of shock on " + * var + " declared twice " ) ;
2010-04-14 15:03:41 +02:00
var_shocks [ symb_id ] = value ;
2008-02-03 11:28:36 +01:00
delete var ;
}
void
ParsingDriver : : add_covar_shock ( string * var1 , string * var2 , NodeID value )
{
check_symbol_existence ( * var1 ) ;
check_symbol_existence ( * var2 ) ;
2010-04-14 15:03:41 +02:00
int symb_id1 = mod_file - > symbol_table . getID ( * var1 ) ;
int symb_id2 = mod_file - > symbol_table . getID ( * var2 ) ;
2008-02-03 11:28:36 +01:00
2010-04-14 15:03:41 +02:00
SymbolType type1 = mod_file - > symbol_table . getType ( symb_id1 ) ;
SymbolType type2 = mod_file - > symbol_table . getType ( symb_id2 ) ;
if ( ! ( ( type1 = = eExogenous & & type2 = = eExogenous )
| | ( mod_file - > symbol_table . isObservedVariable ( symb_id1 ) & & mod_file - > symbol_table . isObservedVariable ( symb_id2 ) ) ) )
error ( " shocks: covariance can only be specified for exogenous or observed endogenous variables of same type " ) ;
pair < int , int > key ( symb_id1 , symb_id2 ) , key_inv ( symb_id2 , symb_id1 ) ;
2008-02-03 11:28:36 +01:00
if ( covar_shocks . find ( key ) ! = covar_shocks . end ( )
| | covar_shocks . find ( key_inv ) ! = covar_shocks . end ( )
| | corr_shocks . find ( key ) ! = corr_shocks . end ( )
| | corr_shocks . find ( key_inv ) ! = corr_shocks . end ( ) )
error ( " shocks: covariance or correlation shock on variable pair ( " + * var1 + " , "
+ * var2 + " ) declared twice " ) ;
covar_shocks [ key ] = value ;
delete var1 ;
delete var2 ;
}
void
ParsingDriver : : add_correl_shock ( string * var1 , string * var2 , NodeID value )
{
check_symbol_existence ( * var1 ) ;
check_symbol_existence ( * var2 ) ;
2010-04-14 15:03:41 +02:00
int symb_id1 = mod_file - > symbol_table . getID ( * var1 ) ;
int symb_id2 = mod_file - > symbol_table . getID ( * var2 ) ;
SymbolType type1 = mod_file - > symbol_table . getType ( symb_id1 ) ;
SymbolType type2 = mod_file - > symbol_table . getType ( symb_id2 ) ;
if ( ! ( ( type1 = = eExogenous & & type2 = = eExogenous )
| | ( mod_file - > symbol_table . isObservedVariable ( symb_id1 ) & & mod_file - > symbol_table . isObservedVariable ( symb_id2 ) ) ) )
error ( " shocks: correlation can only be specified for exogenous or observed endogenous variables of same type " ) ;
2008-02-03 11:28:36 +01:00
2010-04-14 15:03:41 +02:00
pair < int , int > key ( symb_id1 , symb_id2 ) , key_inv ( symb_id2 , symb_id1 ) ;
2008-02-03 11:28:36 +01:00
if ( covar_shocks . find ( key ) ! = covar_shocks . end ( )
| | covar_shocks . find ( key_inv ) ! = covar_shocks . end ( )
| | corr_shocks . find ( key ) ! = corr_shocks . end ( )
| | corr_shocks . find ( key_inv ) ! = corr_shocks . end ( ) )
error ( " shocks: covariance or correlation shock on variable pair ( " + * var1 + " , "
+ * var2 + " ) declared twice " ) ;
corr_shocks [ key ] = value ;
delete var1 ;
delete var2 ;
}
void
ParsingDriver : : add_period ( string * p1 , string * p2 )
{
int p1_val = atoi ( p1 - > c_str ( ) ) ;
int p2_val = atoi ( p2 - > c_str ( ) ) ;
2009-10-16 19:23:57 +02:00
if ( p1_val > p2_val )
error ( " shocks/conditional_forecast_paths: can't have first period index greater than second index in range specification " ) ;
2008-02-03 11:28:36 +01:00
det_shocks_periods . push_back ( make_pair ( p1_val , p2_val ) ) ;
delete p1 ;
delete p2 ;
}
void
ParsingDriver : : add_period ( string * p1 )
{
int p1_val = atoi ( p1 - > c_str ( ) ) ;
det_shocks_periods . push_back ( make_pair ( p1_val , p1_val ) ) ;
delete p1 ;
}
void
ParsingDriver : : add_value ( NodeID value )
{
det_shocks_values . push_back ( value ) ;
}
void
ParsingDriver : : add_value ( string * p1 )
{
det_shocks_values . push_back ( add_constant ( p1 ) ) ;
}
2009-12-04 22:32:19 +01:00
void
ParsingDriver : : end_svar_identification ( )
{
mod_file - > addStatement ( new SvarIdentificationStatement ( svar_ident_exclusion_values ,
svar_upper_cholesky ,
svar_lower_cholesky ,
mod_file - > symbol_table ) ) ;
svar_upper_cholesky = false ;
svar_lower_cholesky = false ;
svar_restriction_symbols . clear ( ) ;
svar_equation_restrictions . clear ( ) ;
svar_ident_exclusion_values . clear ( ) ;
}
void
ParsingDriver : : combine_lag_and_restriction ( string * lag )
{
int current_lag = atoi ( lag - > c_str ( ) ) ;
for ( SvarIdentificationStatement : : svar_identification_exclusion_type : : const_iterator it = svar_ident_exclusion_values . begin ( ) ;
it ! = svar_ident_exclusion_values . end ( ) ; it + + )
if ( it - > first . first = = current_lag )
error ( " lag " + * lag + " used more than once. " ) ;
2009-12-16 18:13:23 +01:00
for ( map < int , vector < int > > : : const_iterator it = svar_equation_restrictions . begin ( ) ;
it ! = svar_equation_restrictions . end ( ) ; it + + )
2009-12-04 22:32:19 +01:00
svar_ident_exclusion_values [ make_pair ( current_lag , it - > first ) ] = it - > second ;
svar_upper_cholesky = false ;
svar_lower_cholesky = false ;
svar_equation_restrictions . clear ( ) ;
delete lag ;
}
void
ParsingDriver : : add_restriction_in_equation ( string * equation )
{
int eqn = atoi ( equation - > c_str ( ) ) ;
if ( eqn < 1 )
error ( " equation numbers must be greater than or equal to 1. " ) ;
if ( svar_equation_restrictions . count ( eqn ) > 0 )
error ( " equation number " + * equation + " referenced more than once under a single lag. " ) ;
svar_equation_restrictions [ eqn ] = svar_restriction_symbols ;
svar_restriction_symbols . clear ( ) ;
delete equation ;
}
void
ParsingDriver : : add_in_svar_restriction_symbols ( string * tmp_var )
{
check_symbol_existence ( * tmp_var ) ;
2009-12-14 16:54:00 +01:00
int symb_id = mod_file - > symbol_table . getID ( * tmp_var ) ;
2009-12-16 18:13:23 +01:00
for ( vector < int > : : const_iterator viit = svar_restriction_symbols . begin ( ) ;
viit ! = svar_restriction_symbols . end ( ) ; viit + + )
if ( symb_id = = * viit )
2009-12-04 22:32:19 +01:00
error ( * tmp_var + " restriction added twice. " ) ;
2009-12-14 16:54:00 +01:00
svar_restriction_symbols . push_back ( symb_id ) ;
2009-12-04 22:32:19 +01:00
delete tmp_var ;
}
void
ParsingDriver : : add_upper_cholesky ( )
{
svar_upper_cholesky = true ;
svar_lower_cholesky = false ;
}
void
ParsingDriver : : add_lower_cholesky ( )
{
svar_upper_cholesky = false ;
svar_lower_cholesky = true ;
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : do_sigma_e ( )
{
2009-10-29 18:16:10 +01:00
warning ( " Sigma_e: this command is now deprecated and may be removed in a future version of Dynare. Please use the \" shocks \" command instead. " ) ;
2008-02-03 11:28:36 +01:00
try
{
mod_file - > addStatement ( new SigmaeStatement ( sigmae_matrix ) ) ;
}
2009-12-16 18:13:23 +01:00
catch ( SigmaeStatement : : MatrixFormException & e )
2008-02-03 11:28:36 +01:00
{
error ( " Sigma_e: matrix is neither upper triangular nor lower triangular " ) ;
}
sigmae_matrix . clear ( ) ;
}
void
ParsingDriver : : end_of_row ( )
{
sigmae_matrix . push_back ( sigmae_row ) ;
sigmae_row . clear ( ) ;
}
void
ParsingDriver : : add_to_row_const ( string * s )
{
sigmae_row . push_back ( add_constant ( s ) ) ;
}
void
ParsingDriver : : add_to_row ( NodeID v )
{
sigmae_row . push_back ( v ) ;
}
void
ParsingDriver : : steady ( )
{
2009-09-02 15:36:56 +02:00
mod_file - > addStatement ( new SteadyStatement ( options_list ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
void
ParsingDriver : : option_num ( const string & name_option , string * opt1 , string * opt2 )
{
if ( options_list . paired_num_options . find ( name_option )
! = options_list . paired_num_options . end ( ) )
error ( " option " + name_option + " declared twice " ) ;
options_list . paired_num_options [ name_option ] = make_pair ( * opt1 , * opt2 ) ;
delete opt1 ;
delete opt2 ;
}
void
ParsingDriver : : option_num ( const string & name_option , string * opt )
{
option_num ( name_option , * opt ) ;
delete opt ;
}
void
ParsingDriver : : option_num ( const string & name_option , const string & opt )
{
2009-12-01 18:51:47 +01:00
if ( options_list . num_options . find ( name_option ) ! = options_list . num_options . end ( ) )
2008-02-03 11:28:36 +01:00
error ( " option " + name_option + " declared twice " ) ;
options_list . num_options [ name_option ] = opt ;
}
void
ParsingDriver : : option_str ( const string & name_option , string * opt )
{
option_str ( name_option , * opt ) ;
delete opt ;
}
void
ParsingDriver : : option_str ( const string & name_option , const string & opt )
{
if ( options_list . string_options . find ( name_option )
! = options_list . string_options . end ( ) )
error ( " option " + name_option + " declared twice " ) ;
options_list . string_options [ name_option ] = opt ;
}
2008-04-04 20:40:20 +02:00
void
2008-04-07 15:14:40 +02:00
ParsingDriver : : option_symbol_list ( const string & name_option )
2008-04-04 20:40:20 +02:00
{
2008-04-07 15:14:40 +02:00
if ( options_list . symbol_list_options . find ( name_option )
! = options_list . symbol_list_options . end ( ) )
2008-04-04 20:40:20 +02:00
error ( " option " + name_option + " declared twice " ) ;
2008-04-07 15:14:40 +02:00
options_list . symbol_list_options [ name_option ] = symbol_list ;
symbol_list . clear ( ) ;
2008-04-04 20:40:20 +02:00
}
2009-12-10 23:49:50 +01:00
void
ParsingDriver : : option_vec_int ( const string & name_option , const vector < int > * opt )
{
if ( options_list . vector_int_options . find ( name_option )
! = options_list . vector_int_options . end ( ) )
error ( " option " + name_option + " declared twice " ) ;
2009-12-14 16:54:00 +01:00
if ( ( * opt ) . empty ( ) )
error ( " option " + name_option + " was passed an empty vector. " ) ;
2009-12-10 23:49:50 +01:00
options_list . vector_int_options [ name_option ] = * opt ;
2009-12-14 16:54:00 +01:00
delete opt ;
2009-12-10 23:49:50 +01:00
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : linear ( )
{
mod_file - > linear = true ;
}
void
2008-04-07 15:14:40 +02:00
ParsingDriver : : add_in_symbol_list ( string * tmp_var )
2008-02-03 11:28:36 +01:00
{
2008-04-11 16:41:52 +02:00
if ( * tmp_var ! = " : " )
check_symbol_existence ( * tmp_var ) ;
2008-04-07 15:14:40 +02:00
symbol_list . addSymbol ( * tmp_var ) ;
2008-02-03 11:28:36 +01:00
delete tmp_var ;
}
2009-12-16 18:13:23 +01:00
void
ParsingDriver : : rplot ( )
2008-02-03 11:28:36 +01:00
{
2008-04-07 15:14:40 +02:00
mod_file - > addStatement ( new RplotStatement ( symbol_list , options_list ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
2008-04-07 15:14:40 +02:00
symbol_list . clear ( ) ;
2008-02-03 11:28:36 +01:00
}
2009-12-16 18:13:23 +01:00
void
ParsingDriver : : stoch_simul ( )
2008-02-03 11:28:36 +01:00
{
2009-09-02 18:44:15 +02:00
mod_file - > addStatement ( new StochSimulStatement ( symbol_list , options_list ) ) ;
2008-04-07 15:14:40 +02:00
symbol_list . clear ( ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
void
ParsingDriver : : simul ( )
{
2009-09-02 18:44:15 +02:00
mod_file - > addStatement ( new SimulStatement ( options_list ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
2008-08-25 17:06:36 +02:00
void
ParsingDriver : : model_info ( )
{
2008-08-29 14:31:25 +02:00
mod_file - > addStatement ( new ModelInfoStatement ( options_list ) ) ;
2008-08-25 17:06:36 +02:00
options_list . clear ( ) ;
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : check ( )
{
mod_file - > addStatement ( new CheckStatement ( options_list ) ) ;
options_list . clear ( ) ;
}
void
ParsingDriver : : add_estimated_params_element ( )
{
check_symbol_existence ( estim_params . name ) ;
if ( estim_params . name2 . size ( ) > 0 )
check_symbol_existence ( estim_params . name2 ) ;
estim_params_list . push_back ( estim_params ) ;
2009-01-22 16:05:38 +01:00
estim_params . init ( * data_tree ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : estimated_params ( )
{
mod_file - > addStatement ( new EstimatedParamsStatement ( estim_params_list , mod_file - > symbol_table ) ) ;
estim_params_list . clear ( ) ;
}
void
ParsingDriver : : estimated_params_init ( )
{
mod_file - > addStatement ( new EstimatedParamsInitStatement ( estim_params_list , mod_file - > symbol_table ) ) ;
estim_params_list . clear ( ) ;
}
void
ParsingDriver : : estimated_params_bounds ( )
{
mod_file - > addStatement ( new EstimatedParamsBoundsStatement ( estim_params_list , mod_file - > symbol_table ) ) ;
estim_params_list . clear ( ) ;
}
void
ParsingDriver : : set_unit_root_vars ( )
{
2008-04-07 15:14:40 +02:00
mod_file - > addStatement ( new UnitRootVarsStatement ( symbol_list ) ) ;
symbol_list . clear ( ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : run_estimation ( )
{
2008-04-07 15:14:40 +02:00
mod_file - > addStatement ( new EstimationStatement ( symbol_list , options_list ) ) ;
symbol_list . clear ( ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
void
ParsingDriver : : dynare_sensitivity ( )
{
mod_file - > addStatement ( new DynareSensitivityStatement ( options_list ) ) ;
options_list . clear ( ) ;
}
void
ParsingDriver : : optim_options_helper ( const string & name )
{
if ( options_list . string_options . find ( " optim_opt " ) = = options_list . string_options . end ( ) )
options_list . string_options [ " optim_opt " ] = " " ;
else
options_list . string_options [ " optim_opt " ] + = " , " ;
options_list . string_options [ " optim_opt " ] + = " '' " + name + " '', " ;
}
void
ParsingDriver : : optim_options_string ( string * name , string * value )
{
optim_options_helper ( * name ) ;
options_list . string_options [ " optim_opt " ] + = " '' " + * value + " '' " ;
delete name ;
delete value ;
}
void
ParsingDriver : : optim_options_num ( string * name , string * value )
{
optim_options_helper ( * name ) ;
options_list . string_options [ " optim_opt " ] + = * value ;
delete name ;
delete value ;
}
void
2010-04-14 15:03:41 +02:00
ParsingDriver : : check_varobs ( )
2008-02-03 11:28:36 +01:00
{
2010-04-14 15:03:41 +02:00
if ( mod_file - > symbol_table . observedVariablesNbr ( ) > 0 )
error ( " varobs: you cannot have several 'varobs' statements in the same MOD file " ) ;
}
void
ParsingDriver : : add_varobs ( string * name )
{
check_symbol_existence ( * name ) ;
int symb_id = mod_file - > symbol_table . getID ( * name ) ;
if ( mod_file - > symbol_table . getType ( symb_id ) ! = eEndogenous )
error ( " varobs: " + * name + " is not an endogenous variable " ) ;
mod_file - > symbol_table . addObservedVariable ( symb_id ) ;
delete name ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : set_trends ( )
{
mod_file - > addStatement ( new ObservationTrendsStatement ( trend_elements , mod_file - > symbol_table ) ) ;
trend_elements . clear ( ) ;
}
void
ParsingDriver : : set_trend_element ( string * arg1 , NodeID arg2 )
{
check_symbol_existence ( * arg1 ) ;
if ( trend_elements . find ( * arg1 ) ! = trend_elements . end ( ) )
error ( " observation_trends: " + * arg1 + " declared twice " ) ;
trend_elements [ * arg1 ] = arg2 ;
delete arg1 ;
}
void
ParsingDriver : : set_optim_weights ( string * name , NodeID value )
{
check_symbol_existence ( * name ) ;
if ( mod_file - > symbol_table . getType ( * name ) ! = eEndogenous )
error ( " optim_weights: " + * name + " isn't an endogenous variable " ) ;
if ( var_weights . find ( * name ) ! = var_weights . end ( ) )
error ( " optim_weights: " + * name + " declared twice " ) ;
var_weights [ * name ] = value ;
delete name ;
}
void
ParsingDriver : : set_optim_weights ( string * name1 , string * name2 , NodeID value )
{
check_symbol_existence ( * name1 ) ;
if ( mod_file - > symbol_table . getType ( * name1 ) ! = eEndogenous )
error ( " optim_weights: " + * name1 + " isn't an endogenous variable " ) ;
check_symbol_existence ( * name2 ) ;
if ( mod_file - > symbol_table . getType ( * name2 ) ! = eEndogenous )
error ( " optim_weights: " + * name2 + " isn't an endogenous variable " ) ;
pair < string , string > covar_key ( * name1 , * name2 ) ;
if ( covar_weights . find ( covar_key ) ! = covar_weights . end ( ) )
error ( " optim_weights: pair of variables ( " + * name1 + " , " + * name2
+ " ) declared twice " ) ;
covar_weights [ covar_key ] = value ;
delete name1 ;
delete name2 ;
}
void
ParsingDriver : : optim_weights ( )
{
mod_file - > addStatement ( new OptimWeightsStatement ( var_weights , covar_weights , mod_file - > symbol_table ) ) ;
var_weights . clear ( ) ;
covar_weights . clear ( ) ;
}
void
ParsingDriver : : set_osr_params ( )
{
2008-04-07 15:14:40 +02:00
mod_file - > addStatement ( new OsrParamsStatement ( symbol_list ) ) ;
symbol_list . clear ( ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : run_osr ( )
{
2008-04-07 15:14:40 +02:00
mod_file - > addStatement ( new OsrStatement ( symbol_list , options_list ) ) ;
symbol_list . clear ( ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
void
ParsingDriver : : set_calib_var ( string * name , string * weight , NodeID expression )
{
check_symbol_existence ( * name ) ;
if ( mod_file - > symbol_table . getType ( * name ) ! = eEndogenous
& & mod_file - > symbol_table . getType ( * name ) ! = eExogenous )
error ( " calib_var: " + * name + " isn't an endogenous or exogenous variable " ) ;
if ( calib_var . find ( * name ) ! = calib_var . end ( ) )
error ( " calib_var: " + * name + " declared twice " ) ;
calib_var [ * name ] = make_pair ( * weight , expression ) ;
delete name ;
delete weight ;
}
void
ParsingDriver : : set_calib_covar ( string * name1 , string * name2 ,
string * weight , NodeID expression )
{
check_symbol_existence ( * name1 ) ;
check_symbol_existence ( * name2 ) ;
if ( mod_file - > symbol_table . getType ( * name1 ) ! = mod_file - > symbol_table . getType ( * name2 ) )
error ( " calib_var: " + * name1 + " and " + * name2 + " dont't have the same type " ) ;
if ( mod_file - > symbol_table . getType ( * name1 ) ! = eEndogenous
& & mod_file - > symbol_table . getType ( * name1 ) ! = eExogenous )
error ( " calib_var: " + * name1 + " and " + * name2 + " aren't endogenous or exogenous variables " ) ;
pair < string , string > covar_key ( * name1 , * name2 ) ;
if ( calib_covar . find ( covar_key ) ! = calib_covar . end ( ) )
error ( " calib_var: pair of variables ( " + * name1 + " , " + * name2
+ " ) declared twice " ) ;
calib_covar [ covar_key ] = make_pair ( * weight , expression ) ;
delete name1 ;
delete name2 ;
delete weight ;
}
void
ParsingDriver : : set_calib_ac ( string * name , string * ar ,
string * weight , NodeID expression )
{
check_symbol_existence ( * name ) ;
if ( mod_file - > symbol_table . getType ( * name ) ! = eEndogenous )
error ( " calib_var: " + * name + " isn't an endogenous variable " ) ;
int iar = atoi ( ar - > c_str ( ) ) ;
pair < string , int > ac_key ( * name , iar ) ;
if ( calib_ac . find ( ac_key ) ! = calib_ac . end ( ) )
error ( " calib_var: autocorr " + * name + " ( " + * ar + " ) declared twice " ) ;
calib_ac [ ac_key ] = make_pair ( * weight , expression ) ;
delete name ;
delete ar ;
delete weight ;
}
void
ParsingDriver : : run_calib_var ( )
{
mod_file - > addStatement ( new CalibVarStatement ( calib_var , calib_covar , calib_ac ,
mod_file - > symbol_table ) ) ;
calib_var . clear ( ) ;
calib_covar . clear ( ) ;
calib_ac . clear ( ) ;
}
void
ParsingDriver : : run_calib ( int covar )
{
mod_file - > addStatement ( new CalibStatement ( covar ) ) ;
}
void
2008-10-13 18:06:07 +02:00
ParsingDriver : : run_dynatype ( string * filename )
2008-02-03 11:28:36 +01:00
{
2008-10-13 18:06:07 +02:00
mod_file - > addStatement ( new DynaTypeStatement ( symbol_list , * filename ) ) ;
2008-04-07 15:14:40 +02:00
symbol_list . clear ( ) ;
2008-02-03 11:28:36 +01:00
delete filename ;
}
void
2008-10-13 18:06:07 +02:00
ParsingDriver : : run_dynasave ( string * filename )
2008-02-03 11:28:36 +01:00
{
2008-10-13 18:06:07 +02:00
mod_file - > addStatement ( new DynaSaveStatement ( symbol_list , * filename ) ) ;
2008-04-07 15:14:40 +02:00
symbol_list . clear ( ) ;
2008-02-03 11:28:36 +01:00
delete filename ;
}
2008-12-31 20:29:17 +01:00
void
ParsingDriver : : run_load_params_and_steady_state ( string * filename )
{
2009-02-27 13:19:25 +01:00
mod_file - > addStatement ( new LoadParamsAndSteadyStateStatement ( * filename , mod_file - > symbol_table ) ) ;
2008-12-31 20:29:17 +01:00
delete filename ;
}
void
ParsingDriver : : run_save_params_and_steady_state ( string * filename )
{
mod_file - > addStatement ( new SaveParamsAndSteadyStateStatement ( * filename ) ) ;
delete filename ;
}
2009-04-20 15:58:15 +02:00
void
ParsingDriver : : run_identification ( )
{
2009-10-14 18:16:43 +02:00
mod_file - > addStatement ( new IdentificationStatement ( options_list ) ) ;
options_list . clear ( ) ;
2009-04-20 15:58:15 +02:00
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : add_mc_filename ( string * filename , string * prior )
{
2009-12-16 18:13:23 +01:00
for ( ModelComparisonStatement : : filename_list_type : : iterator it = filename_list . begin ( ) ;
it ! = filename_list . end ( ) ; it + + )
2008-09-26 18:24:13 +02:00
if ( ( * it ) . first = = * filename )
error ( " model_comparison: filename " + * filename + " declared twice " ) ;
filename_list . push_back ( make_pair ( * filename , * prior ) ) ;
2008-02-03 11:28:36 +01:00
delete filename ;
delete prior ;
}
void
ParsingDriver : : run_model_comparison ( )
{
mod_file - > addStatement ( new ModelComparisonStatement ( filename_list , options_list ) ) ;
filename_list . clear ( ) ;
options_list . clear ( ) ;
}
void
ParsingDriver : : begin_planner_objective ( )
{
2010-02-22 17:33:38 +01:00
set_current_data_tree ( new StaticModel ( mod_file - > symbol_table , mod_file - > num_constants , mod_file - > external_functions_table ) ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : end_planner_objective ( NodeID expr )
{
// Add equation corresponding to expression
NodeID eq = model_tree - > AddEqual ( expr , model_tree - > Zero ) ;
model_tree - > addEquation ( eq ) ;
2009-04-14 16:39:53 +02:00
mod_file - > addStatement ( new PlannerObjectiveStatement ( dynamic_cast < StaticModel * > ( model_tree ) ) ) ;
2008-02-03 11:28:36 +01:00
reset_data_tree ( ) ;
}
void
ParsingDriver : : ramsey_policy ( )
{
2008-04-07 15:14:40 +02:00
mod_file - > addStatement ( new RamseyPolicyStatement ( symbol_list , options_list ) ) ;
symbol_list . clear ( ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
2009-04-30 15:14:33 +02:00
void
ParsingDriver : : write_latex_dynamic_model ( )
{
mod_file - > addStatement ( new WriteLatexDynamicModelStatement ( mod_file - > dynamic_model ) ) ;
}
void
ParsingDriver : : write_latex_static_model ( )
{
mod_file - > addStatement ( new WriteLatexStaticModelStatement ( mod_file - > static_model ) ) ;
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : bvar_density ( string * maxnlags )
{
mod_file - > addStatement ( new BVARDensityStatement ( atoi ( maxnlags - > c_str ( ) ) , options_list ) ) ;
options_list . clear ( ) ;
delete maxnlags ;
}
void
ParsingDriver : : bvar_forecast ( string * nlags )
{
mod_file - > addStatement ( new BVARForecastStatement ( atoi ( nlags - > c_str ( ) ) , options_list ) ) ;
options_list . clear ( ) ;
delete nlags ;
}
2009-07-26 19:07:07 +02:00
void
ParsingDriver : : sbvar ( )
{
mod_file - > addStatement ( new SBVARStatement ( options_list ) ) ;
options_list . clear ( ) ;
}
void
ParsingDriver : : ms_sbvar ( )
{
mod_file - > addStatement ( new MS_SBVARStatement ( options_list ) ) ;
options_list . clear ( ) ;
}
2009-12-09 01:38:53 +01:00
void
ParsingDriver : : svar ( )
{
OptionsList : : num_options_type : : const_iterator it0 , it1 , it2 ;
2009-12-10 23:49:50 +01:00
OptionsList : : vec_int_options_type : : const_iterator itv ;
2009-12-09 01:38:53 +01:00
it0 = options_list . string_options . find ( " ms.coefficients " ) ;
it1 = options_list . string_options . find ( " ms.variances " ) ;
it2 = options_list . string_options . find ( " ms.constants " ) ;
2009-12-16 18:13:23 +01:00
if ( it0 = = options_list . string_options . end ( )
& & it1 = = options_list . string_options . end ( )
& & it2 = = options_list . string_options . end ( ) )
2009-12-09 01:38:53 +01:00
error ( " You must pass one of 'coefficients', 'variances', or 'constants'. " ) ;
2009-12-16 18:13:23 +01:00
if ( ( it0 ! = options_list . string_options . end ( )
& & it1 ! = options_list . string_options . end ( ) )
| | ( it1 ! = options_list . string_options . end ( )
& & it2 ! = options_list . string_options . end ( ) )
| | ( it0 ! = options_list . string_options . end ( )
& & it2 ! = options_list . string_options . end ( ) ) )
2009-12-09 01:38:53 +01:00
error ( " You may only pass one 'coefficients', 'variances', or 'constants' option. " ) ;
it0 = options_list . num_options . find ( " ms.chain " ) ;
if ( it0 = = options_list . num_options . end ( ) )
error ( " A chain option must be passed to the svar statement. " ) ;
else if ( atoi ( it0 - > second . c_str ( ) ) < = 0 )
error ( " The value passed to the chain option must be greater than zero. " ) ;
2009-12-10 23:49:50 +01:00
itv = options_list . vector_int_options . find ( " ms.equations " ) ;
if ( itv ! = options_list . vector_int_options . end ( ) )
2009-12-16 18:13:23 +01:00
for ( vector < int > : : const_iterator viit = itv - > second . begin ( ) ; viit ! = itv - > second . end ( ) ; viit + + )
2009-12-14 16:54:00 +01:00
if ( * viit < = 0 )
error ( " The value(s) passed to the equation option must be greater than zero. " ) ;
2009-12-09 01:38:53 +01:00
mod_file - > addStatement ( new SvarStatement ( options_list ) ) ;
options_list . clear ( ) ;
}
2009-12-08 17:46:13 +01:00
void
ParsingDriver : : markov_switching ( )
{
OptionsList : : num_options_type : : const_iterator it0 , it1 ;
it0 = options_list . num_options . find ( " ms.chain " ) ;
if ( it0 = = options_list . num_options . end ( ) )
error ( " A chain option must be passed to the markov_switching statement. " ) ;
else if ( atoi ( it0 - > second . c_str ( ) ) < = 0 )
error ( " The value passed to the chain option must be greater than zero. " ) ;
2009-12-16 18:13:23 +01:00
it0 = options_list . num_options . find ( " ms.state " ) ;
it1 = options_list . num_options . find ( " ms.number_of_states " ) ;
if ( ( it0 = = options_list . num_options . end ( ) )
& & ( it1 = = options_list . num_options . end ( ) ) )
2009-12-08 17:46:13 +01:00
error ( " Either a state option or a number_of_states option must be passed to the markov_switching statement. " ) ;
2009-12-16 18:13:23 +01:00
if ( ( it0 ! = options_list . num_options . end ( ) )
& & ( it1 ! = options_list . num_options . end ( ) ) )
2009-12-08 17:46:13 +01:00
error ( " You cannot pass both a state option and a number_of_states option to the markov_switching statement. " ) ;
if ( it0 ! = options_list . num_options . end ( ) )
if ( atoi ( it0 - > second . c_str ( ) ) < = 0 )
error ( " The value passed to the state option must be greater than zero. " ) ;
if ( it1 ! = options_list . num_options . end ( ) )
if ( atoi ( it1 - > second . c_str ( ) ) < = 0 )
error ( " The value passed to the number_of_states option must be greater than zero. " ) ;
2009-12-16 18:13:23 +01:00
string infStr ( " Inf " ) ;
2009-12-08 17:46:13 +01:00
it0 = options_list . num_options . find ( " ms.duration " ) ;
if ( it0 = = options_list . num_options . end ( ) )
error ( " A duration option must be passed to the markov_switching statement. " ) ;
else if ( infStr . compare ( it0 - > second ) ! = 0 )
if ( atof ( it0 - > second . c_str ( ) ) < = 0.0 )
error ( " The value passed to the duration option must be greater than zero. " ) ;
mod_file - > addStatement ( new MarkovSwitchingStatement ( options_list ) ) ;
options_list . clear ( ) ;
}
2009-08-29 17:04:11 +02:00
void
2009-07-23 10:31:48 +02:00
ParsingDriver : : shock_decomposition ( )
{
mod_file - > addStatement ( new ShockDecompositionStatement ( symbol_list , options_list ) ) ;
symbol_list . clear ( ) ;
options_list . clear ( ) ;
}
2009-08-29 17:04:11 +02:00
2009-10-16 19:23:57 +02:00
void
ParsingDriver : : conditional_forecast ( )
{
mod_file - > addStatement ( new ConditionalForecastStatement ( options_list ) ) ;
options_list . clear ( ) ;
}
void
ParsingDriver : : plot_conditional_forecast ( string * periods )
{
int nperiods ;
if ( periods = = NULL )
nperiods = - 1 ;
else
{
nperiods = atoi ( periods - > c_str ( ) ) ;
delete periods ;
}
mod_file - > addStatement ( new PlotConditionalForecastStatement ( nperiods , symbol_list ) ) ;
symbol_list . clear ( ) ;
}
void
ParsingDriver : : conditional_forecast_paths ( )
{
mod_file - > addStatement ( new ConditionalForecastPathsStatement ( det_shocks , mod_file - > symbol_table ) ) ;
det_shocks . clear ( ) ;
}
2008-02-03 11:28:36 +01:00
NodeID
ParsingDriver : : add_model_equal ( NodeID arg1 , NodeID arg2 )
{
NodeID id = model_tree - > AddEqual ( arg1 , arg2 ) ;
model_tree - > addEquation ( id ) ;
return id ;
}
NodeID
ParsingDriver : : add_model_equal_with_zero_rhs ( NodeID arg )
{
return add_model_equal ( arg , model_tree - > Zero ) ;
}
void
ParsingDriver : : declare_and_init_model_local_variable ( string * name , NodeID rhs )
{
2010-04-23 18:39:07 +02:00
int symb_id ;
2008-02-03 11:28:36 +01:00
try
{
2010-04-23 18:39:07 +02:00
symb_id = mod_file - > symbol_table . addSymbol ( * name , eModelLocalVariable ) ;
2008-02-03 11:28:36 +01:00
}
2009-12-16 18:13:23 +01:00
catch ( SymbolTable : : AlreadyDeclaredException & e )
2008-02-03 11:28:36 +01:00
{
2010-04-23 18:39:07 +02:00
// It can have already been declared in a steady_state_model block, check that it is indeed a ModelLocalVariable
symb_id = mod_file - > symbol_table . getID ( * name ) ;
if ( mod_file - > symbol_table . getType ( symb_id ) ! = eModelLocalVariable )
error ( * name + " has wrong type, you cannot use it within as left-hand side of a pound ('#') expression " ) ;
2008-02-03 11:28:36 +01:00
}
2010-04-23 18:39:07 +02:00
try
{
model_tree - > AddLocalVariable ( symb_id , rhs ) ;
}
catch ( DataTree : : LocalVariableException & e )
{
error ( " Local model variable " + * name + " declared twice. " ) ;
}
2008-02-03 11:28:36 +01:00
delete name ;
}
2009-03-11 12:43:18 +01:00
void
ParsingDriver : : change_type ( SymbolType new_type , vector < string * > * var_list )
{
2009-12-16 18:13:23 +01:00
for ( vector < string * > : : iterator it = var_list - > begin ( ) ;
it ! = var_list - > end ( ) ; it + + )
2009-03-11 12:43:18 +01:00
{
int id ;
try
{
id = mod_file - > symbol_table . getID ( * * it ) ;
}
2009-12-16 18:13:23 +01:00
catch ( SymbolTable : : UnknownSymbolNameException & e )
2009-03-11 12:43:18 +01:00
{
error ( " Unknown variable " + * * it ) ;
}
// Check if symbol already used in a VariableNode
if ( mod_file - > expressions_tree . isSymbolUsed ( id )
2009-04-14 16:39:53 +02:00
| | mod_file - > dynamic_model . isSymbolUsed ( id ) )
2009-03-11 12:43:18 +01:00
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 ;
}
2008-02-03 11:28:36 +01:00
NodeID
ParsingDriver : : add_plus ( NodeID arg1 , NodeID arg2 )
{
return data_tree - > AddPlus ( arg1 , arg2 ) ;
}
NodeID
ParsingDriver : : add_minus ( NodeID arg1 , NodeID arg2 )
{
return data_tree - > AddMinus ( arg1 , arg2 ) ;
}
NodeID
ParsingDriver : : add_uminus ( NodeID arg1 )
{
return data_tree - > AddUMinus ( arg1 ) ;
}
NodeID
ParsingDriver : : add_times ( NodeID arg1 , NodeID arg2 )
{
return data_tree - > AddTimes ( arg1 , arg2 ) ;
}
NodeID
ParsingDriver : : add_divide ( NodeID arg1 , NodeID arg2 )
{
return data_tree - > AddDivide ( arg1 , arg2 ) ;
}
NodeID
ParsingDriver : : add_less ( NodeID arg1 , NodeID arg2 )
{
return data_tree - > AddLess ( arg1 , arg2 ) ;
}
NodeID
ParsingDriver : : add_greater ( NodeID arg1 , NodeID arg2 )
{
return data_tree - > AddGreater ( arg1 , arg2 ) ;
}
NodeID
ParsingDriver : : add_less_equal ( NodeID arg1 , NodeID arg2 )
{
return data_tree - > AddLessEqual ( arg1 , arg2 ) ;
}
NodeID
ParsingDriver : : add_greater_equal ( NodeID arg1 , NodeID arg2 )
{
return data_tree - > AddGreaterEqual ( arg1 , arg2 ) ;
}
NodeID
ParsingDriver : : add_equal_equal ( NodeID arg1 , NodeID arg2 )
{
return data_tree - > AddEqualEqual ( arg1 , arg2 ) ;
}
NodeID
ParsingDriver : : add_different ( NodeID arg1 , NodeID arg2 )
{
return data_tree - > AddDifferent ( arg1 , arg2 ) ;
}
NodeID
ParsingDriver : : add_power ( NodeID arg1 , NodeID arg2 )
{
return data_tree - > AddPower ( arg1 , arg2 ) ;
}
2009-10-29 18:16:10 +01:00
NodeID
ParsingDriver : : add_expectation ( string * arg1 , NodeID arg2 )
{
2010-01-18 23:08:44 +01:00
NodeID expectationNode ;
if ( " varobs " = = * arg1 | | " full " = = * arg1 )
if ( dynamic_cast < VariableNode * > ( arg2 ) = = NULL )
error ( " EXPECTATION( " + * arg1 + " )(X) can only be used when X is a single variable. " ) ;
else
if ( mod_file - > symbol_table . getType ( dynamic_cast < VariableNode * > ( arg2 ) - > get_symb_id ( ) ) ! = eEndogenous )
error ( mod_file - > symbol_table . getName ( dynamic_cast < VariableNode * > ( arg2 ) - > get_symb_id ( ) ) + " is not endogenous. " ) ;
else
expectationNode = data_tree - > AddExpectation ( arg1 , arg2 ) ;
else
expectationNode = data_tree - > AddExpectation ( atoi ( arg1 - > c_str ( ) ) , arg2 ) ;
2009-10-29 18:16:10 +01:00
delete arg1 ;
return expectationNode ;
}
2008-02-03 11:28:36 +01:00
NodeID
ParsingDriver : : add_exp ( NodeID arg1 )
{
return data_tree - > AddExp ( arg1 ) ;
}
NodeID
ParsingDriver : : add_log ( NodeID arg1 )
{
return data_tree - > AddLog ( arg1 ) ;
}
NodeID
ParsingDriver : : add_log10 ( NodeID arg1 )
{
return data_tree - > AddLog10 ( arg1 ) ;
}
NodeID
ParsingDriver : : add_cos ( NodeID arg1 )
{
return data_tree - > AddCos ( arg1 ) ;
}
NodeID
ParsingDriver : : add_sin ( NodeID arg1 )
{
return data_tree - > AddSin ( arg1 ) ;
}
NodeID
ParsingDriver : : add_tan ( NodeID arg1 )
{
return data_tree - > AddTan ( arg1 ) ;
}
NodeID
ParsingDriver : : add_acos ( NodeID arg1 )
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAcos ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_asin ( NodeID arg1 )
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAsin ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_atan ( NodeID arg1 )
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAtan ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_cosh ( NodeID arg1 )
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddCosh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_sinh ( NodeID arg1 )
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddSinh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_tanh ( NodeID arg1 )
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddTanh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_acosh ( NodeID arg1 )
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAcosh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_asinh ( NodeID arg1 )
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAsinh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_atanh ( NodeID arg1 )
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAtanh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_sqrt ( NodeID arg1 )
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddSqrt ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_max ( NodeID arg1 , NodeID arg2 )
{
2009-12-16 18:13:23 +01:00
return data_tree - > AddMax ( arg1 , arg2 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_min ( NodeID arg1 , NodeID arg2 )
{
2009-12-16 18:13:23 +01:00
return data_tree - > AddMin ( arg1 , arg2 ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
ParsingDriver : : add_normcdf ( NodeID arg1 , NodeID arg2 , NodeID arg3 )
{
2009-12-16 18:13:23 +01:00
return data_tree - > AddNormcdf ( arg1 , arg2 , arg3 ) ;
2008-02-03 11:28:36 +01:00
}
2008-09-04 10:10:42 +02:00
NodeID
ParsingDriver : : add_normcdf ( NodeID arg )
{
return add_normcdf ( arg , data_tree - > Zero , data_tree - > One ) ;
}
2010-03-11 09:43:16 +01:00
NodeID
ParsingDriver : : add_normpdf ( NodeID arg1 , NodeID arg2 , NodeID arg3 )
{
return data_tree - > AddNormpdf ( arg1 , arg2 , arg3 ) ;
}
NodeID
ParsingDriver : : add_normpdf ( NodeID arg )
{
return add_normpdf ( arg , data_tree - > Zero , data_tree - > One ) ;
}
2010-03-11 11:57:34 +01:00
NodeID
ParsingDriver : : add_erf ( NodeID arg1 )
{
return data_tree - > AddErf ( arg1 ) ;
}
2009-09-10 22:09:16 +02:00
NodeID
ParsingDriver : : add_steady_state ( NodeID arg1 )
{
return data_tree - > AddSteadyState ( arg1 ) ;
}
2008-02-03 11:28:36 +01:00
void
2010-02-22 17:33:38 +01:00
ParsingDriver : : external_function_option ( const string & name_option , string * opt )
{
external_function_option ( name_option , * opt ) ;
2010-03-03 11:40:13 +01:00
delete opt ;
2010-02-22 17:33:38 +01:00
}
void
ParsingDriver : : external_function_option ( const string & name_option , const string & opt )
{
if ( name_option = = " name " )
{
if ( opt . empty ( ) )
error ( " An argument must be passed to the 'name' option of the external_function() statement. " ) ;
declare_symbol ( & opt , eExternalFunction , NULL ) ;
2010-02-24 15:10:11 +01:00
current_external_function_id = mod_file - > symbol_table . getID ( opt ) ;
2010-02-22 17:33:38 +01:00
}
else if ( name_option = = " first_deriv_provided " )
{
if ( opt . empty ( ) )
current_external_function_options . firstDerivSymbID = eExtFunSetButNoNameProvided ;
else
{
declare_symbol ( & opt , eExternalFunction , NULL ) ;
current_external_function_options . firstDerivSymbID = mod_file - > symbol_table . getID ( opt ) ;
}
}
else if ( name_option = = " second_deriv_provided " )
{
if ( opt . empty ( ) )
current_external_function_options . secondDerivSymbID = eExtFunSetButNoNameProvided ;
else
{
declare_symbol ( & opt , eExternalFunction , NULL ) ;
current_external_function_options . secondDerivSymbID = mod_file - > symbol_table . getID ( opt ) ;
}
}
else if ( name_option = = " nargs " )
current_external_function_options . nargs = atoi ( opt . c_str ( ) ) ;
else
error ( " Unexpected error in ParsingDriver::external_function_option(): Please inform Dynare Team. " ) ;
}
void
ParsingDriver : : external_function ( )
{
2010-02-24 15:10:11 +01:00
if ( current_external_function_id = = eExtFunNotSet )
2010-02-22 17:33:38 +01:00
error ( " The 'name' option must be passed to external_function(). " ) ;
2010-02-24 15:10:11 +01:00
if ( current_external_function_options . secondDerivSymbID > = 0 & &
current_external_function_options . firstDerivSymbID = = eExtFunNotSet )
2010-02-22 17:33:38 +01:00
error ( " If the second derivative is provided to the external_function command, the first derivative must also be provided. " ) ;
2010-02-24 15:10:11 +01:00
if ( current_external_function_options . secondDerivSymbID = = eExtFunSetButNoNameProvided & &
current_external_function_options . firstDerivSymbID ! = eExtFunSetButNoNameProvided )
error ( " If the second derivative is provided in the top-level function, the first derivative must also be provided in that function. " ) ;
2010-03-03 11:40:13 +01:00
mod_file - > external_functions_table . addExternalFunction ( current_external_function_id , current_external_function_options , true ) ;
2010-02-22 17:33:38 +01:00
reset_current_external_function_options ( ) ;
}
void
ParsingDriver : : push_external_function_arg_vector_onto_stack ( )
2008-02-03 11:28:36 +01:00
{
2010-02-22 17:33:38 +01:00
vector < NodeID > emptyvec ;
stack_external_function_args . push ( emptyvec ) ;
}
void
ParsingDriver : : add_external_function_arg ( NodeID arg )
{
stack_external_function_args . top ( ) . push_back ( arg ) ;
2008-02-03 11:28:36 +01:00
}
NodeID
2010-03-03 11:40:13 +01:00
ParsingDriver : : add_model_var_or_external_function ( string * function_name , bool in_model_block )
2008-02-03 11:28:36 +01:00
{
2010-03-03 11:40:13 +01:00
NodeID nid ;
2008-02-03 11:28:36 +01:00
if ( mod_file - > symbol_table . exists ( * function_name ) )
{
2010-02-22 17:33:38 +01:00
if ( mod_file - > symbol_table . getType ( * function_name ) ! = eExternalFunction )
2010-03-15 10:47:44 +01:00
{
if ( ! in_model_block )
2010-02-22 17:33:38 +01:00
{
2010-03-15 10:47:44 +01:00
if ( ( int ) stack_external_function_args . top ( ) . size ( ) > 0 )
error ( " A variable cannot take arguments. " ) ;
else
return add_expression_variable ( function_name ) ;
}
else
{ // e.g. model_var(lag) => ADD MODEL VARIABLE WITH LEAD (NumConstNode)/LAG (UnaryOpNode)
if ( ( int ) stack_external_function_args . top ( ) . size ( ) ! = 1 )
error ( " A model variable is being treated as if it were a function (i.e., has received more than one argument). " ) ;
2010-02-22 17:33:38 +01:00
NumConstNode * numNode = dynamic_cast < NumConstNode * > ( stack_external_function_args . top ( ) . front ( ) ) ;
UnaryOpNode * unaryNode = dynamic_cast < UnaryOpNode * > ( stack_external_function_args . top ( ) . front ( ) ) ;
if ( numNode = = NULL & & unaryNode = = NULL )
error ( " A model variable is being treated as if it were a function (i.e., takes an argument that is not an integer). " ) ;
eval_context_type ectmp ;
int model_var_arg ;
double model_var_arg_dbl ;
if ( unaryNode = = NULL )
{
model_var_arg = ( int ) numNode - > eval ( ectmp ) ;
model_var_arg_dbl = numNode - > eval ( ectmp ) ;
}
else
2010-03-15 10:47:44 +01:00
if ( unaryNode - > get_op_code ( ) ! = oUminus )
error ( " A model variable is being treated as if it were a function (i.e., takes an argument that is not an integer). " ) ;
else
{
model_var_arg = ( int ) unaryNode - > eval ( ectmp ) ;
model_var_arg_dbl = unaryNode - > eval ( ectmp ) ;
}
2010-02-22 17:33:38 +01:00
if ( ( double ) model_var_arg ! = model_var_arg_dbl ) //make 100% sure int cast didn't lose info
error ( " A model variable is being treated as if it were a function (i.e., takes an argument that is not an integer). " ) ;
2010-03-03 11:40:13 +01:00
nid = add_model_variable ( mod_file - > symbol_table . getID ( * function_name ) , model_var_arg ) ;
2010-02-22 17:33:38 +01:00
stack_external_function_args . pop ( ) ;
delete function_name ;
return nid ;
}
}
else
{ // e.g. this function has already been referenced (either ad hoc or through the external_function() statement
// => check that the information matches previously declared info
int symb_id = mod_file - > symbol_table . getID ( * function_name ) ;
2010-02-23 19:08:54 +01:00
assert ( mod_file - > external_functions_table . exists ( symb_id ) ) ;
2010-02-22 17:33:38 +01:00
2010-03-03 11:40:13 +01:00
if ( in_model_block )
if ( mod_file - > external_functions_table . getNargs ( symb_id ) = = eExtFunNotSet )
error ( " Before using " + * function_name +
" () in the model block, you must first declare it via the external_function() statement " ) ;
else if ( ( int ) ( stack_external_function_args . top ( ) . size ( ) ) ! = mod_file - > external_functions_table . getNargs ( symb_id ) )
error ( " The number of arguments passed to " + * function_name +
" () does not match those of a previous call or declaration of this function. " ) ;
2010-02-22 17:33:38 +01:00
}
2008-02-03 11:28:36 +01:00
}
else
2010-02-22 17:33:38 +01:00
{ //First time encountering this external function i.e., not previously declared or encountered
2010-03-03 11:40:13 +01:00
if ( in_model_block )
error ( " To use an external function within the model block, you must first declare it via the external_function() statement. " ) ;
2010-02-22 17:33:38 +01:00
declare_symbol ( function_name , eExternalFunction , NULL ) ;
current_external_function_options . nargs = stack_external_function_args . top ( ) . size ( ) ;
mod_file - > external_functions_table . addExternalFunction ( mod_file - > symbol_table . getID ( * function_name ) ,
2010-03-03 11:40:13 +01:00
current_external_function_options , in_model_block ) ;
2010-02-22 17:33:38 +01:00
reset_current_external_function_options ( ) ;
}
2008-02-03 11:28:36 +01:00
2010-02-22 17:33:38 +01:00
//By this point, we're sure that this function exists in the External Functions Table and is not a mod var
2010-03-16 12:17:17 +01:00
int symb_id = mod_file - > symbol_table . getID ( * function_name ) ;
nid = data_tree - > AddExternalFunction ( symb_id , stack_external_function_args . top ( ) ) ;
2010-02-22 17:33:38 +01:00
stack_external_function_args . pop ( ) ;
delete function_name ;
2010-03-03 11:40:13 +01:00
return nid ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : add_native ( const char * s )
{
mod_file - > addStatement ( new NativeStatement ( s ) ) ;
}
2010-04-23 18:39:07 +02:00
void
ParsingDriver : : begin_steady_state_model ( )
{
set_current_data_tree ( & mod_file - > steady_state_model ) ;
}
void
ParsingDriver : : add_steady_state_model_equal ( string * varname , NodeID expr )
{
int id ;
try
{
id = mod_file - > symbol_table . getID ( * varname ) ;
}
catch ( SymbolTable : : UnknownSymbolNameException & e )
{
// Unknown symbol, declare it as a ModFileLocalVariable
id = mod_file - > symbol_table . addSymbol ( * varname , eModFileLocalVariable ) ;
}
SymbolType type = mod_file - > symbol_table . getType ( id ) ;
2010-06-03 15:59:35 +02:00
if ( type ! = eEndogenous & & type ! = eModFileLocalVariable & & type ! = eParameter )
2010-04-23 18:39:07 +02:00
error ( * varname + " has incorrect type " ) ;
2010-05-31 17:43:17 +02:00
mod_file - > steady_state_model . addDefinition ( id , expr ) ;
2010-04-23 18:39:07 +02:00
delete varname ;
}