2018-03-31 16:58:13 +02:00
|
|
|
/******************************************************************************/
|
|
|
|
/* ABSTRACT SYNTAX TREE - INLINE CODE******************************************/
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
#ifndef _H_EBCL_INLINE_SYNTAXTREE
|
|
|
|
#define _H_EBCL_INLINE_SYNTAXTREE
|
|
|
|
#include <ebcl/SyntaxTree.hh>
|
|
|
|
namespace ebcl {
|
|
|
|
|
|
|
|
|
|
|
|
/*= T_SyntaxTree =============================================================*/
|
|
|
|
|
2018-03-31 22:11:00 +02:00
|
|
|
template< typename T , size_t S >
|
|
|
|
T_SyntaxTree< T , S >::T_Node::T_Node(
|
|
|
|
T_Self const& tree ,
|
|
|
|
const uint32_t node ) noexcept
|
|
|
|
: tree{ tree } , node{ node }
|
|
|
|
{
|
|
|
|
// EMPTY
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
T_SyntaxTree< T , S >::T_Node::T_Node(
|
|
|
|
T_Node const& other ) noexcept
|
|
|
|
: tree{ other.tree } , node{ other.node }
|
|
|
|
{
|
|
|
|
// EMPTY
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
T_SyntaxTree< T , S >::T_Node::T_Node(
|
|
|
|
T_Node&& other ) noexcept
|
|
|
|
: T_Node( other )
|
|
|
|
{
|
|
|
|
// EMPTY
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator =(
|
|
|
|
T_SyntaxTree< T , S >::T_Node const& other ) noexcept
|
|
|
|
{
|
|
|
|
assert( &other.tree == &tree );
|
|
|
|
node = other.node;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator =(
|
|
|
|
T_SyntaxTree< T , S >::T_Node&& other ) noexcept
|
|
|
|
{
|
|
|
|
assert( &other.tree == &tree );
|
|
|
|
node = other.node;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
2018-03-31 16:58:13 +02:00
|
|
|
template< typename T , size_t S >
|
|
|
|
T_SyntaxTree< T , S >::T_Node_::T_Node_(
|
|
|
|
const T nodeType ,
|
|
|
|
const uint32_t parent ) noexcept
|
|
|
|
: type{ nodeType } , parent{ parent }
|
|
|
|
{
|
|
|
|
// EMPTY
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
T_SyntaxTree< T , S >::T_Node_::T_Node_(
|
|
|
|
T_Node_&& other ) noexcept
|
|
|
|
: type{ other.type } , parent{ other.parent } ,
|
|
|
|
children{ std::move( other.children ) } ,
|
|
|
|
data{ std::move( other.data ) }
|
|
|
|
{
|
|
|
|
// EMPTY
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
typename T_SyntaxTree< T , S >::T_Node_& T_SyntaxTree< T , S >::T_Node_::operator =(
|
|
|
|
T_Node_&& other ) noexcept
|
|
|
|
{
|
|
|
|
type = other.type;
|
|
|
|
parent = other.parent;
|
|
|
|
children = std::move( other.children );
|
|
|
|
data = std::move( other.data );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
T_SyntaxTree< T , S >::T_SyntaxTree(
|
|
|
|
const T rootType ) noexcept
|
|
|
|
: nodes_( 64 )
|
|
|
|
{
|
|
|
|
nodes_.addNew( rootType , 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
T_SyntaxTree< T , S >::T_SyntaxTree(
|
|
|
|
T_SyntaxTree< T , S >&& other ) noexcept
|
|
|
|
: nodes_{ std::move( other.nodes_ ) }
|
|
|
|
{
|
|
|
|
// EMPTY
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::operator =(
|
|
|
|
T_SyntaxTree< T , S >&& other ) noexcept
|
|
|
|
{
|
|
|
|
nodes_ = std::move( other.nodes_ );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::swap(
|
|
|
|
T_SyntaxTree< T , S >& other ) noexcept
|
|
|
|
{
|
|
|
|
using std::swap;
|
|
|
|
swap( nodes_ , other.nodes_ );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
void swap( T_SyntaxTree< T , S >& lhs ,
|
|
|
|
T_SyntaxTree< T , S >& rhs ) noexcept
|
|
|
|
{
|
|
|
|
lhs.swap( rhs );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
T T_SyntaxTree< T , S >::typeOf(
|
|
|
|
const uint32_t node ) const noexcept
|
|
|
|
{
|
|
|
|
return nodes_[ node ].type;
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
uint32_t T_SyntaxTree< T , S >::parentOf(
|
|
|
|
const uint32_t node ) const noexcept
|
|
|
|
{
|
|
|
|
return nodes_[ node ].parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
T_AutoArray< uint32_t , 8 > const& T_SyntaxTree< T , S >::childrenOf(
|
|
|
|
const uint32_t node ) const noexcept
|
|
|
|
{
|
|
|
|
return nodes_[ node ].children;
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
bool T_SyntaxTree< T , S >::hasData(
|
|
|
|
const uint32_t node ) const noexcept
|
|
|
|
{
|
|
|
|
return bool( nodes_[ node ].data );
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
template< typename D >
|
|
|
|
D const& T_SyntaxTree< T , S >::dataOf(
|
|
|
|
const uint32_t node ) const
|
|
|
|
{
|
|
|
|
return nodes_[ node ].data.template value< D >( );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
uint32_t T_SyntaxTree< T , S >::addChild(
|
|
|
|
const uint32_t parent ,
|
|
|
|
const E_Node type ) noexcept
|
|
|
|
{
|
|
|
|
T_Node_ node{ type , parent };
|
|
|
|
const auto idx{ nodes_.add( std::move( node ) ) };
|
|
|
|
assert( idx != parent );
|
|
|
|
nodes_[ parent ].children.add( idx );
|
|
|
|
return idx;
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
template< typename D , typename ... ArgTypes >
|
|
|
|
D& T_SyntaxTree< T , S >::newData(
|
|
|
|
const uint32_t node ,
|
|
|
|
ArgTypes&& ... args )
|
|
|
|
{
|
|
|
|
auto& data{ nodes_[ node ].data };
|
|
|
|
data.template setNew< D >( std::forward< ArgTypes >( args ) ... );
|
|
|
|
return data.template value< D >( );
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
template< typename D >
|
|
|
|
D& T_SyntaxTree< T , S >::dataOf(
|
|
|
|
const uint32_t node )
|
|
|
|
{
|
|
|
|
return nodes_[ node ].data.template value< D >( );
|
|
|
|
}
|
|
|
|
|
2018-03-31 22:11:00 +02:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
typename T_SyntaxTree< T , S >::T_Visitor T_SyntaxTree< T , S >::visitor( ) const noexcept
|
|
|
|
{
|
|
|
|
return T_Visitor{
|
|
|
|
[this]( T_Node node , uint32_t child ) -> T_Optional< T_Node > {
|
|
|
|
auto const& n{ nodes_[ node.node ] };
|
|
|
|
if ( child >= n.children.size( ) ) {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
return T_Node{ node.tree , n.children[ child ] };
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
template< typename T , size_t S >
|
|
|
|
typename T_SyntaxTree< T , S >::T_Node T_SyntaxTree< T , S >::root( ) const noexcept
|
|
|
|
{
|
|
|
|
return T_Node{ *this , 0 };
|
|
|
|
}
|
|
|
|
|
2018-03-31 16:58:13 +02:00
|
|
|
|
|
|
|
} // namespace
|
|
|
|
#endif // _H_EBCL_INLINE_SYNTAXTREE
|