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

View file

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

View file

@ -623,9 +623,9 @@ bool T_CompilerImpl_::compileNode(
addInstruction( OP_CONST , un.uloc( ) , un.ulocLocation( ) );
addInstruction( OP_PUSH , un.ulocLocation( ) );
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( ) );
sdMain -= un.values( );
sdMain -= un.size( );
}
break;

View file

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