2008-02-03 11:28:36 +01:00
/*
2023-01-05 16:40:04 +01:00
* Copyright © 2007 - 2023 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
2021-06-09 16:52:20 +02:00
* along with Dynare . If not , see < https : //www.gnu.org/licenses/>.
2008-02-03 11:28:36 +01:00
*/
2022-06-16 17:52:14 +02:00
# ifndef _BYTECODE_HH
# define _BYTECODE_HH
2014-12-17 09:37:43 +01:00
2009-10-16 18:34:27 +02:00
# include <fstream>
2009-10-23 13:26:29 +02:00
# include <vector>
2022-06-17 15:33:54 +02:00
# include <utility>
2022-06-23 14:28:13 +02:00
# include <ios>
2023-01-05 16:40:04 +01:00
# include <filesystem>
2023-02-17 22:20:40 +01:00
# include <type_traits>
2022-06-23 14:28:13 +02:00
# include "CommonEnums.hh"
2022-06-16 17:52:14 +02:00
2009-10-16 18:34:27 +02:00
using namespace std ;
2022-06-16 17:52:14 +02:00
// The different opcodes of bytecode
2021-02-01 11:10:59 +01:00
enum class Tags
2009-10-16 18:34:27 +02:00
{
2022-06-17 12:17:57 +02:00
FLDZ , // Loads a zero onto the stack
FLDC , // Loads a constant term onto the stack
FDIMT , // Defines the number of temporary terms - dynamic context (the period has to be indicated)
FDIMST , // Defines the number of temporary terms - static context (the period hasn’ t to be indicated)
FLDT , // Loads a temporary term onto the stack - dynamic context (the period has to be indicated)
FLDST , // Loads a temporary term onto the stack - static context (the period hasn’ t to be indicated)
FSTPT , // Stores a temporary term from the stack - dynamic context (the period has to be indicated)
FSTPST , // Stores a temporary term from the stack - static context (the period hasn’ t to be indicated)
FLDU , // Loads an element of the vector U onto the stack - dynamic context (the period has to be indicated)
FLDSU , // Loads an element of the vector U onto the stack - static context (the period hasn’ t to be indicated)
FSTPU , // Stores an element of the vector U from the stack - dynamic context (the period has to be indicated)
FSTPSU , // Stores an element of the vector U from the stack - static context (the period hasn’ t to be indicated)
FLDV , // Loads a variable (described in SymbolType) onto the stack - dynamic context (the period has to be indicated)
FLDSV , // Loads a variable (described in SymbolType) onto the stack - static context (the period hasn’ t to be indicated)
FLDVS , // Loads a variable (described in SymbolType) onto the stack - dynamic context but inside the STEADY_STATE operator (the period hasn’ t to be indicated)
FSTPV , // Stores a variable (described in SymbolType) from the stack - dynamic context (the period has to be indicated)
FSTPSV , // Stores a variable (described in SymbolType) from the stack - static context (the period hasn’ t to be indicated)
FLDR , // Loads a residual onto the stack
FSTPR , // Stores a residual from the stack
FSTPG , // Stores a derivative from the stack
FSTPG2 , // Stores a derivative matrix for a static model from the stack
FSTPG3 , // Stores a derivative matrix for a dynamic model from the stack
FUNARY , // A unary operator
FBINARY , // A binary operator
FTRINARY , // A trinary operator
FJMPIFEVAL , // Jump if evaluate = true
FJMP , // Jump
FBEGINBLOCK , // Marks the beginning of a model block
FENDBLOCK , // Marks the end of a model block
FENDEQU , // Marks the last equation of the block; for a block that has to be solved, the derivatives appear just after this flag
FEND , // Marks the end of the model code
FNUMEXPR , // Stores the expression type and references
FCALL , // Call an external function
FLDTEF , // Loads the result of an external function onto the stack
FSTPTEF , // Stores the result of an external function from the stack
FLDTEFD , // Loads the result of the 1st derivative of an external function onto the stack
FSTPTEFD , // Stores the result of the 1st derivative of an external function from the stack
FLDTEFDD , // Loads the result of the 2nd derivative of an external function onto the stack
FSTPTEFDD // Stores the result of the 2nd derivative of an external function from the stack
2009-12-16 18:13:23 +01:00
} ;
2008-02-03 11:28:36 +01:00
2021-02-01 11:10:59 +01:00
enum class ExpressionType
2010-01-22 17:42:08 +01:00
{
2019-12-20 16:59:30 +01:00
TemporaryTerm ,
ModelEquation ,
FirstEndoDerivative ,
FirstExoDerivative ,
FirstExodetDerivative ,
2010-01-22 17:42:08 +01:00
} ;
2022-07-08 16:00:02 +02:00
enum class ExternalFunctionCallType
{
levelWithoutDerivative ,
levelWithFirstDerivative ,
levelWithFirstAndSecondDerivative ,
separatelyProvidedFirstDerivative ,
numericalFirstDerivative ,
separatelyProvidedSecondDerivative ,
numericalSecondDerivative
} ;
2009-12-16 18:13:23 +01:00
struct Block_contain_type
{
int Equation , Variable , Own_Derivative ;
} ;
2009-10-16 18:34:27 +02:00
2022-06-23 14:28:13 +02:00
class BytecodeWriter ;
2022-07-26 18:26:18 +02:00
struct BytecodeInstruction
2009-10-16 18:34:27 +02:00
{
2022-07-26 18:26:18 +02:00
const Tags op_code ;
2023-09-01 13:50:57 +02:00
explicit BytecodeInstruction ( Tags op_code_arg ) :
op_code { op_code_arg }
{
}
protected :
/* This is a base class, so the destructor should be either public+virtual or
protected + non - virtual . We opt for the latter , because otherwise this class
would no longer be POD ; its memory representation would also include
runtime type information , and our crude serialization technique ( copying the
whole object from memory ) would thus not work . */
~ BytecodeInstruction ( ) = default ;
2009-10-16 18:34:27 +02:00
} ;
2018-10-04 18:00:30 +02:00
template < typename T1 >
2022-06-17 15:33:54 +02:00
class TagWithOneArgument : public BytecodeInstruction
2009-10-16 18:34:27 +02:00
{
protected :
T1 arg1 ;
public :
2022-06-17 15:33:54 +02:00
TagWithOneArgument ( Tags op_code_arg , T1 arg_arg1 ) : BytecodeInstruction { op_code_arg } ,
2021-02-01 11:10:59 +01:00
arg1 { arg_arg1 }
2009-12-16 18:13:23 +01:00
{
} ;
2023-09-01 13:50:57 +02:00
protected :
// See BytecodeInstruction destructor for the rationale
~ TagWithOneArgument ( ) = default ;
2009-10-16 18:34:27 +02:00
} ;
2018-10-04 18:00:30 +02:00
template < typename T1 , typename T2 >
2022-06-17 15:33:54 +02:00
class TagWithTwoArguments : public BytecodeInstruction
2009-10-16 18:34:27 +02:00
{
protected :
T1 arg1 ;
T2 arg2 ;
public :
2021-02-01 11:10:59 +01:00
TagWithTwoArguments ( Tags op_code_arg , T1 arg_arg1 , T2 arg_arg2 ) :
2022-06-17 15:33:54 +02:00
BytecodeInstruction { op_code_arg } , arg1 { arg_arg1 } , arg2 { arg_arg2 }
2009-12-16 18:13:23 +01:00
{
} ;
2023-09-01 13:50:57 +02:00
protected :
// See BytecodeInstruction destructor for the rationale
~ TagWithTwoArguments ( ) = default ;
2009-10-16 18:34:27 +02:00
} ;
2018-10-04 18:00:30 +02:00
template < typename T1 , typename T2 , typename T3 >
2022-06-17 15:33:54 +02:00
class TagWithThreeArguments : public BytecodeInstruction
2009-10-16 18:34:27 +02:00
{
protected :
T1 arg1 ;
T2 arg2 ;
T3 arg3 ;
public :
2021-02-01 11:10:59 +01:00
TagWithThreeArguments ( Tags op_code_arg , T1 arg_arg1 , T2 arg_arg2 , T3 arg_arg3 ) :
2022-06-17 15:33:54 +02:00
BytecodeInstruction { op_code_arg } , arg1 { arg_arg1 } , arg2 { arg_arg2 } , arg3 { arg_arg3 }
2009-12-16 18:13:23 +01:00
{
} ;
2023-09-01 13:50:57 +02:00
protected :
// See BytecodeInstruction destructor for the rationale
~ TagWithThreeArguments ( ) = default ;
2009-10-16 18:34:27 +02:00
} ;
2018-10-04 18:00:30 +02:00
template < typename T1 , typename T2 , typename T3 , typename T4 >
2022-06-17 15:33:54 +02:00
class TagWithFourArguments : public BytecodeInstruction
2010-07-23 11:20:24 +02:00
{
protected :
T1 arg1 ;
T2 arg2 ;
T3 arg3 ;
T4 arg4 ;
public :
2021-02-01 11:10:59 +01:00
TagWithFourArguments ( Tags op_code_arg , T1 arg_arg1 , T2 arg_arg2 , T3 arg_arg3 , T4 arg_arg4 ) :
2022-06-17 15:33:54 +02:00
BytecodeInstruction { op_code_arg } , arg1 { arg_arg1 } , arg2 { arg_arg2 } ,
2021-02-01 11:10:59 +01:00
arg3 { move ( arg_arg3 ) } , arg4 { arg_arg4 }
2010-07-23 11:20:24 +02:00
{
} ;
2023-09-01 13:50:57 +02:00
protected :
// See BytecodeInstruction destructor for the rationale
~ TagWithFourArguments ( ) = default ;
2010-07-23 11:20:24 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FLDZ_ final : public BytecodeInstruction
2009-10-16 18:34:27 +02:00
{
public :
2022-06-17 15:33:54 +02:00
FLDZ_ ( ) : BytecodeInstruction { Tags : : FLDZ }
2009-12-16 18:13:23 +01:00
{
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FEND_ final : public BytecodeInstruction
2009-10-16 18:34:27 +02:00
{
public :
2022-06-17 15:33:54 +02:00
FEND_ ( ) : BytecodeInstruction { Tags : : FEND }
2009-12-16 18:13:23 +01:00
{
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FENDBLOCK_ final : public BytecodeInstruction
2009-10-16 18:34:27 +02:00
{
public :
2022-06-17 15:33:54 +02:00
FENDBLOCK_ ( ) : BytecodeInstruction { Tags : : FENDBLOCK }
2009-12-16 18:13:23 +01:00
{
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FENDEQU_ final : public BytecodeInstruction
2009-10-16 18:34:27 +02:00
{
public :
2022-06-17 15:33:54 +02:00
FENDEQU_ ( ) : BytecodeInstruction { Tags : : FENDEQU }
2009-12-16 18:13:23 +01:00
{
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FDIMT_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FDIMT_ ( int size_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FDIMT , size_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_size ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FDIMST_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FDIMST_ ( int size_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FDIMST , size_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_size ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FLDC_ final : public TagWithOneArgument < double >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FLDC_ ( double value_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FLDC , value_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-17 14:29:12 +02:00
double
2009-12-16 18:13:23 +01:00
get_value ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FLDU_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FLDU_ ( int pos_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FLDU , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FLDSU_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FLDSU_ ( int pos_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FLDSU , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FLDR_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FLDR_ ( int pos_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FLDR , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FLDT_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FLDT_ ( int pos_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FLDT , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FLDST_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FLDST_ ( int pos_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FLDST , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FSTPT_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FSTPT_ ( int pos_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FSTPT , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FSTPST_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FSTPST_ ( int pos_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FSTPST , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FSTPR_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FSTPR_ ( int pos_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FSTPR , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FSTPU_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FSTPU_ ( int pos_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FSTPU , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FSTPSU_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FSTPSU_ ( int pos_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FSTPSU , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FSTPG_ final : public TagWithOneArgument < int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FSTPG_ ( int pos_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FSTPG , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FSTPG2_ final : public TagWithTwoArguments < int , int >
2010-01-22 11:03:29 +01:00
{
public :
2022-06-20 17:49:09 +02:00
FSTPG2_ ( int row_arg , int col_arg ) : TagWithTwoArguments : : TagWithTwoArguments { Tags : : FSTPG2 , row_arg , col_arg }
2010-01-22 11:03:29 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2010-01-22 11:03:29 +01:00
get_row ( )
{
return arg1 ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-01-22 11:03:29 +01:00
get_col ( )
{
return arg2 ;
} ;
} ;
2023-09-01 13:50:57 +02:00
class FSTPG3_ final : public TagWithFourArguments < int , int , int , int >
2010-07-23 11:20:24 +02:00
{
public :
2022-06-20 17:49:09 +02:00
FSTPG3_ ( int row_arg , int col_arg , int lag_arg , int col_pos_arg ) : TagWithFourArguments : : TagWithFourArguments { Tags : : FSTPG3 , row_arg , col_arg , lag_arg , col_pos_arg }
2010-07-23 11:20:24 +02:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2010-07-23 11:20:24 +02:00
get_row ( )
{
return arg1 ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-07-23 11:20:24 +02:00
get_col ( )
{
return arg2 ;
} ;
2022-06-17 14:29:12 +02:00
int
2010-07-23 11:20:24 +02:00
get_lag ( )
{
return arg2 ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-07-23 11:20:24 +02:00
get_col_pos ( )
{
return arg4 ;
} ;
} ;
2010-01-22 11:03:29 +01:00
2023-09-01 13:50:57 +02:00
class FUNARY_ final : public TagWithOneArgument < UnaryOpcode >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 14:44:55 +02:00
explicit FUNARY_ ( UnaryOpcode op_type_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FUNARY , op_type_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 14:44:55 +02:00
UnaryOpcode
2009-12-16 18:13:23 +01:00
get_op_type ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FBINARY_ final : public TagWithOneArgument < BinaryOpcode >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 14:44:55 +02:00
explicit FBINARY_ ( BinaryOpcode op_type_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FBINARY , op_type_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 14:44:55 +02:00
BinaryOpcode
2009-12-16 18:13:23 +01:00
get_op_type ( )
{
return arg1 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FTRINARY_ final : public TagWithOneArgument < TrinaryOpcode >
2010-04-16 16:54:55 +02:00
{
public :
2022-06-20 14:44:55 +02:00
explicit FTRINARY_ ( TrinaryOpcode op_type_arg ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FTRINARY , op_type_arg }
2010-04-16 16:54:55 +02:00
{
} ;
2022-06-20 14:44:55 +02:00
TrinaryOpcode
2010-04-16 16:54:55 +02:00
get_op_type ( )
{
return arg1 ;
} ;
} ;
2023-09-01 13:50:57 +02:00
class FJMPIFEVAL_ final : public TagWithOneArgument < int >
2010-07-23 11:20:24 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FJMPIFEVAL_ ( int arg_pos ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FJMPIFEVAL , arg_pos }
2010-07-23 11:20:24 +02:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2010-07-23 11:20:24 +02:00
get_pos ( )
{
return arg1 ;
}
} ;
2023-09-01 13:50:57 +02:00
class FJMP_ final : public TagWithOneArgument < int >
2010-07-23 11:20:24 +02:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FJMP_ ( int arg_pos ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FJMP , arg_pos }
2010-07-23 11:20:24 +02:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2010-07-23 11:20:24 +02:00
get_pos ( )
{
return arg1 ;
}
} ;
2023-09-01 13:50:57 +02:00
class FLDTEF_ final : public TagWithOneArgument < int >
2010-12-10 11:50:27 +01:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FLDTEF_ ( int number ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FLDTEF , number }
2010-12-10 11:50:27 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_number ( )
{
return arg1 ;
}
} ;
2023-09-01 13:50:57 +02:00
class FSTPTEF_ final : public TagWithOneArgument < int >
2010-12-10 11:50:27 +01:00
{
public :
2022-06-20 17:49:09 +02:00
explicit FSTPTEF_ ( int number ) : TagWithOneArgument : : TagWithOneArgument { Tags : : FSTPTEF , number }
2010-12-10 11:50:27 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_number ( )
{
return arg1 ;
}
} ;
2023-09-01 13:50:57 +02:00
class FLDTEFD_ final : public TagWithTwoArguments < int , int >
2010-12-10 11:50:27 +01:00
{
public :
2022-06-20 17:49:09 +02:00
FLDTEFD_ ( int indx , int row ) : TagWithTwoArguments : : TagWithTwoArguments { Tags : : FLDTEFD , indx , row }
2010-12-10 11:50:27 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_indx ( )
{
return arg1 ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_row ( )
{
return arg2 ;
} ;
} ;
2023-09-01 13:50:57 +02:00
class FSTPTEFD_ final : public TagWithTwoArguments < int , int >
2010-12-10 11:50:27 +01:00
{
public :
2022-06-20 17:49:09 +02:00
FSTPTEFD_ ( int indx , int row ) : TagWithTwoArguments : : TagWithTwoArguments { Tags : : FSTPTEFD , indx , row }
2010-12-10 11:50:27 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_indx ( )
{
return arg1 ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_row ( )
{
return arg2 ;
} ;
} ;
2023-09-01 13:50:57 +02:00
class FLDTEFDD_ final : public TagWithThreeArguments < int , int , int >
2010-12-10 11:50:27 +01:00
{
public :
2022-06-20 17:49:09 +02:00
FLDTEFDD_ ( int indx , int row , int col ) : TagWithThreeArguments : : TagWithThreeArguments { Tags : : FLDTEFDD , indx , row , col }
2010-12-10 11:50:27 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_indx ( )
{
return arg1 ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_row ( )
{
return arg2 ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_col ( )
{
return arg3 ;
} ;
} ;
2023-09-01 13:50:57 +02:00
class FSTPTEFDD_ final : public TagWithThreeArguments < int , int , int >
2010-12-10 11:50:27 +01:00
{
public :
2022-06-20 17:49:09 +02:00
FSTPTEFDD_ ( int indx , int row , int col ) : TagWithThreeArguments : : TagWithThreeArguments { Tags : : FSTPTEF , indx , row , col }
2010-12-10 11:50:27 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_indx ( )
{
return arg1 ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_row ( )
{
return arg2 ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_col ( )
{
return arg3 ;
} ;
} ;
2023-09-01 13:50:57 +02:00
class FLDVS_ final : public TagWithTwoArguments < SymbolType , int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
FLDVS_ ( SymbolType type_arg , int pos_arg ) : TagWithTwoArguments : : TagWithTwoArguments { Tags : : FLDVS , type_arg , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 14:44:55 +02:00
SymbolType
2009-12-16 18:13:23 +01:00
get_type ( )
{
return arg1 ;
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg2 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FLDSV_ final : public TagWithTwoArguments < SymbolType , int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
FLDSV_ ( SymbolType type_arg , int pos_arg ) : TagWithTwoArguments : : TagWithTwoArguments { Tags : : FLDSV , type_arg , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 14:44:55 +02:00
SymbolType
2009-12-16 18:13:23 +01:00
get_type ( )
{
return arg1 ;
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg2 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FSTPSV_ final : public TagWithTwoArguments < SymbolType , int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
FSTPSV_ ( SymbolType type_arg , int pos_arg ) : TagWithTwoArguments : : TagWithTwoArguments { Tags : : FSTPSV , type_arg , pos_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 14:44:55 +02:00
SymbolType
2009-12-16 18:13:23 +01:00
get_type ( )
{
return arg1 ;
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg2 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FLDV_ final : public TagWithThreeArguments < SymbolType , int , int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
FLDV_ ( SymbolType type_arg , int pos_arg , int lead_lag_arg ) :
2022-06-20 14:44:55 +02:00
TagWithThreeArguments : : TagWithThreeArguments { Tags : : FLDV , type_arg , pos_arg , lead_lag_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 14:44:55 +02:00
SymbolType
2009-12-16 18:13:23 +01:00
get_type ( )
{
return arg1 ;
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg2 ;
} ;
2022-06-17 14:29:12 +02:00
int
2009-12-16 18:13:23 +01:00
get_lead_lag ( )
{
return arg3 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FSTPV_ final : public TagWithThreeArguments < SymbolType , int , int >
2009-10-16 18:34:27 +02:00
{
public :
2022-06-20 17:49:09 +02:00
FSTPV_ ( SymbolType type_arg , int pos_arg , int lead_lag_arg ) :
2022-06-20 14:44:55 +02:00
TagWithThreeArguments : : TagWithThreeArguments { Tags : : FSTPV , type_arg , pos_arg , lead_lag_arg }
2009-12-16 18:13:23 +01:00
{
} ;
2022-06-20 14:44:55 +02:00
SymbolType
2009-12-16 18:13:23 +01:00
get_type ( )
{
return arg1 ;
} ;
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_pos ( )
{
return arg2 ;
} ;
2022-06-17 14:29:12 +02:00
int
2009-12-16 18:13:23 +01:00
get_lead_lag ( )
{
return arg3 ;
} ;
2009-10-16 18:34:27 +02:00
} ;
2023-09-01 13:50:57 +02:00
class FCALL_ final : public BytecodeInstruction
2010-12-10 11:50:27 +01:00
{
2022-06-23 14:28:13 +02:00
template < typename B >
friend BytecodeWriter & operator < < ( BytecodeWriter & code_file , const B & instr ) ;
private :
2022-06-20 17:49:09 +02:00
int nb_output_arguments , nb_input_arguments , indx ;
2010-12-10 11:50:27 +01:00
string func_name ;
string arg_func_name ;
2022-06-20 17:49:09 +02:00
int add_input_arguments { 0 } , row { 0 } , col { 0 } ;
2022-07-08 16:00:02 +02:00
ExternalFunctionCallType call_type ;
2010-12-10 11:50:27 +01:00
public :
2022-07-08 16:00:02 +02:00
FCALL_ ( int nb_output_arguments_arg , int nb_input_arguments_arg , string func_name_arg , int indx_arg , ExternalFunctionCallType call_type_arg ) :
2022-06-17 15:33:54 +02:00
BytecodeInstruction { Tags : : FCALL } ,
nb_output_arguments { nb_output_arguments_arg } ,
nb_input_arguments { nb_input_arguments_arg } ,
indx { indx_arg } ,
2022-07-08 16:00:02 +02:00
func_name { move ( func_name_arg ) } ,
call_type { call_type_arg }
2019-12-16 19:42:59 +01:00
{
2010-12-10 11:50:27 +01:00
} ;
2023-02-17 22:20:40 +01:00
/* Deserializing constructor.
Updates the code pointer to point beyond the bytes read . */
FCALL_ ( char * & code ) :
BytecodeInstruction { Tags : : FCALL }
{
code + = sizeof ( op_code ) ;
auto read_member = [ & code ] ( auto & member )
{
member = * reinterpret_cast < add_pointer_t < decltype ( member ) > > ( code ) ;
code + = sizeof member ;
} ;
read_member ( nb_output_arguments ) ;
read_member ( nb_input_arguments ) ;
read_member ( indx ) ;
read_member ( add_input_arguments ) ;
read_member ( row ) ;
read_member ( col ) ;
read_member ( call_type ) ;
int size ;
read_member ( size ) ;
func_name = code ;
code + = size + 1 ;
read_member ( size ) ;
arg_func_name = code ;
code + = size + 1 ;
}
2022-06-17 14:29:12 +02:00
string
2010-12-10 11:50:27 +01:00
get_function_name ( )
{
//printf("get_function_name => func_name=%s\n",func_name.c_str());fflush(stdout);
return func_name ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_nb_output_arguments ( )
{
2022-06-17 15:33:54 +02:00
return nb_output_arguments ;
2010-12-10 11:50:27 +01:00
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_nb_input_arguments ( )
{
2022-06-17 15:33:54 +02:00
return nb_input_arguments ;
2010-12-10 11:50:27 +01:00
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_indx ( )
{
2022-06-17 15:33:54 +02:00
return indx ;
2010-12-10 11:50:27 +01:00
} ;
2022-06-17 14:29:12 +02:00
void
2010-12-10 11:50:27 +01:00
set_arg_func_name ( string arg_arg_func_name )
{
arg_func_name = arg_arg_func_name ;
} ;
2022-06-17 14:29:12 +02:00
string
2010-12-10 11:50:27 +01:00
get_arg_func_name ( )
{
return arg_func_name ;
} ;
2022-06-17 14:29:12 +02:00
void
2022-06-20 17:49:09 +02:00
set_nb_add_input_arguments ( int arg_add_input_arguments )
2010-12-10 11:50:27 +01:00
{
add_input_arguments = arg_add_input_arguments ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_nb_add_input_arguments ( )
{
return add_input_arguments ;
} ;
2022-06-17 14:29:12 +02:00
void
2022-06-20 17:49:09 +02:00
set_row ( int arg_row )
2010-12-10 11:50:27 +01:00
{
row = arg_row ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_row ( )
{
return row ;
}
2022-06-17 14:29:12 +02:00
void
2022-06-20 17:49:09 +02:00
set_col ( int arg_col )
2010-12-10 11:50:27 +01:00
{
col = arg_col ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-12-10 11:50:27 +01:00
get_col ( )
{
return col ;
} ;
2022-07-08 16:00:02 +02:00
ExternalFunctionCallType
get_call_type ( )
2011-02-04 16:25:38 +01:00
{
2022-07-08 16:00:02 +02:00
return call_type ;
2011-02-04 16:25:38 +01:00
}
2010-12-10 11:50:27 +01:00
} ;
2023-09-01 13:50:57 +02:00
class FNUMEXPR_ final : public BytecodeInstruction
2010-01-22 17:42:08 +01:00
{
private :
2022-06-17 15:33:54 +02:00
ExpressionType expression_type ;
2022-07-26 14:51:48 +02:00
int equation ; // Equation number (non-block-specific) (or temporary term number for ExpressionType::TemporaryTerm)
int dvariable1 ; // For derivatives, type-specific ID of the derivation variable
int lag1 ; // For derivatives, lead/lag of the derivation variable
2010-01-22 17:42:08 +01:00
public :
2022-06-20 17:49:09 +02:00
FNUMEXPR_ ( const ExpressionType expression_type_arg , int equation_arg ) :
2022-06-17 15:33:54 +02:00
BytecodeInstruction { Tags : : FNUMEXPR } ,
expression_type { expression_type_arg } ,
2018-10-04 17:18:27 +02:00
equation { equation_arg } ,
2022-06-17 16:31:29 +02:00
dvariable1 { 0 } ,
lag1 { 0 }
2010-01-22 17:42:08 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
FNUMEXPR_ ( const ExpressionType expression_type_arg , int equation_arg , int dvariable1_arg ) :
2022-06-17 15:33:54 +02:00
BytecodeInstruction { Tags : : FNUMEXPR } ,
expression_type { expression_type_arg } ,
2018-10-04 17:18:27 +02:00
equation { equation_arg } ,
2022-06-20 17:49:09 +02:00
dvariable1 { dvariable1_arg } ,
2022-06-17 16:31:29 +02:00
lag1 { 0 }
2010-01-22 17:42:08 +01:00
{
} ;
2022-06-20 17:49:09 +02:00
FNUMEXPR_ ( const ExpressionType expression_type_arg , int equation_arg , int dvariable1_arg , int lag1_arg ) :
2022-06-17 15:33:54 +02:00
BytecodeInstruction { Tags : : FNUMEXPR } ,
expression_type { expression_type_arg } ,
2018-10-04 17:18:27 +02:00
equation { equation_arg } ,
2022-06-20 17:49:09 +02:00
dvariable1 { dvariable1_arg } ,
2022-06-20 10:44:21 +02:00
lag1 { lag1_arg }
2010-01-22 17:42:08 +01:00
{
} ;
2022-06-17 14:29:12 +02:00
ExpressionType
2010-01-22 17:42:08 +01:00
get_expression_type ( )
{
2022-06-17 15:33:54 +02:00
return expression_type ;
2010-01-22 17:42:08 +01:00
}
2022-06-20 17:49:09 +02:00
int
2010-01-22 17:42:08 +01:00
get_equation ( )
{
return equation ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-01-22 17:42:08 +01:00
get_dvariable1 ( )
{
return dvariable1 ;
} ;
2022-06-17 14:29:12 +02:00
int
2010-01-22 17:42:08 +01:00
get_lag1 ( )
{
return lag1 ;
} ;
} ;
2023-09-01 13:50:57 +02:00
class FBEGINBLOCK_ final : public BytecodeInstruction
2009-10-16 18:34:27 +02:00
{
2022-06-23 14:28:13 +02:00
template < typename B >
friend BytecodeWriter & operator < < ( BytecodeWriter & code_file , const B & instr ) ;
2009-10-16 18:34:27 +02:00
private :
2021-02-01 12:44:24 +01:00
int size { 0 } ;
2022-06-20 14:44:55 +02:00
BlockSimulationType type ;
2009-12-16 14:21:31 +01:00
vector < int > variable ;
vector < int > equation ;
2020-05-06 14:02:58 +02:00
vector < int > exogenous ;
vector < int > det_exogenous ;
2021-02-01 12:44:24 +01:00
bool is_linear { false } ;
2009-10-23 13:26:29 +02:00
vector < Block_contain_type > Block_Contain_ ;
2021-02-01 12:44:24 +01:00
int u_count_int { 0 } ;
int nb_col_jacob { 0 } ;
2023-01-17 13:47:02 +01:00
int det_exo_size , exo_size ;
2009-10-16 18:34:27 +02:00
public :
2023-01-17 13:47:02 +01:00
/* Constructor when derivatives w.r.t. exogenous are present (only makes
sense when there is no block - decomposition , since there is no provision for
derivatives w . r . t . endogenous not belonging to the block ) */
2022-06-20 17:49:09 +02:00
FBEGINBLOCK_ ( int size_arg , BlockSimulationType type_arg , int first_element , int block_size ,
2011-02-04 16:25:38 +01:00
const vector < int > & variable_arg , const vector < int > & equation_arg ,
2023-04-18 16:54:35 +02:00
bool is_linear_arg , int u_count_int_arg , int nb_col_jacob_arg ,
2023-01-17 13:47:02 +01:00
int det_exo_size_arg , int exo_size_arg ,
vector < int > det_exogenous_arg , vector < int > exogenous_arg ) :
2022-06-17 15:33:54 +02:00
BytecodeInstruction { Tags : : FBEGINBLOCK } ,
2022-06-20 17:49:09 +02:00
size { size_arg } ,
2022-06-20 14:44:55 +02:00
type { type_arg } ,
2018-10-04 17:18:27 +02:00
variable { variable_arg . begin ( ) + first_element , variable_arg . begin ( ) + ( first_element + block_size ) } ,
equation { equation_arg . begin ( ) + first_element , equation_arg . begin ( ) + ( first_element + block_size ) } ,
2020-05-06 14:02:58 +02:00
exogenous { move ( exogenous_arg ) } ,
det_exogenous { move ( det_exogenous_arg ) } ,
2018-10-04 17:18:27 +02:00
is_linear { is_linear_arg } ,
u_count_int { u_count_int_arg } ,
nb_col_jacob { nb_col_jacob_arg } ,
det_exo_size { det_exo_size_arg } ,
2023-01-17 13:47:02 +01:00
exo_size { exo_size_arg }
2009-12-16 18:13:23 +01:00
{
2018-10-04 17:18:27 +02:00
}
2023-01-17 13:47:02 +01:00
// Constructor when derivatives w.r.t. exogenous are absent
2022-06-20 17:49:09 +02:00
FBEGINBLOCK_ ( int size_arg , BlockSimulationType type_arg , int first_element , int block_size ,
2011-02-04 16:25:38 +01:00
const vector < int > & variable_arg , const vector < int > & equation_arg ,
2023-04-18 16:54:35 +02:00
bool is_linear_arg , int u_count_int_arg , int nb_col_jacob_arg ) :
2022-06-17 15:33:54 +02:00
BytecodeInstruction { Tags : : FBEGINBLOCK } ,
2022-06-20 17:49:09 +02:00
size { size_arg } ,
2022-06-20 14:44:55 +02:00
type { type_arg } ,
2018-10-04 17:18:27 +02:00
variable { variable_arg . begin ( ) + first_element , variable_arg . begin ( ) + ( first_element + block_size ) } ,
equation { equation_arg . begin ( ) + first_element , equation_arg . begin ( ) + ( first_element + block_size ) } ,
is_linear { is_linear_arg } ,
u_count_int { u_count_int_arg } ,
nb_col_jacob { nb_col_jacob_arg } ,
det_exo_size { 0 } ,
2023-01-17 13:47:02 +01:00
exo_size { 0 }
2018-10-04 17:18:27 +02:00
{
2010-07-23 11:20:24 +02:00
}
2023-02-17 22:20:40 +01:00
/* Deserializing constructor.
Updates the code pointer to point beyond the bytes read . */
FBEGINBLOCK_ ( char * & code ) :
BytecodeInstruction { Tags : : FBEGINBLOCK }
{
code + = sizeof ( op_code ) ;
auto read_member = [ & code ] ( auto & member )
{
member = * reinterpret_cast < add_pointer_t < decltype ( member ) > > ( code ) ;
code + = sizeof member ;
} ;
read_member ( size ) ;
read_member ( type ) ;
for ( int i { 0 } ; i < size ; i + + )
{
Block_contain_type bc ;
read_member ( bc . Variable ) ;
read_member ( bc . Equation ) ;
Block_Contain_ . push_back ( move ( bc ) ) ;
}
if ( type = = BlockSimulationType : : solveTwoBoundariesSimple
| | type = = BlockSimulationType : : solveTwoBoundariesComplete
| | type = = BlockSimulationType : : solveBackwardComplete
| | type = = BlockSimulationType : : solveForwardComplete )
{
read_member ( is_linear ) ;
read_member ( u_count_int ) ;
}
read_member ( nb_col_jacob ) ;
read_member ( det_exo_size ) ;
read_member ( exo_size ) ;
for ( int i { 0 } ; i < det_exo_size ; i + + )
{
int tmp_i ;
read_member ( tmp_i ) ;
det_exogenous . push_back ( tmp_i ) ;
}
for ( int i { 0 } ; i < exo_size ; i + + )
{
int tmp_i ;
read_member ( tmp_i ) ;
exogenous . push_back ( tmp_i ) ;
}
}
2022-06-20 17:49:09 +02:00
int
2009-12-16 18:13:23 +01:00
get_size ( )
{
return size ;
} ;
2022-06-20 14:44:55 +02:00
BlockSimulationType
2009-12-16 18:13:23 +01:00
get_type ( )
{
return type ;
} ;
2022-06-17 14:29:12 +02:00
bool
2009-12-16 18:13:23 +01:00
get_is_linear ( )
{
return is_linear ;
} ;
2022-06-17 14:29:12 +02:00
int
2009-12-16 18:13:23 +01:00
get_u_count_int ( )
{
return u_count_int ;
} ;
2022-06-17 14:29:12 +02:00
vector < Block_contain_type >
2009-12-16 18:13:23 +01:00
get_Block_Contain ( )
{
return Block_Contain_ ;
} ;
2022-06-17 14:29:12 +02:00
int
2010-07-23 11:20:24 +02:00
get_nb_col_jacob ( )
{
return nb_col_jacob ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-07-23 11:20:24 +02:00
get_exo_size ( )
{
return exo_size ;
} ;
2022-06-20 17:49:09 +02:00
int
2010-07-23 11:20:24 +02:00
get_det_exo_size ( )
{
return det_exo_size ;
} ;
2022-06-17 14:29:12 +02:00
vector < int >
2015-09-22 12:45:27 +02:00
get_endogenous ( )
{
return variable ;
}
2022-06-17 14:29:12 +02:00
vector < int >
2015-09-22 12:45:27 +02:00
get_exogenous ( )
{
return exogenous ;
}
2009-10-16 18:34:27 +02:00
} ;
2022-06-23 14:28:13 +02:00
// Superclass of std::ofstream for writing a sequence of bytecode instructions
class BytecodeWriter : private ofstream
{
template < typename B >
friend BytecodeWriter & operator < < ( BytecodeWriter & code_file , const B & instr ) ;
private :
// Stores the positions of all instructions in the byte stream
vector < pos_type > instructions_positions ;
public :
2023-01-05 16:40:04 +01:00
BytecodeWriter ( const filesystem : : path & filename ) ;
2022-06-23 14:28:13 +02:00
// Returns the number of the next instruction to be written
int
getInstructionCounter ( ) const
{
return static_cast < int > ( instructions_positions . size ( ) ) ;
}
/* Overwrites an existing instruction, given its number.
It is the responsibility of the caller to ensure that the new instruction
occupies exactly as many bytes as the former one . */
template < typename B >
void
overwriteInstruction ( int instruction_number , const B & new_instruction )
{
seekp ( instructions_positions . at ( instruction_number ) ) ;
* this < < new_instruction ;
instructions_positions . pop_back ( ) ;
seekp ( 0 , ios_base : : end ) ;
}
} ;
// Overloads of operator<< for writing bytecode instructions
template < typename B >
BytecodeWriter &
operator < < ( BytecodeWriter & code_file , const B & instr )
{
code_file . instructions_positions . push_back ( code_file . tellp ( ) ) ;
code_file . write ( reinterpret_cast < const char * > ( & instr ) , sizeof ( B ) ) ;
return code_file ;
}
template < >
BytecodeWriter & operator < < ( BytecodeWriter & code_file , const FCALL_ & instr ) ;
template < >
BytecodeWriter & operator < < ( BytecodeWriter & code_file , const FBEGINBLOCK_ & instr ) ;
2022-06-16 17:52:14 +02:00
# endif // _BYTECODE_HH