Parser - Refactored AST nodes
AST nodes use the same storage structure, whatever their nature.
This commit is contained in:
parent
efa1b26150
commit
5f6eee238f
4 changed files with 247 additions and 190 deletions
131
c-opast.cc
131
c-opast.cc
|
@ -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 ) );
|
||||
}
|
||||
|
|
290
c-opast.hh
290
c-opast.hh
|
@ -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 ,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
Loading…
Reference in a new issue