blob: efce4f17d2ec12174f6150be448100146283f70f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#ifndef AVMCODE_H_
#define AVMCODE_H_
#include <common/AvmPointer.h>
#include <common/Element.h>
//#include <collection/BFContainer.h>
#include <collection/List.h>
#include <collection/Vector.h>
#include <computer/instruction/AvmInstruction.h>
#include <fml/operator/Operator.h>
namespace sep
{
class BaseTypeSpecifier;
class AvmCode :
public Element ,
public Vector< BF > ,
AVM_INJECT_INSTANCE_COUNTER_CLASS( AvmCode )
{
AVM_DECLARE_CLONABLE_CLASS( AvmCode )
public:
/**
* TYPEDEF
*/
typedef Vector< BF > this_container_type;
typedef this_container_type::const_iterator const_iterator;
typedef this_container_type::iterator iterator;
typedef this_container_type::const_reverse_iterator const_reverse_iterator;
typedef this_container_type::reverse_iterator reverse_iterator;
typedef this_container_type::size_type size_type;
protected:
/*
* ATTRIBUTES
*/
Operator * mOperator;
AvmInstruction * mInstruction;
public:
/**
* CONSTRUCTOR
* Default
*/
AvmCode()
: Element( CLASS_KIND_T( AvmCode ) ),
this_container_type(),
mOperator( NULL ),
mInstruction( NULL )
{
//!! NOTHING
}
/**
* CONSTRUCTOR
* Copy
*/
AvmCode(const AvmCode & anElement)
: Element( anElement ),
this_container_type( anElement ),
mOperator( anElement.mOperator ),
mInstruction( (anElement.mInstruction == NULL) ? NULL
: new AvmInstruction( *(anElement.mInstruction) ) )
{
//!! NOTHING
}
/**
* CONSTRUCTOR
* Others
*/
AvmCode(Operator * anOperator)
: Element( CLASS_KIND_T( AvmCode ) ),
this_container_type( ),
mOperator( anOperator ),
mInstruction( NULL )
{
//!! NOTHING
}
AvmCode(Operator * anOperator, const BF & arg)
: Element( CLASS_KIND_T( AvmCode ) ),
this_container_type( arg ),
mOperator( anOperator ),
mInstruction( NULL )
{
//!! NOTHING
}
AvmCode(Operator * anOperator, const BF & arg1, const BF & arg2)
: Element( CLASS_KIND_T( AvmCode ) ),
this_container_type( arg1 , arg2 ),
mOperator( anOperator ),
mInstruction( NULL )
{
//!! NOTHING
}
AvmCode(Operator * anOperator, const BF & arg1,
const BF & arg2, const BF & arg3)
: Element( CLASS_KIND_T( AvmCode ) ),
this_container_type( arg1 , arg2 , arg3 ),
mOperator( anOperator ),
mInstruction( NULL )
{
//!! NOTHING
}
AvmCode(Operator * anOperator, const BF & arg1,
const BF & arg2, const BF & arg3, const BF & arg4)
: Element( CLASS_KIND_T( AvmCode ) ),
this_container_type( arg1 , arg2 , arg3 , arg4 ),
mOperator( anOperator ),
mInstruction( NULL )
{
//!! NOTHING
}
AvmCode(Operator * anOperator, const BF & arg1, const BF & arg2,
const BF & arg3, const BF & arg4, const BF & arg5)
: Element( CLASS_KIND_T( AvmCode ) ),
this_container_type( arg1 , arg2 , arg3 , arg4 , arg5 ),
mOperator( anOperator ),
mInstruction( NULL )
{
//!! NOTHING
}
/**
* DESTRUCTOR
*/
virtual ~AvmCode()
{
delete ( mInstruction );
}
/**
* GETTER
* this_container_type
*/
inline this_container_type & getArgs()
{
return( *this );
}
inline const this_container_type & getArgs() const
{
return( *this );
}
/**
* APPEND
* this_container_type
*/
inline void append(const BF & anElement)
{
// AVM_OS_ASSERT_FATAL_ERROR_EXIT( isUnique() )
// << "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
// << strRefCount() << " " << str() << " !!!" !!!"
// << SEND_EXIT;
this_container_type::append( anElement );
}
inline void append(const this_container_type & anElement)
{
// AVM_OS_ASSERT_FATAL_ERROR_EXIT( isUnique() )
// << "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
// << strRefCount() << " " << str() << " !!!"
// << SEND_EXIT;
this_container_type::append( anElement );
}
inline void appendTail(const this_container_type & anElement)
{
// AVM_OS_ASSERT_FATAL_ERROR_EXIT( isUnique() )
// << "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
// << strRefCount() << " " << str() << " !!!"
// << SEND_EXIT;
this_container_type::appendTail( anElement );
}
inline void append(const List< BF > & anElement)
{
// AVM_OS_ASSERT_FATAL_ERROR_EXIT( isUnique() )
// << "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
// << strRefCount() << " " << str() << " !!!"
// << SEND_EXIT;
this_container_type::append( anElement );
}
inline void append(const List< BFCode > & anElement)
{
// AVM_OS_ASSERT_FATAL_ERROR_EXIT( isUnique() )
// << "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
// << strRefCount() << " " << str() << " !!!"
// << SEND_EXIT;
this_container_type::append( anElement );
}
inline void appendFlat(const BF & anElement)
{
if( anElement.is< AvmCode >()
&& getOperator()->isWeakAssociative()
&& (anElement.to_ptr< AvmCode >()->getOperator() == getOperator()) )
{
append( anElement.to_ptr< AvmCode >()->getArgs() );
}
else
{
append( anElement );
}
}
/**
* GETTER - SETTER
* for element of this_container_type
*/
inline virtual BF & at(avm_size_t offset)
{
return( this_container_type::at(offset) );
}
inline virtual const BF & at(avm_size_t offset) const
{
return( this_container_type::at(offset) );
}
inline AvmCode * codeAt(avm_size_t offset)
{
return( this_container_type::at(offset).as_ptr< AvmCode >() );
}
inline const AvmCode * codeAt(avm_size_t offset) const
{
return( this_container_type::at(offset).as_ptr< AvmCode >() );
}
virtual BF & operator[](avm_size_t offset)
{
return( this_container_type::operator[](offset) );
}
virtual const BF & operator[](avm_size_t offset) const
{
return( this_container_type::operator[](offset) );
}
inline virtual BF & getWritable(avm_size_t offset)
{
this_container_type::at(offset).makeWritable();
return( this_container_type::operator[](offset) );
}
inline virtual void makeWritable(avm_size_t offset)
{
this_container_type::at(offset).makeWritable();
}
inline virtual void safe_set(avm_size_t index, const BF & anElement)
{
this_container_type::operator[](index) = anElement;
}
inline virtual void set(avm_size_t index, const BF & anElement)
{
// AVM_OS_ASSERT_FATAL_ERROR_EXIT( isUnique() )
// << "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
// << strRefCount() << " " << str() << " !!!"
// << SEND_EXIT;
////////////////////////////////////////////////////////////////////////
//!!! OPTIMISATION
////////////////////////////////////////////////////////////////////////
// this_container_type::set(index, anElement);
AVM_OS_ASSERT_FATAL_ARRAY_INDEX_EXIT( index , size() )
<< SEND_EXIT;
this_container_type::operator[](index) = anElement;
}
inline avm_size_t size() const
{
return( this_container_type::size() );
}
/**
* GETTER - SETTER
* for mOperator
*/
inline Operator * getOperator() const
{
return( mOperator );
}
inline AVM_OPCODE getAvmOpCode() const
{
return( mOperator->getAvmOpCode() );
}
inline AVM_OPCODE getOptimizedOpCode() const
{
return( mOperator->getOptimizedOpCode() );
}
inline avm_offset_t getOpOffset() const
{
return( mOperator->getOffset() );
}
inline bool hasOperator() const
{
return( mOperator != NULL );
}
inline bool isOperator(Operator * op) const
{
return( mOperator->isEQ( op ) );
}
inline bool isnotOperator(Operator * op) const
{
return( mOperator->isNEQ( op ) );
}
inline bool isOpCode(AVM_OPCODE opCode) const
{
return( mOperator->isOpCode( opCode ) );
}
inline bool hasOpCode(AVM_OPCODE opCode1, AVM_OPCODE opCode2) const
{
return( mOperator->hasOpCode( opCode1 , opCode2 ) );
}
inline bool hasOpCode(AVM_OPCODE opCode1,
AVM_OPCODE opCode2, AVM_OPCODE opCode3) const
{
return( mOperator->hasOpCode( opCode1 , opCode2 , opCode3 ) );
}
inline bool isOpCode(Operator * op) const
{
return( mOperator->isOpCode( op ) );
}
inline bool isOptimizedOpCode(AVM_OPCODE opCode) const
{
return( mOperator->isOptimizedOpCode( opCode ) );
}
inline bool sameOperator(const AvmCode & aCode) const
{
return( mOperator->isEQ( aCode.mOperator ) );
}
inline bool sameOperator(AvmCode * aCode) const
{
return( mOperator->isEQ( aCode->mOperator ) );
}
inline bool isnotOpCode(AVM_OPCODE opCode) const
{
return( mOperator->isnotOpCode( opCode ) );
}
inline void setOperator(Operator * anOperator)
{
mOperator = anOperator;
}
inline const std::string & strOperator() const
{
return( mOperator->standardSymbol() );
}
/**
* GETTER - SETTER
* for mInstruction
*/
inline AvmInstruction * getInstruction() const
{
return( mInstruction );
}
inline bool hasInstruction() const
{
return( mInstruction != NULL );
}
inline AvmInstruction * newEmptyInstruction()
{
AVM_OS_ASSERT_FATAL_ERROR_EXIT( mInstruction == NULL )
<< "Unexpected a code with AvmInstruction: "
<< toStringWithBytecode()
<< SEND_EXIT;
return( mInstruction = new AvmInstruction() );
}
inline AvmInstruction * newInstruction(avm_size_t aSize)
{
AVM_OS_ASSERT_FATAL_ERROR_EXIT( mInstruction == NULL )
<< "Unexpected a code with AvmInstruction: "
<< toStringWithBytecode()
<< SEND_EXIT;
return( mInstruction = new AvmInstruction( aSize ) );
}
inline AvmInstruction * genInstruction()
{
return( newInstruction( size() ) );
}
inline void setInstruction(AvmInstruction * anInstruction)
{
mInstruction = anInstruction;
}
/**
* COMPARISON
* OPERATOR
*/
int compare(const AvmCode & other) const;
inline bool operator==(const AvmCode & other) const
{
return( AvmCode::isEQ( other ) );
}
inline bool operator==(AvmCode * other) const
{
return( (other != NULL) && AvmCode::isEQ( *other ) );
}
inline bool operator!=(const AvmCode & other) const
{
return( (this != &other) && (not AvmCode::isEQ( other )) );
}
inline bool operator!=(AvmCode * other) const
{
return( (other == NULL)
|| ((this != other)
&& (not AvmCode::isEQ( *other ) ) ) );
}
bool isEQ(const AvmCode & other) const;
inline bool isEQ(AvmCode * other) const
{
return( (other != NULL) && AvmCode::isEQ( *other ) );
}
/**
* Serialization
*/
std::string strDebug(const AvmIndent & indent = AVM_SPC_INDENT) const
{
StringOutStream oss(indent);
toDebug( oss );
return( oss.str() );
}
OutStream & toDebug(OutStream & out) const;
OutStream & toStreamWithBytecode(OutStream & out) const;
std::string toStringWithBytecode(
const AvmIndent & indent = AVM_TAB_INDENT) const
{
StringOutStream oss(indent);
toStreamWithBytecode( oss );
return( oss.str() );
}
OutStream & toStreamRoutine(OutStream & out) const;
void toStreamPrefix(OutStream & out, bool printEOL = true) const;
static void toStreamPrefix(OutStream & out, const BF & arg);
inline static void toStream(OutStream & out, const BF & arg)
{
// toStreamPrefix(out, arg);
prettyPrinter(out, arg);
}
inline virtual void toStream(OutStream & out) const
{
AVM_IF_DEBUG_FLAG( BYTECODE )
toStreamPrefix( out );
return;
AVM_ENDIF_DEBUG_FLAG( BYTECODE )
prettyPrinter( out );
}
/**
* PRETTY PRINTER
*/
void prettyPrinter(OutStream & out, bool isStatement = true) const;
void prettyPrinterBasicStatement(
OutStream & out, bool isStatement = true) const;
void prettyPrinterBlockStatement(
OutStream & out, bool isStatement = true) const;
void prettyPrinterDefault(OutStream & out, bool isStatement = true) const;
void prettyPrinterFunctional(OutStream & out) const;
void prettyPrinterInfix(OutStream & out) const;
void prettyPrinterPrefix(OutStream & out) const;
void prettyPrinterSuffix(OutStream & out) const;
static void prettyPrinter(OutStream & out,
const BF & arg, bool isStatement = true);
static void prettyPrinter(OutStream & out,
const BF & arg, BaseTypeSpecifier * aType);
static void prettyPrinterCondition(OutStream & out, const BF & arg);
static void prettyPrinterBlock(OutStream & out, const BF & arg);
/**
* toString
*/
inline virtual std::string toString(
const AvmIndent & indent = AVM_TAB_INDENT) const
{
StringOutStream oss(indent);
// toStream(oss);
prettyPrinter(oss);
return( oss.str() );
}
inline virtual std::string str() const
{
StringOutStream oss( AVM_STR_INDENT );
// toStream(oss);
prettyPrinter( oss << IGNORE_FIRST_TAB );
return( oss.str() );
}
};
/**
* operator<<
*/
AVM_OS_STREAM( AvmCode )
#define AVM_DEBUG_BFCODE_POINTER true
#undef AVM_DEBUG_BFCODE_POINTER
#if defined(AVM_DEBUG_BFCODE_POINTER)
// #define AVM_DECLARE_DEBUG_BFCODE_PTR const AvmCode * debugPTR;
//
// #define AVM_INIT_DEBUG_BFCODE_PTR( ptr ) , debugPTR( ptr )
//
// #define AVM_ASSIGN_STMNT_DEBUG_BFCODE_PTR( ptr ) debugPTR = ptr;
//
// #define AVM_ASSIGN_EXPR_DEBUG_BFCODE_PTR( ptr ) debugPTR = ptr
#define AVM_DECLARE_DEBUG_BFCODE_PTR public: std::string dbgPTR;
#define AVM_STR_BFCODE_PTR( ptr ) ( (ptr != NULL) ? ptr->str() : "BFCode<null>" )
#define AVM_INIT_DEBUG_BFCODE_PTR_NULL , dbgPTR( "BFCode<null>" )
#define AVM_INIT_DEBUG_BFCODE_PTR( ptr ) , dbgPTR( AVM_STR_BFCODE_PTR(ptr) )
#define AVM_COPY_DEBUG_BFCODE_PTR( bf ) , dbgPTR( bf.dbgPTR )
#define AVM_ASSIGN_DEBUG_BFCODE_PTR( ptr ) dbgPTR = AVM_STR_BFCODE_PTR(ptr);
#else
#define AVM_DECLARE_DEBUG_BFCODE_PTR
#define AVM_INIT_DEBUG_BFCODE_PTR( ptr )
#define AVM_ASSIGN_STMNT_DEBUG_BFCODE_PTR( ptr )
#define AVM_ASSIGN_EXPR_DEBUG_BFCODE_PTR( ptr ) ptr
#endif
class BFCode :
public BF ,
AVM_INJECT_INSTANCE_COUNTER_CLASS( BFCode )
{
protected:
/**
* Only for debug facilities
*/
AVM_DECLARE_DEBUG_BFCODE_PTR
public:
/**
* CONSTRUCTOR
* Default
*/
BFCode()
: BF()
AVM_INIT_DEBUG_BFCODE_PTR( NULL )
{
//!! NOTHING
}
/**
* CONSTRUCTOR
* Copy
*/
BFCode(const BFCode & other)
: BF( other )
AVM_INIT_DEBUG_BFCODE_PTR( other.debugPTR )
{
//!! NOTHING
}
// explicit BFCode(const BF & other)
// : BF( ( other.is< AvmCode >() ) ? other : BFCode::REF_NULL )
// AVM_INIT_DEBUG_BFCODE_PTR( ( other.is< AvmCode >() ) ?
// static_cast< const AvmCode * >( other.raw_pointer() ) : NULL )
// {
// AVM_OS_ASSERT_FATAL_ERROR_EXIT( other.invalid() || other.is< AvmCode >() )
// << "Invalid Constructor Cast of a BF to a BFCode !!!"
// << SEND_EXIT;
// }
explicit BFCode(AvmCode * aCode)
: BF( AVM_ASSIGN_EXPR_DEBUG_BFCODE_PTR( aCode ) )
{
//!! NOTHING
}
/**
* CONSTRUCTOR
* Others
*/
BFCode(Operator * anOperator)
: BF( AVM_ASSIGN_EXPR_DEBUG_BFCODE_PTR(
new AvmCode(anOperator) ) )
{
//!! NOTHING
}
BFCode(Operator * anOperator, const BF & arg)
: BF( AVM_ASSIGN_EXPR_DEBUG_BFCODE_PTR(
new AvmCode(anOperator, arg) ) )
{
//!! NOTHING
}
BFCode(Operator * anOperator, const BF & arg1, const BF & arg2)
: BF( AVM_ASSIGN_EXPR_DEBUG_BFCODE_PTR(
new AvmCode(anOperator, arg1, arg2) ) )
{
//!! NOTHING
}
BFCode(Operator * anOperator, const BF & arg1,
const BF & arg2, const BF & arg3)
: BF( AVM_ASSIGN_EXPR_DEBUG_BFCODE_PTR(
new AvmCode(anOperator, arg1, arg2, arg3) ) )
{
//!! NOTHING
}
BFCode(Operator * anOperator, const BF & arg1, const BF & arg2,
const BF & arg3, const BF & arg4)
: BF( AVM_ASSIGN_EXPR_DEBUG_BFCODE_PTR(
new AvmCode(anOperator, arg1, arg2, arg3, arg4) ) )
{
//!! NOTHING
}
BFCode(Operator * anOperator, const BF & arg1, const BF & arg2,
const BF & arg3, const BF & arg4, const BF & arg5)
: BF( AVM_ASSIGN_EXPR_DEBUG_BFCODE_PTR(
new AvmCode(anOperator, arg1, arg2, arg3, arg4, arg5) ) )
{
//!! NOTHING
}
/**
* DESTRUCTOR
*/
virtual ~BFCode()
{
//!! NOTHING
}
/**
* CAST
*/
//protected:
inline operator AvmCode * () const
{
return( static_cast< AvmCode * >( mPTR ) );
}
inline AvmCode * raw_pointer() const
{
return( static_cast< AvmCode * >( mPTR ) );
}
/**
* OPERATORS
*/
inline AvmCode * operator-> () const
{
AVM_OS_ASSERT_FATAL_NULL_POINTER_EXIT( mPTR )
<< "Unexpected a BFCode with a NULL Pointer !!!"
<< SEND_EXIT;
return( static_cast< AvmCode * >( mPTR ) );
}
/**
* ASSIGNMENT
*/
inline BFCode & operator=(AvmCode * aPtr)
{
if( mPTR != aPtr )
{
AVM_ASSIGN_STMNT_DEBUG_BFCODE_PTR( aPtr )
release( aPtr );
}
return( *this );
}
inline BFCode & operator=(const BFCode & other)
{
if( mPTR != other.mPTR )
{
AVM_ASSIGN_STMNT_DEBUG_BFCODE_PTR( other.debugPTR )
release_acquire( other.mPTR );
}
return( *this );
}
inline BFCode & operator=(const BF & other)
{
AVM_OS_ASSERT_FATAL_ERROR_EXIT(
other.invalid() || other.is< AvmCode >() )
<< "Invalid Assignment Cast of a BF to a BFCode !!!"
<< SEND_EXIT;
if( mPTR != other.raw_pointer() )
{
AVM_ASSIGN_STMNT_DEBUG_BFCODE_PTR(
static_cast< AvmCode * >( other.raw_pointer() ) )
release_acquire( other.raw_pointer() );
}
return( *this );
}
/**
* COMPARISON
* OPERATOR
*/
inline bool operator==(const AvmCode & other) const
{
return( other.operator==( raw_pointer() ) );
}
inline bool operator==(AvmCode * other) const
{
return( (mPTR == other)
|| ((mPTR != NULL)
&& raw_pointer()->operator==( other ) ) );
}
inline bool operator==(const BFCode & other) const
{
return( (mPTR == other.raw_pointer())
|| ((mPTR != NULL)
&& raw_pointer()->operator==( other.raw_pointer() ) ) );
}
inline bool operator==(const BF & other) const
{
return( (mPTR == other.raw_pointer())
|| ((mPTR != NULL)
&& other.is< AvmCode >()
&& raw_pointer()->operator==(
other.to_ptr< AvmCode >() ) ) );
}
inline bool operator!=(const AvmCode & other) const
{
return( other.operator!=( raw_pointer() ) );
}
inline bool operator!=(AvmCode * other) const
{
return( (mPTR != other)
&& ((mPTR == NULL)
|| raw_pointer()->operator!=( other ) ) );
}
inline bool operator!=(const BFCode & other) const
{
return( (mPTR != other.raw_pointer())
&& ((mPTR == NULL)
|| raw_pointer()->operator!=( other.raw_pointer() ) ) );
}
inline bool operator!=(const BF & other) const
{
return( (mPTR != other.raw_pointer())
&& ((mPTR == NULL)
|| (other.is< AvmCode >()
&& raw_pointer()->operator!=(
other.to_ptr< AvmCode >() ) ) ) );
}
/**
* COMPARISON
*/
inline bool isEQ(const BF & other) const
{
return( BF::isEQ(other) );
}
inline bool isEQ(const BFCode & other) const
{
return( (mPTR == other.mPTR)
|| ((mPTR != NULL)
&& raw_pointer()->isEQ( other.raw_pointer() ) ) );
}
inline bool isNEQ(const BF & other) const
{
return( BF::isNEQ(other) );
}
inline bool isNEQ(const BFCode & other) const
{
return( not BFCode::isEQ(other) );
}
public:
/**
* SETTER
* this_container_type
*/
inline void append(const BF & anElement)
{
AVM_OS_ASSERT_FATAL_ERROR_EXIT( isWritable() )
<< "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
<< strRefCount() << " " << str() << " !!!"
<< SEND_EXIT;
static_cast< AvmCode * >( mPTR )->append(anElement);
}
inline void append(const List< BF > & anElement)
{
AVM_OS_ASSERT_FATAL_ERROR_EXIT( isWritable() )
<< "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
<< strRefCount() << " " << str() << " !!!"
<< SEND_EXIT;
static_cast< AvmCode * >( mPTR )->append( anElement );
}
inline void append(const List< BFCode > & anElement)
{
AVM_OS_ASSERT_FATAL_ERROR_EXIT( isWritable() )
<< "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
<< strRefCount() << " " << str() << " !!!"
<< SEND_EXIT;
static_cast< AvmCode * >( mPTR )->append( anElement );
}
inline void append(AvmCode::this_container_type & anElement)
{
AVM_OS_ASSERT_FATAL_ERROR_EXIT( isWritable() )
<< "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
<< strRefCount() << " " << str() << " !!!"
<< SEND_EXIT;
static_cast< AvmCode * >( mPTR )->append( anElement );
}
inline void appendFlat(const BF & anElement)
{
AVM_OS_ASSERT_FATAL_ERROR_EXIT( isWritable() )
<< "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
<< strRefCount() << " " << str() << " !!!"
<< SEND_EXIT;
static_cast< AvmCode * >( mPTR )->appendFlat( anElement );
}
inline AvmCode::this_container_type & getArgs()
{
return( static_cast< AvmCode * >( mPTR )->getArgs() );
}
inline void set(avm_size_t index, const BF & anElement)
{
AVM_OS_ASSERT_FATAL_ERROR_EXIT( isWritable() )
<< "ILLEGAL MODIFICATION OF A NON UNIQUE REFERENCE :> "
<< strRefCount() << " " << str() << " !!!"
<< SEND_EXIT;
static_cast< AvmCode * >( mPTR )->set( index , anElement );
}
/**
* GETTER
* for BFCode
*/
inline virtual BFCode & codeAt(avm_size_t offset)
{
return( static_cast< AvmCode * >( mPTR )->at(offset).bfCode() );
}
inline virtual const BFCode & codeAt(avm_size_t offset) const
{
return( static_cast< AvmCode * >( mPTR )->at(offset).bfCode() );
}
/**
* GETTER
* for iterators
*/
inline AvmCode::iterator begin()
{
return( static_cast< AvmCode * >( mPTR )->begin() );
}
inline AvmCode::iterator end()
{
return( static_cast< AvmCode * >( mPTR )->end() );
}
inline AvmCode::const_iterator begin() const
{
return( static_cast< AvmCode * >( mPTR )->begin() );
}
inline AvmCode::const_iterator end() const
{
return( static_cast< AvmCode * >( mPTR )->end() );
}
/**
* GETTER
* for reverse_iterators
*/
inline AvmCode::reverse_iterator rbegin()
{
return( static_cast< AvmCode * >( mPTR )->rbegin() );
}
inline AvmCode::reverse_iterator rend()
{
return( static_cast< AvmCode * >( mPTR )->rend() );
}
inline AvmCode::const_reverse_iterator rbegin() const
{
return( static_cast< AvmCode * >( mPTR )->rbegin() );
}
inline AvmCode::const_reverse_iterator rend() const
{
return( static_cast< AvmCode * >( mPTR )->rend() );
}
/**
* GETTER - SETTER
* for mOperator
*/
inline Operator * getOperator() const
{
return( static_cast< AvmCode * >( mPTR )->getOperator() );
}
inline AVM_OPCODE getAvmOpCode() const
{
return( static_cast< AvmCode * >( mPTR )->getAvmOpCode() );
}
inline bool hasOperator() const
{
return( static_cast< AvmCode * >( mPTR )->hasOperator() );
}
inline void setOperator(Operator * anOperator)
{
static_cast< AvmCode * >( mPTR )->setOperator( anOperator );
}
/**
* DEFAULT NULL
*/
static BFCode REF_NULL;
/**
***************************************************************************
* SERIALIZATION
***************************************************************************
*/
inline virtual void toStream(OutStream & out) const
{
if( mPTR != NULL )
{
static_cast< AvmCode * >( mPTR )->toStream(out);
}
else
{
out << TAB << "BFCode<null>" << EOL_FLUSH;
}
}
inline virtual std::string toString(
const AvmIndent & indent = AVM_TAB_INDENT) const
{
StringOutStream oss(indent);
toStream(oss);
return( oss.str() );
}
inline virtual std::string str() const
{
return( ( mPTR == NULL ) ? "BFCode<null>" :
static_cast< AvmCode * >( mPTR )->str() );
}
inline virtual void AVM_DEBUG_REF_COUNTER(OutStream & out) const
{
if( mPTR != NULL )
{
mPTR->AVM_DEBUG_REF_COUNTER(out);
}
else
{
out << "BFCode<null, ref:0>" << std::flush;
}
}
inline virtual std::string AVM_DEBUG_REF_COUNTER() const
{
return( ( mPTR != NULL ) ? mPTR->AVM_DEBUG_REF_COUNTER() :
"BFCode<null, ref:0>" );
}
inline virtual std::string strRefCount() const
{
return( ( mPTR != NULL ) ? mPTR->strRefCount() :
"BFCode<null, ref:0>" );
}
};
/**
* operator<<
*/
AVM_OS_STREAM( BFCode )
}
#endif /*AVMCODE_H_*/