Parser - Refactored AST nodes

AST nodes use the same storage structure, whatever their nature.
This commit is contained in:
Emmanuel BENOîT 2017-12-13 21:44:50 +01:00
parent efa1b26150
commit 5f6eee238f
4 changed files with 247 additions and 190 deletions

View file

@ -131,7 +131,7 @@ A_Node* opast::ASTVisitorBrowser(
case A_Node::OP_CALL: case A_Node::OP_CALL:
{ {
auto& n( (T_CallInstrNode&) node ); auto& n( (T_CallInstrNode&) node );
const auto nArgs( n.arguments( ) ); const auto nArgs( n.size( ) );
if ( child < nArgs ) { if ( child < nArgs ) {
return &n.argument( nArgs - child - 1 ); return &n.argument( nArgs - child - 1 );
} }
@ -151,7 +151,7 @@ A_Node* opast::ASTVisitorBrowser(
case A_Node::OP_CLEAR: case A_Node::OP_CLEAR:
{ {
auto& n( (T_ClearInstrNode&) node ); auto& n( (T_ClearInstrNode&) node );
const auto nArgs( n.components( ) ); const auto nArgs( n.size( ) );
if ( child < nArgs ) { if ( child < nArgs ) {
return &n.component( nArgs - child - 1 ); return &n.component( nArgs - child - 1 );
} }
@ -272,7 +272,7 @@ A_Node* opast::ASTVisitorBrowser(
case A_Node::OP_UNIFORMS: case A_Node::OP_UNIFORMS:
{ {
auto& n( (T_UniformsInstrNode&) node ); auto& n( (T_UniformsInstrNode&) node );
const auto nv( n.values( ) ); const auto nv( n.size( ) );
if ( child < nv ) { if ( child < nv ) {
return &n.value( nv - child - 1 ); return &n.value( nv - child - 1 );
} }
@ -348,15 +348,13 @@ A_FuncNode::A_FuncNode(
const bool isInit , const bool isInit ,
T_RootNode* const root ) noexcept T_RootNode* const root ) noexcept
: A_Node( isInit ? DECL_INIT : DECL_FRAME , root ) , : A_Node( isInit ? DECL_INIT : DECL_FRAME , root ) ,
name_( isInit ? "*init*" : "*frame*" ) , name_( isInit ? "*init*" : "*frame*" )
instructions_( *this )
{ } { }
A_FuncNode::A_FuncNode( A_FuncNode::A_FuncNode(
T_String const& name , T_String const& name ,
T_RootNode* const root ) noexcept T_RootNode* const root ) noexcept
: A_Node( DECL_FN , root ) , name_( name ) , : A_Node( DECL_FN , root ) , name_( name )
instructions_( *this )
{ } { }
T_Optional< T_SRDLocation > A_FuncNode::addLocalVariable( T_Optional< T_SRDLocation > A_FuncNode::addLocalVariable(
@ -377,10 +375,7 @@ T_Optional< T_SRDLocation > A_FuncNode::addLocalVariable(
/*= T_RootNode ===============================================================*/ /*= T_RootNode ===============================================================*/
T_RootNode::T_RootNode( ) noexcept T_RootNode::T_RootNode( ) noexcept
: A_Node( ROOT , nullptr ) , functions_( : A_Node( ROOT , nullptr )
[]( T_OwnPtr< A_FuncNode > const& f ) {
return f->name( );
} )
{ } { }
T_RootNode::T_AddFunctionResult T_RootNode::addFunction( T_RootNode::T_AddFunctionResult T_RootNode::addFunction(
@ -390,7 +385,8 @@ T_RootNode::T_AddFunctionResult T_RootNode::addFunction(
auto const* const pf( functions_.get( fn ) ); auto const* const pf( functions_.get( fn ) );
if ( !pf ) { if ( !pf ) {
auto* const rv( function.get( ) ); auto* const rv( function.get( ) );
functions_.add( std::move( function ) ); functions_.add( fn , children_.size( ) );
children_.add( std::move( function ) );
return *rv; return *rv;
} }
@ -404,8 +400,9 @@ T_RootNode::T_AddFunctionResult T_RootNode::addFunction(
T_OwnPtr< A_FuncNode > df( NewOwned< T_FuncNode >( dfn , *this ) ); T_OwnPtr< A_FuncNode > df( NewOwned< T_FuncNode >( dfn , *this ) );
auto* const rv( df.get( ) ); auto* const rv( df.get( ) );
functions_.add( std::move( df ) ); functions_.add( fn , children_.size( ) );
return T_AddFunctionResult{ *rv , (*pf)->location( ) }; children_.add( std::move( df ) );
return T_AddFunctionResult{ *rv , child( *pf )->location( ) };
} }
@ -475,7 +472,9 @@ T_UnaryOperatorNode::T_UnaryOperatorNode(
} }
std::abort( ); std::abort( );
})( ) , parent ) , op_( op ) })( ) , parent ) , op_( op )
{ } {
children_.add( P_ExpressionNode{} );
}
/*= T_BinaryOperatorNode =====================================================*/ /*= T_BinaryOperatorNode =====================================================*/
@ -499,18 +498,21 @@ T_BinaryOperatorNode::T_BinaryOperatorNode(
} }
std::abort( ); std::abort( );
})( ) , parent ) , op_( op ) })( ) , parent ) , op_( op )
{ } {
children_.add( P_ExpressionNode{} );
children_.add( P_ExpressionNode{} );
}
void T_BinaryOperatorNode::replaceChild( void T_BinaryOperatorNode::replaceChild(
A_Node const& child , A_Node const& ch ,
T_OwnPtr< A_Node > replacement T_OwnPtr< A_Node > replacement
) noexcept ) noexcept
{ {
if ( right_.get( ) == &child ) { if ( child( 0 ).get( ) == &ch ) {
right_ = std::move( replacement ); child( 0 ) = std::move( replacement );
} else { } else {
assert( left_.get( ) == &child ); assert( child( 1 ).get( ) == &ch );
left_ = std::move( replacement ); child( 1 ) = std::move( replacement );
} }
} }
@ -520,13 +522,10 @@ void T_BinaryOperatorNode::replaceChild(
bool T_FramebufferInstrNode::hasAttachment( bool T_FramebufferInstrNode::hasAttachment(
T_String const& name ) const noexcept T_String const& name ) const noexcept
{ {
if ( depthAttachment_ && depthAttachment_->id( ) == name ) { const auto nc{ size( ) };
return true; for ( auto i = 0u ; i < nc ; i ++ ) {
} auto const& att{ (T_Attachment const&) *child( i ) };
if ( att.id( ) == name ) {
const auto nca( colorAttachments_.size( ) );
for ( auto i = 0u ; i < nca ; i ++ ) {
if ( colorAttachments_[ i ]->id( ) == name ) {
return true; return true;
} }
} }
@ -541,8 +540,9 @@ bool T_FramebufferInstrNode::addColorAttachment(
if ( hasAttachment( id.stringValue( ) ) ) { if ( hasAttachment( id.stringValue( ) ) ) {
return false; return false;
} }
colorAttachments_.add( NewOwned< T_Attachment >( *this , colorAttachments_.add( children_.add(
false , id , std::move( lod ) ) ); NewOwned< T_Attachment >( *this ,
false , id , std::move( lod ) ) ) );
return true; return true;
} }
@ -553,8 +553,8 @@ bool T_FramebufferInstrNode::setDepthAttachment(
if ( depthAttachment_ || hasAttachment( id.stringValue( ) ) ) { if ( depthAttachment_ || hasAttachment( id.stringValue( ) ) ) {
return false; return false;
} }
depthAttachment_ = NewOwned< T_Attachment >( *this , depthAttachment_ = children_.add( NewOwned< T_Attachment >(
true , id , std::move( lod ) ); *this , true , id , std::move( lod ) ) );
return true; return true;
} }
@ -657,31 +657,66 @@ void T_CondInstrNode::T_Expression::replaceChild(
A_Node const& child , A_Node const& child ,
T_OwnPtr< A_Node > replacement ) noexcept T_OwnPtr< A_Node > replacement ) noexcept
{ {
assert( expression_.get( ) == &child ); assert( this->child( 0 ).get( ) == &child );
expression_ = std::move( replacement ); this->child( 0 ) = std::move( replacement );
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void T_CondInstrNode::handleRemoval(
const uint32_t idx ) noexcept
{
children_.removeSwap( idx );
if ( idx >= children_.size( ) ) {
return;
}
if ( defaultCase_ && idx == *defaultCase_ ) {
defaultCase_ = idx;
} else if ( expression_ && idx == *expression_ ) {
expression_ = idx;
} else {
auto& vc{ (T_ValuedCase&) *child( idx ) };
cases_.update( vc.value( ) , idx );
}
}
void T_CondInstrNode::setExpression( void T_CondInstrNode::setExpression(
P_ExpressionNode expression ) noexcept P_ExpressionNode expression ) noexcept
{ {
if ( !expression ) { if ( !expression ) {
expression_.clear( ); if ( !expression_ ) {
return; return;
} }
expression_ = NewOwned< T_Expression >( const auto idx{ *expression_ };
expression_.clear( );
handleRemoval( idx );
} else if ( expression_ ) {
child( *expression_ ) = NewOwned< T_Expression >(
*this , std::move( expression ) ); *this , std::move( expression ) );
} else {
expression_ = children_.size( );
children_.add( NewOwned< T_Expression >(
*this , std::move( expression ) ) );
}
} }
void T_CondInstrNode::setCase( void T_CondInstrNode::setCase(
const int64_t value , const int64_t value ,
P_InstrListNode instrList ) noexcept P_InstrListNode instrList ) noexcept
{ {
cases_.remove( value ); auto const* const pp{ cases_.get( value ) };
if ( instrList ) { if ( instrList && pp ) {
cases_.add( NewOwned< T_ValuedCase >( *this , value , child( *pp ) = NewOwned< T_ValuedCase >( *this , value ,
std::move( instrList ) );
} else if ( instrList ) {
cases_.add( value , children_.size( ) );
children_.add( NewOwned< T_ValuedCase >( *this , value ,
std::move( instrList ) ) ); std::move( instrList ) ) );
} else if ( pp ) {
const auto idx{ *pp };
cases_.remove( value );
handleRemoval( idx );
} }
} }
@ -689,9 +724,19 @@ void T_CondInstrNode::setDefaultCase(
P_InstrListNode defaultCase ) noexcept P_InstrListNode defaultCase ) noexcept
{ {
if ( !defaultCase ) { if ( !defaultCase ) {
defaultCase_.clear( ); if ( !defaultCase_ ) {
return; return;
} }
defaultCase_ = NewOwned< T_DefaultCase >( *this , const auto idx{ *defaultCase_ };
std::move( defaultCase ) ); defaultCase_.clear( );
handleRemoval( idx );
} else if ( defaultCase_ ) {
child( *defaultCase_ ) = NewOwned< T_DefaultCase >(
*this , std::move( defaultCase ) );
} else {
defaultCase_ = children_.size( );
children_.add( NewOwned< T_DefaultCase >(
*this , std::move( defaultCase ) ) );
}
} }

View file

@ -76,6 +76,8 @@ class A_Node
ebcl::T_SRDLocation location_; ebcl::T_SRDLocation location_;
protected: protected:
T_AutoArray< T_OwnPtr< A_Node > , 8 > children_;
explicit A_Node( const E_Type type , explicit A_Node( const E_Type type ,
A_Node* const parent ) noexcept; A_Node* const parent ) noexcept;
@ -95,6 +97,16 @@ class A_Node
T_RootNode& root( ) const noexcept; T_RootNode& root( ) const noexcept;
uint32_t size( ) const noexcept
{ return children_.size( ); }
T_OwnPtr< A_Node > const& child(
const uint32_t index ) const noexcept
{ return children_[ index ]; }
T_OwnPtr< A_Node >& child(
const uint32_t index ) noexcept
{ return children_[ index ]; }
virtual void replaceChild( virtual void replaceChild(
A_Node const& child , A_Node const& child ,
T_OwnPtr< A_Node > replacement ) noexcept; T_OwnPtr< A_Node > replacement ) noexcept;
@ -156,9 +168,6 @@ class A_InstructionNode : public A_Node
// Nodes that store lists of instructions // Nodes that store lists of instructions
class T_InstrListNode : public A_Node class T_InstrListNode : public A_Node
{ {
private:
T_Array< T_OwnPtr< A_InstructionNode > > instructions_;
public: public:
T_InstrListNode( A_Node& parent ) noexcept T_InstrListNode( A_Node& parent ) noexcept
: A_Node( ILIST , &parent ) { } : A_Node( ILIST , &parent ) { }
@ -168,10 +177,8 @@ class T_InstrListNode : public A_Node
typename... ArgTypes typename... ArgTypes
> IType& add( ArgTypes&&... args ); > IType& add( ArgTypes&&... args );
uint32_t size( ) const noexcept
{ return instructions_.size( ); }
A_InstructionNode& node( const uint32_t index ) const noexcept A_InstructionNode& node( const uint32_t index ) const noexcept
{ return *instructions_[ index ]; } { return dynamic_cast< A_InstructionNode& >( *children_[ index ] ); }
}; };
template< template<
@ -180,9 +187,9 @@ template<
> inline IType& T_InstrListNode::add( > inline IType& T_InstrListNode::add(
ArgTypes&&... args ) ArgTypes&&... args )
{ {
instructions_.add( NewOwned< IType >( *this , children_.add( NewOwned< IType >( *this ,
std::forward< ArgTypes >( args ) ... ) ); std::forward< ArgTypes >( args ) ... ) );
return (IType&) *instructions_.last( ); return (IType&) *children_.last( );
} }
/*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/
@ -201,27 +208,24 @@ using P_ExpressionNode = T_OwnPtr< A_ExpressionNode >;
// Technical node used for the arguments of various instructions // Technical node used for the arguments of various instructions
class T_ArgumentNode : public A_Node class T_ArgumentNode : public A_Node
{ {
private:
P_ExpressionNode expr_;
public: public:
T_ArgumentNode( A_Node& parent , T_ArgumentNode( A_Node& parent ,
P_ExpressionNode expr ) noexcept P_ExpressionNode expr ) noexcept
: A_Node( TN_ARG , &parent ) , : A_Node( TN_ARG , &parent )
expr_( std::move( expr ) )
{ {
if ( expr_ ) { if ( expr ) {
location( ) = expr_->location( ); location( ) = expr->location( );
children_.add( std::move( expr ) );
} }
} }
A_ExpressionNode& expression( ) const noexcept A_ExpressionNode& expression( ) const noexcept
{ return *expr_; } { return (A_ExpressionNode&) *child( 0 ); }
bool isIdentifier( ) const noexcept bool isIdentifier( ) const noexcept
{ return expr_->type( ) == EXPR_ID; } { return expression( ).type( ) == EXPR_ID; }
void expression( P_ExpressionNode expr ) noexcept void expression( P_ExpressionNode expr ) noexcept
{ assert( expr ); expr_ = std::move( expr ); } { assert( expr ); child( 0 ) = std::move( expr ); }
}; };
using P_ArgumentNode = T_OwnPtr< T_ArgumentNode >; using P_ArgumentNode = T_OwnPtr< T_ArgumentNode >;
@ -233,7 +237,7 @@ class A_FuncNode : public A_Node
{ {
private: private:
T_String name_; T_String name_;
T_InstrListNode instructions_; T_InstrListNode* instructions_{ nullptr };
protected: protected:
struct T_Local_ struct T_Local_
@ -272,9 +276,14 @@ class A_FuncNode : public A_Node
{ return name_; } { return name_; }
T_InstrListNode& instructions( ) noexcept T_InstrListNode& instructions( ) noexcept
{ return instructions_; } {
T_InstrListNode const& instructions( ) const noexcept if ( !instructions_ ) {
{ return instructions_; } auto p{ NewOwned< T_InstrListNode >( *this ) };
instructions_ = p.get( );
children_.add( std::move( p ) );
}
return *instructions_;
}
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -322,7 +331,7 @@ using P_InstrListNode = T_OwnPtr< T_InstrListNode >;
class T_RootNode : public A_Node class T_RootNode : public A_Node
{ {
private: private:
T_ObjectTable< T_String , T_OwnPtr< A_FuncNode > > functions_; T_KeyValueTable< T_String , uint32_t > functions_;
public: public:
T_RootNode( ) noexcept; T_RootNode( ) noexcept;
@ -366,13 +375,29 @@ class T_RootNode : public A_Node
uint32_t nFunctions( ) const noexcept uint32_t nFunctions( ) const noexcept
{ return functions_.size( ); } { return functions_.size( ); }
int32_t functionIndex( T_String const& name ) const noexcept int32_t functionIndex( T_String const& name ) const noexcept
{ return functions_.indexOf( name ); } {
auto const* const ip{ functions_.get( name ) };
return ip ? *ip : -1;
}
A_FuncNode& function( const uint32_t index ) const noexcept A_FuncNode& function( const uint32_t index ) const noexcept
{ return *functions_.values( )[ index ]; } { return dynamic_cast< A_FuncNode& >( *child( index ) ); }
void removeFunction( T_String const& name ) noexcept void removeFunction( T_String const& name ) noexcept
{ functions_.remove( name ); } {
auto const* const ip{ functions_.get( name ) };
if ( !ip ) {
return;
}
const auto i{ *ip };
functions_.remove( name );
children_.removeSwap( i );
if ( i < children_.size( ) ) {
functions_.update( function( i ).name( ) , i );
}
}
}; };
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -414,7 +439,6 @@ class T_CallInstrNode : public A_InstructionNode
private: private:
T_String id_; T_String id_;
ebcl::T_SRDLocation idLocation_; ebcl::T_SRDLocation idLocation_;
T_AutoArray< P_ArgumentNode , 8 > arguments_;
public: public:
T_CallInstrNode( T_InstrListNode& parent , T_CallInstrNode( T_InstrListNode& parent ,
@ -427,7 +451,7 @@ class T_CallInstrNode : public A_InstructionNode
void addArgument( P_ExpressionNode expr ) noexcept void addArgument( P_ExpressionNode expr ) noexcept
{ {
if ( expr ) { if ( expr ) {
arguments_.add( NewOwned< T_ArgumentNode >( children_.add( NewOwned< T_ArgumentNode >(
*this , std::move( expr ) ) ); *this , std::move( expr ) ) );
} }
} }
@ -437,10 +461,8 @@ class T_CallInstrNode : public A_InstructionNode
ebcl::T_SRDLocation const& idLocation( ) const noexcept ebcl::T_SRDLocation const& idLocation( ) const noexcept
{ return idLocation_; } { return idLocation_; }
uint32_t arguments( ) const noexcept
{ return arguments_.size( ); }
T_ArgumentNode& argument( const uint32_t index ) const noexcept T_ArgumentNode& argument( const uint32_t index ) const noexcept
{ return *arguments_[ index ]; } { return (T_ArgumentNode&) *child( index ); }
}; };
// Conditional instruction // Conditional instruction
@ -449,21 +471,19 @@ class T_CondInstrNode : public A_InstructionNode
public: public:
class T_Expression : public A_Node class T_Expression : public A_Node
{ {
private:
P_ExpressionNode expression_;
public: public:
T_Expression( T_CondInstrNode& parent , T_Expression( T_CondInstrNode& parent ,
P_ExpressionNode expr ) P_ExpressionNode expr )
: A_Node( TN_CONDITION , &parent ) , : A_Node( TN_CONDITION , &parent )
expression_( std::move( expr ) ) {
{ } children_.add( std::move( expr ) );
}
A_ExpressionNode& expression( ) const noexcept A_ExpressionNode& expression( ) const noexcept
{ return *expression_; } { return (A_ExpressionNode&) *child( 0 ); }
void expression( P_ExpressionNode expr ) noexcept void expression( P_ExpressionNode expr ) noexcept
{ assert( expr ); expression_ = std::move( expr ); } { assert( expr ); child( 0 ) = std::move( expr ); }
void replaceChild( void replaceChild(
A_Node const& child , A_Node const& child ,
@ -474,47 +494,43 @@ class T_CondInstrNode : public A_InstructionNode
{ {
private: private:
int64_t value_; int64_t value_;
P_InstrListNode instructions_;
public: public:
T_ValuedCase( T_CondInstrNode& parent , T_ValuedCase( T_CondInstrNode& parent ,
const int64_t value , const int64_t value ,
P_InstrListNode il ) P_InstrListNode il )
: A_Node( TN_CASE , &parent ) , : A_Node( TN_CASE , &parent ) ,
value_( value ) , value_( value )
instructions_( std::move( il ) ) {
{ } children_.add( std::move( il ) );
}
int64_t value( ) const noexcept int64_t value( ) const noexcept
{ return value_; } { return value_; }
T_InstrListNode& instructions( ) const noexcept T_InstrListNode& instructions( ) const noexcept
{ return *instructions_; } { return (T_InstrListNode&) *child( 0 ); }
}; };
class T_DefaultCase : public A_Node class T_DefaultCase : public A_Node
{ {
private:
P_InstrListNode instructions_;
public: public:
T_DefaultCase( T_CondInstrNode& parent , T_DefaultCase( T_CondInstrNode& parent ,
P_InstrListNode il ) P_InstrListNode il )
: A_Node( TN_DEFAULT , &parent ) , : A_Node( TN_DEFAULT , &parent )
instructions_( std::move( il ) ) {
{ } children_.add( std::move( il ) );
}
T_InstrListNode& instructions( ) const noexcept T_InstrListNode& instructions( ) const noexcept
{ return *instructions_; } { return (T_InstrListNode&) *child( 0 ); }
}; };
private: private:
T_OwnPtr< T_Expression > expression_; T_Optional< uint32_t > expression_;
T_ObjectTable< int64_t , T_OwnPtr< T_ValuedCase > > cases_{ T_KeyValueTable< int64_t , uint32_t > cases_;
[]( T_OwnPtr< T_ValuedCase > const& c ) -> int64_t { T_Optional< uint32_t > defaultCase_;
return c->value( );
} void handleRemoval( uint32_t idx ) noexcept;
};
T_OwnPtr< T_DefaultCase > defaultCase_;
public: public:
explicit T_CondInstrNode( T_InstrListNode& parent ) noexcept explicit T_CondInstrNode( T_InstrListNode& parent ) noexcept
@ -525,7 +541,7 @@ class T_CondInstrNode : public A_InstructionNode
bool hasExpression( ) const noexcept bool hasExpression( ) const noexcept
{ return bool( expression_ ); } { return bool( expression_ ); }
T_Expression& expression( ) const noexcept T_Expression& expression( ) const noexcept
{ return *expression_; } { return (T_Expression&) *child( *expression_ ); }
void setCase( const int64_t value , void setCase( const int64_t value ,
P_InstrListNode instrList ) noexcept; P_InstrListNode instrList ) noexcept;
@ -534,21 +550,21 @@ class T_CondInstrNode : public A_InstructionNode
uint32_t nCases( ) const noexcept uint32_t nCases( ) const noexcept
{ return cases_.size( ); } { return cases_.size( ); }
T_Array< int64_t > cases( ) const noexcept T_Array< int64_t > const& cases( ) const noexcept
{ return cases_.keys( ); } { return cases_.keys( ); }
bool hasCase( const int64_t value ) const noexcept bool hasCase( const int64_t value ) const noexcept
{ return cases_.contains( value ); } { return cases_.contains( value ); }
T_ValuedCase& getCase( const int64_t value ) const noexcept T_ValuedCase& getCase( const int64_t value ) const noexcept
{ return **cases_.get( value ); } { return (T_ValuedCase&) *child( *cases_.get( value ) ); }
T_ValuedCase& getCaseByIndex( T_ValuedCase& getCaseByIndex(
const uint32_t index ) const noexcept const uint32_t index ) const noexcept
{ return *cases_[ index ]; } { return (T_ValuedCase&) *child( cases_[ index ] ); }
void setDefaultCase( P_InstrListNode defaultCase ) noexcept; void setDefaultCase( P_InstrListNode defaultCase ) noexcept;
bool hasDefaultCase( ) const noexcept bool hasDefaultCase( ) const noexcept
{ return bool( defaultCase_ ); } { return bool( defaultCase_ ); }
T_DefaultCase& defaultCase( ) const noexcept T_DefaultCase& defaultCase( ) const noexcept
{ return *defaultCase_; } { return (T_DefaultCase&) *child( *defaultCase_ ); }
}; };
// Local variable declarations // Local variable declarations
@ -584,7 +600,6 @@ class T_SetInstrNode : public A_InstructionNode
private: private:
T_String id_; T_String id_;
ebcl::T_SRDLocation idLocation_; ebcl::T_SRDLocation idLocation_;
P_ExpressionNode expression_;
public: public:
T_SetInstrNode( T_InstrListNode& parent , T_SetInstrNode( T_InstrListNode& parent ,
@ -600,11 +615,18 @@ class T_SetInstrNode : public A_InstructionNode
{ return idLocation_; } { return idLocation_; }
void setExpression( P_ExpressionNode expression ) noexcept void setExpression( P_ExpressionNode expression ) noexcept
{ expression_ = std::move( expression ); } {
if ( children_.size( ) ) {
child( 0 ) = std::move( expression );
} else {
children_.add( std::move( expression ) );
}
}
bool hasExpression( ) const noexcept bool hasExpression( ) const noexcept
{ return bool( expression_ ); } { return children_.size( ) && child( 0 ); }
A_ExpressionNode& expression( ) const noexcept A_ExpressionNode& expression( ) const noexcept
{ return *expression_; } { return (A_ExpressionNode&) *child( 0 ); }
}; };
@ -651,7 +673,6 @@ class T_FramebufferInstrNode : public A_ResourceDefInstrNode
private: private:
bool depth_; bool depth_;
T_String id_; T_String id_;
P_ArgumentNode lod_;
public: public:
T_Attachment( T_FramebufferInstrNode& parent , T_Attachment( T_FramebufferInstrNode& parent ,
@ -664,8 +685,8 @@ class T_FramebufferInstrNode : public A_ResourceDefInstrNode
{ {
location() = texId.location( ); location() = texId.location( );
if ( lod ) { if ( lod ) {
lod_ = NewOwned< T_ArgumentNode >( *this , children_.add( NewOwned< T_ArgumentNode >(
std::move( lod ) ); *this , std::move( lod ) ) );
} }
} }
@ -676,12 +697,13 @@ class T_FramebufferInstrNode : public A_ResourceDefInstrNode
{ return id_; } { return id_; }
T_ArgumentNode* lod( ) const noexcept T_ArgumentNode* lod( ) const noexcept
{ return lod_.get( ); } { return (T_ArgumentNode*) ( children_.size( )
? child( 0 ).get( ) : nullptr ); }
}; };
private: private:
T_AutoArray< T_OwnPtr< T_Attachment > , 16 > colorAttachments_; T_AutoArray< uint32_t , 16 > colorAttachments_;
T_OwnPtr< T_Attachment > depthAttachment_; T_Optional< uint32_t > depthAttachment_;
bool hasAttachment( T_String const& name ) const noexcept; bool hasAttachment( T_String const& name ) const noexcept;
@ -702,7 +724,7 @@ class T_FramebufferInstrNode : public A_ResourceDefInstrNode
T_Attachment& colorAttachment( T_Attachment& colorAttachment(
const uint32_t index ) const noexcept const uint32_t index ) const noexcept
{ return *colorAttachments_[ index ]; } { return (T_Attachment&) *child( colorAttachments_[ index ] ); }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -710,7 +732,9 @@ class T_FramebufferInstrNode : public A_ResourceDefInstrNode
P_ExpressionNode lod = {} ) noexcept; P_ExpressionNode lod = {} ) noexcept;
T_Attachment* depthAttachment( ) const noexcept T_Attachment* depthAttachment( ) const noexcept
{ return depthAttachment_.get( ); } { return depthAttachment_
? ((T_Attachment*) child( *depthAttachment_ ).get( ) )
: nullptr; }
}; };
// Input declaration // Input declaration
@ -875,9 +899,9 @@ class T_TextureInstrNode : public A_ResourceDefInstrNode
{ {
private: private:
E_TexType type_; E_TexType type_;
P_ArgumentNode width_; T_Optional< uint32_t > width_;
P_ArgumentNode height_; T_Optional< uint32_t > height_;
P_ArgumentNode lods_; T_Optional< uint32_t > lods_;
public: public:
T_TextureInstrNode( T_TextureInstrNode(
@ -895,39 +919,45 @@ class T_TextureInstrNode : public A_ResourceDefInstrNode
void setWidth( P_ExpressionNode width ) noexcept void setWidth( P_ExpressionNode width ) noexcept
{ {
if ( width ) { if ( width ) {
width_ = NewOwned< T_ArgumentNode >( auto a{ NewOwned< T_ArgumentNode >(
*this , std::move( width ) ); *this , std::move( width ) )
};
width_ = children_.add( std::move( a ) );
} }
} }
void setHeight( P_ExpressionNode height ) noexcept void setHeight( P_ExpressionNode height ) noexcept
{ {
if ( height ) { if ( height ) {
height_ = NewOwned< T_ArgumentNode >( auto a{ NewOwned< T_ArgumentNode >(
*this , std::move( height ) ); *this , std::move( height ) )
};
height_ = children_.add( std::move( a ) );
} }
} }
void setLODs( P_ExpressionNode lods ) noexcept void setLODs( P_ExpressionNode lods ) noexcept
{ {
if ( lods ) { if ( lods ) {
lods_ = NewOwned< T_ArgumentNode >( auto a{ NewOwned< T_ArgumentNode >(
*this , std::move( lods ) ); *this , std::move( lods ) )
};
lods_ = children_.add( std::move( a ) );
} }
} }
bool hasWidth( ) const noexcept bool hasWidth( ) const noexcept
{ return bool( width_ ); } { return bool( width_ ); }
T_ArgumentNode& width( ) const noexcept T_ArgumentNode& width( ) const noexcept
{ return *width_; } { return (T_ArgumentNode&) *child( *width_ ); }
bool hasHeight( ) const noexcept bool hasHeight( ) const noexcept
{ return bool( height_ ); } { return bool( height_ ); }
T_ArgumentNode& height( ) const noexcept T_ArgumentNode& height( ) const noexcept
{ return *height_; } { return (T_ArgumentNode&) *child( *height_ ); }
T_ArgumentNode* lods( ) const noexcept T_ArgumentNode* lods( ) const noexcept
{ return lods_.get( ); } { return lods_ ? (T_ArgumentNode*) child( *lods_ ).get( ) : nullptr; }
}; };
@ -994,24 +1024,22 @@ class T_ProfileInstrNode : public A_InstructionNode
{ {
private: private:
T_String text_; T_String text_;
T_InstrListNode instructions_;
public: public:
T_ProfileInstrNode( T_ProfileInstrNode(
T_InstrListNode& parent , T_InstrListNode& parent ,
T_String const& text ) noexcept T_String const& text ) noexcept
: A_InstructionNode( OP_PROFILE , parent , E_InstrRestriction::INIT ) , : A_InstructionNode( OP_PROFILE , parent , E_InstrRestriction::INIT ) ,
text_( text ) , text_( text )
instructions_( *this ) {
{ } children_.add( NewOwned< T_InstrListNode >( *this ) );
}
T_String const& text( ) const T_String const& text( ) const
{ return text_; } { return text_; }
T_InstrListNode& instructions( ) noexcept T_InstrListNode& instructions( ) const noexcept
{ return instructions_; } { return (T_InstrListNode&) *child( 0 ); }
T_InstrListNode const& instructions( ) const noexcept
{ return instructions_; }
}; };
@ -1020,9 +1048,6 @@ class T_ProfileInstrNode : public A_InstructionNode
// Clear instruction // Clear instruction
class T_ClearInstrNode : public A_InstructionNode class T_ClearInstrNode : public A_InstructionNode
{ {
private:
T_StaticArray< P_ArgumentNode , 4 > components_;
public: public:
T_ClearInstrNode( T_InstrListNode& parent ) noexcept T_ClearInstrNode( T_InstrListNode& parent ) noexcept
: A_InstructionNode( OP_CLEAR , parent , : A_InstructionNode( OP_CLEAR , parent ,
@ -1032,15 +1057,13 @@ class T_ClearInstrNode : public A_InstructionNode
void addComponent( P_ExpressionNode expr ) noexcept void addComponent( P_ExpressionNode expr ) noexcept
{ {
if ( expr ) { if ( expr ) {
components_.add( NewOwned< T_ArgumentNode >( children_.add( NewOwned< T_ArgumentNode >(
*this , std::move( expr ) ) ); *this , std::move( expr ) ) );
} }
} }
uint32_t components( ) const noexcept
{ return components_.size( ); }
T_ArgumentNode& component( const uint32_t index ) const noexcept T_ArgumentNode& component( const uint32_t index ) const noexcept
{ return *components_[ index ]; } { return (T_ArgumentNode&) *child( index ); }
}; };
// Fullscreen quad instruction // Fullscreen quad instruction
@ -1070,16 +1093,15 @@ class T_UniformsInstrNode : public A_InstructionNode
ebcl::T_SRDLocation progIdLocation_; ebcl::T_SRDLocation progIdLocation_;
uint32_t uloc_; uint32_t uloc_;
ebcl::T_SRDLocation ulocLocation_; ebcl::T_SRDLocation ulocLocation_;
T_StaticArray< P_ArgumentNode , 4 > values_;
public: public:
T_UniformsInstrNode( T_InstrListNode& parent , T_UniformsInstrNode( T_InstrListNode& parent ,
const bool integers , const bool integers ,
ebcl::T_SRDToken const& prog , ebcl::T_SRDToken const& prog ,
ebcl::T_SRDToken const& loc ) noexcept ebcl::T_SRDToken const& loc ) noexcept
: A_InstructionNode( OP_UNIFORMS , parent ) , integers_( integers ) , : A_InstructionNode{ OP_UNIFORMS , parent } , integers_{ integers } ,
progId_( prog.stringValue( ) ) , progIdLocation_( prog.location( ) ) , progId_{ prog.stringValue( ) } , progIdLocation_{ prog.location( ) } ,
uloc_( loc.longValue( ) ) , ulocLocation_( loc.location( ) ) uloc_{ (uint32_t)loc.longValue( ) } , ulocLocation_{ loc.location( ) }
{ } { }
bool integers( ) const noexcept bool integers( ) const noexcept
@ -1098,15 +1120,13 @@ class T_UniformsInstrNode : public A_InstructionNode
void addValue( P_ExpressionNode value ) noexcept void addValue( P_ExpressionNode value ) noexcept
{ {
if ( value ) { if ( value ) {
values_.add( NewOwned< T_ArgumentNode >( children_.add( NewOwned< T_ArgumentNode >(
*this , std::move( value ) ) ); *this , std::move( value ) ) );
} }
} }
uint32_t values( ) const noexcept
{ return values_.size( ); }
T_ArgumentNode& value( const uint32_t index ) const noexcept T_ArgumentNode& value( const uint32_t index ) const noexcept
{ return *values_[ index ]; } { return (T_ArgumentNode&) *child( index ); }
}; };
// Use-* instructions (framebuffers, programs, pipelines) // Use-* instructions (framebuffers, programs, pipelines)
@ -1185,27 +1205,29 @@ class T_ViewportInstrNode : public A_InstructionNode
PX , PY , PWIDTH , PHEIGHT PX , PY , PWIDTH , PHEIGHT
}; };
private:
P_ArgumentNode parameters_[ 4 ];
public: public:
T_ViewportInstrNode( T_InstrListNode& parent ) noexcept T_ViewportInstrNode( T_InstrListNode& parent ) noexcept
: A_InstructionNode( OP_VIEWPORT , parent , : A_InstructionNode( OP_VIEWPORT , parent ,
E_InstrRestriction::INIT ) E_InstrRestriction::INIT )
{ } {
children_.add( P_ArgumentNode{} );
children_.add( P_ArgumentNode{} );
children_.add( P_ArgumentNode{} );
children_.add( P_ArgumentNode{} );
}
void setParameter( const E_Parameter p , P_ExpressionNode value ) noexcept void setParameter( const E_Parameter p , P_ExpressionNode value ) noexcept
{ {
if ( value ) { if ( value ) {
parameters_[ int( p ) ] = NewOwned< T_ArgumentNode >( children_[ int( p ) ] = NewOwned< T_ArgumentNode >(
*this , std::move( value ) ); *this , std::move( value ) );
} }
} }
bool hasParameter( const E_Parameter p ) const noexcept bool hasParameter( const E_Parameter p ) const noexcept
{ return bool( parameters_[ int( p ) ] ); } { return bool( children_[ int( p ) ] ); }
T_ArgumentNode& parameter( const E_Parameter p ) const noexcept T_ArgumentNode& parameter( const E_Parameter p ) const noexcept
{ return *parameters_[ int( p ) ]; } { return (T_ArgumentNode&) *children_[ int( p ) ]; }
}; };
@ -1302,7 +1324,6 @@ class T_UnaryOperatorNode : public A_ExpressionNode
private: private:
E_Operator op_; E_Operator op_;
P_ExpressionNode argument_;
public: public:
T_UnaryOperatorNode( T_UnaryOperatorNode(
@ -1313,15 +1334,13 @@ class T_UnaryOperatorNode : public A_ExpressionNode
{ return op_; } { return op_; }
void setArgument( P_ExpressionNode argument ) noexcept void setArgument( P_ExpressionNode argument ) noexcept
{ argument_ = std::move( argument ); } { child( 0 ) = std::move( argument ); }
bool hasArgument( ) const noexcept bool hasArgument( ) const noexcept
{ return bool( argument_ ); } { return bool( child( 0 ) ); }
A_ExpressionNode const& argument( ) const noexcept A_ExpressionNode& argument( ) const noexcept
{ return *argument_; } { return (A_ExpressionNode&) *child( 0 ); }
A_ExpressionNode& argument( ) noexcept
{ return *argument_; }
}; };
// A binary operator // A binary operator
@ -1340,8 +1359,6 @@ class T_BinaryOperatorNode : public A_ExpressionNode
private: private:
E_Operator op_; E_Operator op_;
P_ExpressionNode left_;
P_ExpressionNode right_;
public: public:
T_BinaryOperatorNode( T_BinaryOperatorNode(
@ -1352,24 +1369,19 @@ class T_BinaryOperatorNode : public A_ExpressionNode
{ return op_; } { return op_; }
void setLeft( P_ExpressionNode left ) noexcept void setLeft( P_ExpressionNode left ) noexcept
{ left_ = std::move( left ); } { child( 0 ) = std::move( left ); }
void setRight( P_ExpressionNode right ) noexcept void setRight( P_ExpressionNode right ) noexcept
{ right_ = std::move( right ); } { child( 1 ) = std::move( right ); }
bool hasLeft( ) const noexcept bool hasLeft( ) const noexcept
{ return bool( left_ ); } { return bool( child( 0 ) ); }
bool hasRight( ) const noexcept bool hasRight( ) const noexcept
{ return bool( right_ ); } { return bool( child( 1 ) ); }
A_ExpressionNode const& left( ) const noexcept A_ExpressionNode& left( ) const noexcept
{ return *left_; } { return (A_ExpressionNode&) *child( 0 ); }
A_ExpressionNode& left( ) noexcept A_ExpressionNode& right( ) const noexcept
{ return *left_; } { return (A_ExpressionNode&) *child( 1 ); }
A_ExpressionNode const& right( ) const noexcept
{ return *right_; }
A_ExpressionNode& right( ) noexcept
{ return *right_; }
void replaceChild( void replaceChild(
A_Node const& child , A_Node const& child ,

View file

@ -623,9 +623,9 @@ bool T_CompilerImpl_::compileNode(
addInstruction( OP_CONST , un.uloc( ) , un.ulocLocation( ) ); addInstruction( OP_CONST , un.uloc( ) , un.ulocLocation( ) );
addInstruction( OP_PUSH , un.ulocLocation( ) ); addInstruction( OP_PUSH , un.ulocLocation( ) );
processIdentifier( funcIndex , un.progId( ) , un.progIdLocation( ) ); processIdentifier( funcIndex , un.progId( ) , un.progIdLocation( ) );
addInstruction( OP_UNIFORMS , { un.values( ) - 1 , un.integers( ) ? 1u : 0u } , addInstruction( OP_UNIFORMS , { un.size( ) - 1 , un.integers( ) ? 1u : 0u } ,
un.location( ) ); un.location( ) );
sdMain -= un.values( ); sdMain -= un.size( );
} }
break; break;

View file

@ -382,12 +382,12 @@ bool T_ParserImpl_::checkCalls( ) noexcept
// Check argument count while we're at it // Check argument count while we're at it
auto& fn( (T_FuncNode&) output->root.function( callee ) ); auto& fn( (T_FuncNode&) output->root.function( callee ) );
if ( fn.arguments( ) != call.arguments( ) ) { if ( fn.arguments( ) != call.size( ) ) {
T_StringBuilder sb; T_StringBuilder sb;
sb << "function expects " << fn.arguments( ) sb << "function expects " << fn.arguments( )
<< " argument" << ( fn.arguments( ) == 1 ? "" : "s" ) << " argument" << ( fn.arguments( ) == 1 ? "" : "s" )
<< ", " << call.arguments( ) << ", " << call.size( )
<< " argument" << ( call.arguments( ) == 1 ? "" : "s" ) << " argument" << ( call.size( ) == 1 ? "" : "s" )
<< " provided"; << " provided";
errors.addNew( std::move( sb ) , call.location( ) ); errors.addNew( std::move( sb ) , call.location( ) );
} }
@ -633,7 +633,7 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
} }
auto& call( dynamic_cast< T_CallInstrNode& >( node ) ); auto& call( dynamic_cast< T_CallInstrNode& >( node ) );
if ( call.arguments( ) != 0 ) { if ( call.size( ) != 0 ) {
callInstuctions.add( &call ); callInstuctions.add( &call );
} }
return false; return false;
@ -675,7 +675,7 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
output->root.function( calledIdx ) ) ); output->root.function( calledIdx ) ) );
M_TRACE_( 4 , " -> checking call to " << called << " (idx " << calledIdx M_TRACE_( 4 , " -> checking call to " << called << " (idx " << calledIdx
<< ") at " << call->location( ) ); << ") at " << call->location( ) );
assert( call->arguments( ) == calledFn.arguments( ) ); assert( call->size( ) == calledFn.arguments( ) );
if ( argsResolved[ calledIdx ] ) { if ( argsResolved[ calledIdx ] ) {
M_TRACE_( 4 , " argument types already resolved, checking" ); M_TRACE_( 4 , " argument types already resolved, checking" );
} else { } else {
@ -683,7 +683,7 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
} }
bool ok = true; bool ok = true;
for ( auto a = 0u ; a < call->arguments( ) ; a ++ ) { for ( auto a = 0u ; a < call->size( ) ; a ++ ) {
auto& arg( call->argument( a ).expression( ) ); auto& arg( call->argument( a ).expression( ) );
E_DataType ndt{ E_DataType::UNKNOWN }; E_DataType ndt{ E_DataType::UNKNOWN };
if ( arg.type( ) == A_Node::EXPR_ID ) { if ( arg.type( ) == A_Node::EXPR_ID ) {