/******************************************************************************/ /* ABSTRACT SYNTAX TREE - INLINE CODE******************************************/ /******************************************************************************/ #ifndef _H_EBCL_INLINE_SYNTAXTREE #define _H_EBCL_INLINE_SYNTAXTREE #include namespace ebcl { /*= T_SyntaxTree =============================================================*/ template< typename T , typename L , size_t S > T_SyntaxTree< T , L , S >::T_Node::T_Node( T_Self const& tree , const uint32_t node ) noexcept : tree{ tree } , node{ node } { // EMPTY } template< typename T , typename L , size_t S > T_SyntaxTree< T , L , S >::T_Node::T_Node( T_Node const& other ) noexcept : tree{ other.tree } , node{ other.node } { // EMPTY } template< typename T , typename L , size_t S > T_SyntaxTree< T , L , S >::T_Node::T_Node( T_Node&& other ) noexcept : T_Node( other ) { // EMPTY } template< typename T , typename L , size_t S > typename T_SyntaxTree< T , L , S >::T_Node& T_SyntaxTree< T , L , S >::T_Node::operator =( T_SyntaxTree< T , L , S >::T_Node const& other ) noexcept { assert( &other.tree == &tree ); node = other.node; return *this; } template< typename T , typename L , size_t S > typename T_SyntaxTree< T , L , S >::T_Node& T_SyntaxTree< T , L , S >::T_Node::operator =( T_SyntaxTree< T , L , S >::T_Node&& other ) noexcept { assert( &other.tree == &tree ); node = other.node; return *this; } /*----------------------------------------------------------------------------*/ template< typename T , typename L , size_t S > T_SyntaxTree< T , L , S >::T_Node_::T_Node_( const T nodeType , const uint32_t parent ) noexcept : type{ nodeType } , parent{ parent } , location{ } { // EMPTY } template< typename T , typename L , size_t S > T_SyntaxTree< T , L , S >::T_Node_::T_Node_( T_Node_&& other ) noexcept : type{ other.type } , parent{ other.parent } , location{ other.location } , children{ std::move( other.children ) } , data{ std::move( other.data ) } { // EMPTY } template< typename T , typename L , size_t S > typename T_SyntaxTree< T , L , S >::T_Node_& T_SyntaxTree< T , L , S >::T_Node_::operator =( T_Node_&& other ) noexcept { type = other.type; parent = other.parent; location = other.location; children = std::move( other.children ); data = std::move( other.data ); return *this; } /*----------------------------------------------------------------------------*/ template< typename T , typename L , size_t S > T_SyntaxTree< T , L , S >::T_SyntaxTree( const T rootType ) noexcept : nodes_( 64 ) { nodes_.addNew( rootType , 0 ); } /*----------------------------------------------------------------------------*/ template< typename T , typename L , size_t S > T_SyntaxTree< T , L , S >::T_SyntaxTree( T_SyntaxTree< T , L , S >&& other ) noexcept : nodes_{ std::move( other.nodes_ ) } { // EMPTY } template< typename T , typename L , size_t S > T_SyntaxTree< T , L , S >& T_SyntaxTree< T , L , S >::operator =( T_SyntaxTree< T , L , S >&& other ) noexcept { nodes_ = std::move( other.nodes_ ); return *this; } /*----------------------------------------------------------------------------*/ template< typename T , typename L , size_t S > T_SyntaxTree< T , L , S >& T_SyntaxTree< T , L , S >::swap( T_SyntaxTree< T , L , S >& other ) noexcept { using std::swap; swap( nodes_ , other.nodes_ ); return *this; } template< typename T , typename L , size_t S > void swap( T_SyntaxTree< T , L , S >& lhs , T_SyntaxTree< T , L , S >& rhs ) noexcept { lhs.swap( rhs ); } /*----------------------------------------------------------------------------*/ template< typename T , typename L , size_t S > T T_SyntaxTree< T , L , S >::typeOf( const uint32_t node ) const noexcept { return nodes_[ node ].type; } template< typename T , typename L , size_t S > uint32_t T_SyntaxTree< T , L , S >::parentOf( const uint32_t node ) const noexcept { return nodes_[ node ].parent; } template< typename T , typename L , size_t S > T_AutoArray< uint32_t , 8 > const& T_SyntaxTree< T , L , S >::childrenOf( const uint32_t node ) const noexcept { return nodes_[ node ].children; } template< typename T , typename L , size_t S > bool T_SyntaxTree< T , L , S >::hasData( const uint32_t node ) const noexcept { return bool( nodes_[ node ].data ); } template< typename T , typename L , size_t S > template< typename D > D const& T_SyntaxTree< T , L , S >::dataOf( const uint32_t node ) const { return nodes_[ node ].data.template value< D >( ); } template< typename T , typename L , size_t S > L const& T_SyntaxTree< T , L , S >::locationOf( const uint32_t node ) const noexcept { return nodes_[ node ].location; } /*----------------------------------------------------------------------------*/ template< typename T , typename L , size_t S > uint32_t T_SyntaxTree< T , L , 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 , typename L , size_t S > template< typename D , typename ... ArgTypes > D& T_SyntaxTree< T , L , 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 , typename L , size_t S > template< typename D > D& T_SyntaxTree< T , L , S >::dataOf( const uint32_t node ) { return nodes_[ node ].data.template value< D >( ); } template< typename T , typename L , size_t S > L& T_SyntaxTree< T , L , S >::locationOf( const uint32_t node ) noexcept { return nodes_[ node ].location; } /*----------------------------------------------------------------------------*/ template< typename T , typename L , size_t S > typename T_SyntaxTree< T , L , S >::T_Visitor T_SyntaxTree< T , L , 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 , typename L , size_t S > typename T_SyntaxTree< T , L , S >::T_Node T_SyntaxTree< T , L , S >::root( ) const noexcept { return T_Node{ *this , 0 }; } } // namespace #endif // _H_EBCL_INLINE_SYNTAXTREE