Progress on parser
This commit is contained in:
parent
5cb5229e43
commit
ab999d222b
3 changed files with 448 additions and 19 deletions
2
demo.srd
2
demo.srd
|
@ -31,8 +31,8 @@
|
||||||
(fn dof-init ()
|
(fn dof-init ()
|
||||||
# Sampler used for the inputs
|
# Sampler used for the inputs
|
||||||
(sampler dof-sampler
|
(sampler dof-sampler
|
||||||
(sampling clamp-edge)
|
|
||||||
(mipmaps no)
|
(mipmaps no)
|
||||||
|
(wrapping clamp-edge)
|
||||||
(sampling linear)
|
(sampling linear)
|
||||||
(lod 0 0)
|
(lod 0 0)
|
||||||
)
|
)
|
||||||
|
|
312
opast.cc
312
opast.cc
|
@ -27,19 +27,30 @@ T_RootNode& A_Node::root( ) const noexcept
|
||||||
const_cast< A_Node* >( node ) );
|
const_cast< A_Node* >( node ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= T_InstrListNode ==========================================================*/
|
||||||
|
|
||||||
|
T_InstrListNode::T_InstrListNode(
|
||||||
|
A_Node& parent ) noexcept
|
||||||
|
: A_Node( ILIST , &parent )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
/*= A_FuncNode ===============================================================*/
|
/*= A_FuncNode ===============================================================*/
|
||||||
|
|
||||||
A_FuncNode::A_FuncNode(
|
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 )
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,19 +123,119 @@ T_Optional< T_SRDLocation > T_FuncNode::addArgument(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= T_PipelineInstrNode ======================================================*/
|
||||||
|
|
||||||
|
T_PipelineInstrNode::T_PipelineInstrNode(
|
||||||
|
T_InstrListNode& parent ,
|
||||||
|
T_SRDToken const& idToken ) noexcept
|
||||||
|
: A_InstructionNode( OP_PIPELINE , parent ) ,
|
||||||
|
id_( idToken.stringValue( ) ) ,
|
||||||
|
idLocation_( idToken.location( ) )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
T_PipelineInstrNode::T_PipelineInstrNode(
|
||||||
|
T_InstrListNode& parent ) noexcept
|
||||||
|
: A_InstructionNode( OP_PIPELINE , parent ) ,
|
||||||
|
id_( "*invalid*" ) ,
|
||||||
|
idLocation_{ }
|
||||||
|
{ }
|
||||||
|
|
||||||
|
T_Optional< T_SRDLocation > T_PipelineInstrNode::addProgram(
|
||||||
|
T_SRDToken const& pidToken ) noexcept
|
||||||
|
{
|
||||||
|
T_String const& name( pidToken.stringValue( ) );
|
||||||
|
const auto pIndex( pids_.indexOf( name ) );
|
||||||
|
if ( pIndex != -1 ) {
|
||||||
|
return pidLocations_[ pIndex ];
|
||||||
|
}
|
||||||
|
pids_.add( name );
|
||||||
|
pidLocations_.add( pidToken.location( ) );
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= T_ProfileInstrNode =======================================================*/
|
||||||
|
|
||||||
|
T_ProfileInstrNode::T_ProfileInstrNode(
|
||||||
|
T_InstrListNode& parent ,
|
||||||
|
T_String const& text ) noexcept
|
||||||
|
: A_InstructionNode( OP_PROFILE , parent ) ,
|
||||||
|
text_( text ) ,
|
||||||
|
instructions_( *this )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
/*= T_ProgramInstrNode =======================================================*/
|
||||||
|
|
||||||
|
T_ProgramInstrNode::T_ProgramInstrNode(
|
||||||
|
T_InstrListNode& parent ,
|
||||||
|
T_SRDToken const& idToken ,
|
||||||
|
T_SRDToken const& pathToken ) noexcept
|
||||||
|
: A_InstructionNode( OP_PROGRAM , parent ) ,
|
||||||
|
id_( idToken.stringValue( ) ) ,
|
||||||
|
idLocation_( idToken.location( ) ) ,
|
||||||
|
path_( pathToken.stringValue( ) ) ,
|
||||||
|
pathLocation_( pathToken.location( ) )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
/*= T_Parser =================================================================*/
|
/*= T_Parser =================================================================*/
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct T_ParserImpl_
|
struct T_ParserImpl_
|
||||||
{
|
{
|
||||||
|
enum class E_InstrType {
|
||||||
|
IF ,
|
||||||
|
PIPELINE ,
|
||||||
|
PROFILE ,
|
||||||
|
PROGRAM ,
|
||||||
|
};
|
||||||
|
|
||||||
|
const T_KeyValueTable< T_String , E_InstrType > instrMap{ ([]() {
|
||||||
|
T_KeyValueTable< T_String , E_InstrType > temp;
|
||||||
|
const auto add{ [&temp]( char const* name , E_InstrType it ) {
|
||||||
|
temp.add( T_String::Pooled( name ) , it );
|
||||||
|
} };
|
||||||
|
|
||||||
|
add( "if" , E_InstrType::IF );
|
||||||
|
add( "pipeline" , E_InstrType::PIPELINE );
|
||||||
|
add( "profiling" , E_InstrType::PROFILE );
|
||||||
|
add( "program" , E_InstrType::PROGRAM );
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
})( ) };
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
T_OwnPtr< T_RootNode >& root;
|
T_OwnPtr< T_RootNode >& root;
|
||||||
T_Array< T_SRDError >& errors;
|
T_Array< T_SRDError >& errors;
|
||||||
|
|
||||||
T_ParserImpl_( T_Array< T_SRDError >* errors ,
|
T_ParserImpl_( T_Array< T_SRDError >* errors ,
|
||||||
T_OwnPtr< T_RootNode >* root ) noexcept;
|
T_OwnPtr< T_RootNode >* root ) noexcept;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
void parseFunction( T_SRDList const& funcList ) noexcept;
|
void parseFunction( T_SRDList const& funcList ) noexcept;
|
||||||
|
void parseFunctionArguments(
|
||||||
|
T_FuncNode& function ,
|
||||||
|
T_SRDToken const& argsToken ) noexcept;
|
||||||
|
void parseInstructions(
|
||||||
|
T_InstrListNode& instructions ,
|
||||||
|
T_SRDList const& input ,
|
||||||
|
uint32_t start ) noexcept;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
void parsePipelineInstruction(
|
||||||
|
T_InstrListNode& instructions ,
|
||||||
|
T_SRDList const& input ) noexcept;
|
||||||
|
void parseProfileInstruction(
|
||||||
|
T_InstrListNode& instructions ,
|
||||||
|
T_SRDList const& input ) noexcept;
|
||||||
|
void parseProgramInstruction(
|
||||||
|
T_InstrListNode& instructions ,
|
||||||
|
T_SRDList const& input ) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_ParserImpl_::T_ParserImpl_(
|
T_ParserImpl_::T_ParserImpl_(
|
||||||
|
@ -160,7 +271,8 @@ void T_ParserImpl_::parseFunction(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn = NewOwned< T_FuncNode >( funcList[ 1 ].stringValue( ) , *root );
|
fn = NewOwned< T_FuncNode >( funcList[ 1 ].stringValue( ) , *root );
|
||||||
// TODO parseFunctionArguments( funcList[ 2 ] );
|
parseFunctionArguments( dynamic_cast< T_FuncNode& >( *fn ) ,
|
||||||
|
funcList[ 2 ] );
|
||||||
} else {
|
} else {
|
||||||
fn = NewOwned< T_SpecialFuncNode >( ftw == "init" , *root );
|
fn = NewOwned< T_SpecialFuncNode >( ftw == "init" , *root );
|
||||||
}
|
}
|
||||||
|
@ -185,8 +297,181 @@ void T_ParserImpl_::parseFunction(
|
||||||
errors.addNew( std::move( esb ) , fw.location( ) );
|
errors.addNew( std::move( esb ) , fw.location( ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO parseInstructions( fn->instructions , funcList ,
|
parseInstructions( af.function.instructions( ) , funcList , ftw == "fn" ? 3 : 1 );
|
||||||
// ftw == "fn" ? 3 : 1 );
|
}
|
||||||
|
|
||||||
|
void T_ParserImpl_::parseFunctionArguments(
|
||||||
|
T_FuncNode& function ,
|
||||||
|
T_SRDToken const& argsToken ) noexcept
|
||||||
|
{
|
||||||
|
if ( argsToken.type( ) != E_SRDTokenType::LIST ) {
|
||||||
|
errors.addNew( "arguments list expected" , argsToken.location( ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for ( auto const& token : argsToken.list( ) ) {
|
||||||
|
if ( token.type( ) != E_SRDTokenType::WORD ) {
|
||||||
|
errors.addNew( "argument name expected" , token.location( ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto rv( function.addArgument( token ) );
|
||||||
|
if ( rv.present( ) ) {
|
||||||
|
T_StringBuilder esb;
|
||||||
|
esb << "duplicate argument '" << token.stringValue( )
|
||||||
|
<< "'; previous declaration: " << *rv.target( );
|
||||||
|
errors.addNew( std::move( esb ) , token.location( ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void T_ParserImpl_::parseInstructions(
|
||||||
|
T_InstrListNode& instructions ,
|
||||||
|
T_SRDList const& input ,
|
||||||
|
const uint32_t start ) noexcept
|
||||||
|
{
|
||||||
|
for ( auto iter( input.begin( ) + start ) ; iter.valid( ) ; iter ++ ) {
|
||||||
|
T_SRDToken const& itok( *iter );
|
||||||
|
if ( itok.type( ) != E_SRDTokenType::LIST ) {
|
||||||
|
errors.addNew( "instruction expected" , itok.location( ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
T_SRDList const& ilist( itok.list( ) );
|
||||||
|
if ( ilist.empty( ) ) {
|
||||||
|
errors.addNew( "instruction expected" , itok.location( ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
T_SRDToken const& iname( ilist[ 0 ] );
|
||||||
|
if ( iname.type( ) != E_SRDTokenType::WORD ) {
|
||||||
|
errors.addNew( "instruction name expected" , iname.location( ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
T_String const& iword( iname.stringValue( ) );
|
||||||
|
if ( !instrMap.contains( iword ) ) {
|
||||||
|
errors.addNew( "unknown instruction" , iname.location( ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( *instrMap.get( iword ) ) {
|
||||||
|
case E_InstrType::PIPELINE:
|
||||||
|
parsePipelineInstruction( instructions , ilist );
|
||||||
|
break;
|
||||||
|
case E_InstrType::PROFILE:
|
||||||
|
parseProfileInstruction( instructions , ilist );
|
||||||
|
break;
|
||||||
|
case E_InstrType::PROGRAM:
|
||||||
|
parseProgramInstruction( instructions , ilist );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void T_ParserImpl_::parsePipelineInstruction(
|
||||||
|
T_InstrListNode& instructions ,
|
||||||
|
T_SRDList const& input ) noexcept
|
||||||
|
{
|
||||||
|
if ( input.size( ) < 3 ) {
|
||||||
|
errors.addNew( "identifier and program identifiers expected" ,
|
||||||
|
input[ 0 ].location( ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool validId( input[ 1 ].type( ) == E_SRDTokenType::WORD );
|
||||||
|
if ( !validId ) {
|
||||||
|
errors.addNew( "pipeline identifier expected" , input[ 1 ].location( ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
T_PipelineInstrNode& pipeline{ ([&instructions,&input,validId]( ) -> T_PipelineInstrNode& {
|
||||||
|
if ( validId ) {
|
||||||
|
return instructions.add< T_PipelineInstrNode >( input[ 0 ] );
|
||||||
|
}
|
||||||
|
return instructions.add< T_PipelineInstrNode >( );
|
||||||
|
})() };
|
||||||
|
pipeline.location( ) = input[ 0 ].location( );
|
||||||
|
|
||||||
|
const auto nMax{ std::min( input.size( ) , 8u ) };
|
||||||
|
for ( auto i = 2u ; i < nMax ; i ++ ) {
|
||||||
|
T_SRDToken const& tok( input[ i ] );
|
||||||
|
if ( tok.type( ) != E_SRDTokenType::WORD ) {
|
||||||
|
errors.addNew( "program identifier expected" ,
|
||||||
|
tok.location( ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto dup( pipeline.addProgram( tok ) );
|
||||||
|
if ( dup.present( ) ) {
|
||||||
|
T_StringBuilder esb;
|
||||||
|
esb << "duplicate program identifier; previous use: "
|
||||||
|
<< *dup.target( );
|
||||||
|
errors.addNew( std::move( esb ) , tok.location( ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( input.size( ) > 8 ) {
|
||||||
|
errors.addNew( "too many arguments" , input[ 8 ].location( ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void T_ParserImpl_::parseProfileInstruction(
|
||||||
|
T_InstrListNode& instructions ,
|
||||||
|
T_SRDList const& input ) noexcept
|
||||||
|
{
|
||||||
|
const bool hasEnough( input.size( ) < 2 );
|
||||||
|
if ( hasEnough || !input[ 1 ].isText( ) ) {
|
||||||
|
errors.addNew( "profiling section name expected" ,
|
||||||
|
hasEnough ? input[ 1 ].location( ) : T_SRDLocation{} );
|
||||||
|
if ( !hasEnough ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const T_String text( input[ 1 ].isText( ) ? input[ 1 ].stringValue( ) : "*invalid*" );
|
||||||
|
T_ProfileInstrNode& profile{ instructions.add< T_ProfileInstrNode >( text ) };
|
||||||
|
profile.location( ) = input[ 0 ].location( );
|
||||||
|
parseInstructions( profile.instructions( ) , input , 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void T_ParserImpl_::parseProgramInstruction(
|
||||||
|
T_InstrListNode& instructions ,
|
||||||
|
T_SRDList const& input ) noexcept
|
||||||
|
{
|
||||||
|
bool ok{ true };
|
||||||
|
if ( input.size( ) == 1 ) {
|
||||||
|
errors.addNew( "identifier and program name required" ,
|
||||||
|
input[ 0 ].location( ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( input[ 1 ].type( ) != E_SRDTokenType::WORD ) {
|
||||||
|
errors.addNew( "identifier (word) expected" , input[ 1 ].location( ) );
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
if ( input.size( ) == 2 ) {
|
||||||
|
errors.addNew( "program name required" , input[ 0 ].location( ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( !input[ 2 ].isText( ) ) {
|
||||||
|
errors.addNew( "program name (string or word) expected" ,
|
||||||
|
input[ 2 ].location( ) );
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( input.size( ) > 3 ) {
|
||||||
|
errors.addNew( "too many arguments" , input[ 3 ].location( ) );
|
||||||
|
}
|
||||||
|
if ( !ok ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
T_ProgramInstrNode& program{ instructions.add< T_ProgramInstrNode >(
|
||||||
|
input[ 1 ] , input[ 2 ] ) };
|
||||||
|
program.location( ) = input[ 0 ].location( );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -208,10 +493,25 @@ bool T_Parser::parse(
|
||||||
if ( t.type( ) == E_SRDTokenType::LIST && t.list( ).size( ) > 0 ) {
|
if ( t.type( ) == E_SRDTokenType::LIST && t.list( ).size( ) > 0 ) {
|
||||||
p< T_ParserImpl_ >( ).parseFunction( t.list( ) );
|
p< T_ParserImpl_ >( ).parseFunction( t.list( ) );
|
||||||
} else {
|
} else {
|
||||||
errors_.addNew( "Function or special block expected" ,
|
errors_.addNew( "function, init or frame list expected" ,
|
||||||
t.location( ) );
|
t.location( ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( errors_.empty( ) ) {
|
||||||
|
T_SRDLocation loc( ([&input]() {
|
||||||
|
if ( input.size( ) != 0 ) {
|
||||||
|
return T_SRDLocation( input[ 0 ].location( ).source( ) , 1 , 1 );
|
||||||
|
}
|
||||||
|
return T_SRDLocation{};
|
||||||
|
})( ));
|
||||||
|
if ( !rootNode_->hasInit( ) ) {
|
||||||
|
errors_.addNew( "no initialisation block" , loc );
|
||||||
|
}
|
||||||
|
if ( !rootNode_->hasFrame( ) ) {
|
||||||
|
errors_.addNew( "no initialisation block" , loc );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return errors_.empty( );
|
return errors_.empty( );
|
||||||
}
|
}
|
||||||
|
|
153
opast.hh
153
opast.hh
|
@ -16,20 +16,24 @@ class A_Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum E_Type {
|
enum E_Type {
|
||||||
ROOT ,
|
ROOT , // Root node
|
||||||
|
ILIST , // Instruction list
|
||||||
//
|
//
|
||||||
DECL_INIT ,
|
DECL_INIT , // Initialisation block
|
||||||
DECL_FRAME ,
|
DECL_FRAME , // Frame block
|
||||||
DECL_FN ,
|
DECL_FN , // Function
|
||||||
//
|
//
|
||||||
OP_SET ,
|
OP_PIPELINE , // Shader pipeline declaration
|
||||||
|
OP_PROFILE , // Profiling block
|
||||||
|
OP_PROGRAM , // Shader program declaration
|
||||||
|
OP_SET , // Set instruction
|
||||||
//
|
//
|
||||||
EXPR_ADD ,
|
EXPR_ADD , // Binary ops: add
|
||||||
EXPR_MUL ,
|
EXPR_MUL , // Binary ops: mul
|
||||||
EXPR_SUB ,
|
EXPR_SUB , // Binary ops: sub
|
||||||
EXPR_DIV ,
|
EXPR_DIV , // Binary ops: div
|
||||||
EXPR_VAR ,
|
EXPR_VAR , // Variable access
|
||||||
EXPR_CONST ,
|
EXPR_CONST , // Numeric constant
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -60,11 +64,49 @@ class A_Node
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class A_InstructionNode : public A_Node
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
A_InstructionNode( E_Type type ,
|
||||||
|
A_Node& parent ) noexcept
|
||||||
|
: A_Node( type , &parent )
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename IType ,
|
||||||
|
typename... ArgTypes
|
||||||
|
> IType& add( ArgTypes&&... args );
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename IType ,
|
||||||
|
typename... ArgTypes
|
||||||
|
> inline IType& T_InstrListNode::add(
|
||||||
|
ArgTypes&&... args )
|
||||||
|
{
|
||||||
|
instructions_.add( NewOwned< IType >( *this ,
|
||||||
|
std::forward< ArgTypes >( args ) ... ) );
|
||||||
|
return (IType&) *instructions_.last( );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
// Function-like nodes
|
// Function-like nodes
|
||||||
class A_FuncNode : public A_Node
|
class A_FuncNode : public A_Node
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
T_String name_;
|
T_String name_;
|
||||||
|
T_InstrListNode instructions_;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// For init or frame entry points.
|
// For init or frame entry points.
|
||||||
|
@ -80,6 +122,11 @@ class A_FuncNode : public A_Node
|
||||||
public:
|
public:
|
||||||
T_String const& name( ) const noexcept
|
T_String const& name( ) const noexcept
|
||||||
{ return name_; }
|
{ return name_; }
|
||||||
|
|
||||||
|
T_InstrListNode& instructions( ) noexcept
|
||||||
|
{ return instructions_; }
|
||||||
|
T_InstrListNode const& instructions( ) const noexcept
|
||||||
|
{ return instructions_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Root node, keeps track of the whole tree and related data (function table,
|
// Root node, keeps track of the whole tree and related data (function table,
|
||||||
|
@ -92,6 +139,8 @@ class T_RootNode : public A_Node
|
||||||
public:
|
public:
|
||||||
T_RootNode( ) noexcept;
|
T_RootNode( ) noexcept;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
// Return type for addFunction. We'll always return a reference to a
|
// Return type for addFunction. We'll always return a reference to a
|
||||||
// function node (which may or may not be the same as the initial one,
|
// function node (which may or may not be the same as the initial one,
|
||||||
// if there were duplicates), and we'll return the location of the
|
// if there were duplicates), and we'll return the location of the
|
||||||
|
@ -117,6 +166,15 @@ class T_RootNode : public A_Node
|
||||||
// entry will be added to the table instead).
|
// entry will be added to the table instead).
|
||||||
T_AddFunctionResult addFunction(
|
T_AddFunctionResult addFunction(
|
||||||
T_OwnPtr< A_FuncNode >& function ) noexcept;
|
T_OwnPtr< A_FuncNode >& function ) noexcept;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool hasFunction( T_String const& name ) noexcept
|
||||||
|
{ return functions_.contains( name ); }
|
||||||
|
bool hasInit( ) noexcept
|
||||||
|
{ return hasFunction( "*init*" ); }
|
||||||
|
bool hasFrame( ) noexcept
|
||||||
|
{ return hasFunction( "*frame*" ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
@ -147,7 +205,78 @@ class T_FuncNode : public A_FuncNode
|
||||||
T_SRDToken const& token ) noexcept;
|
T_SRDToken const& token ) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*============================================================================*/
|
||||||
|
|
||||||
|
// Pipeline declaration instruction
|
||||||
|
class T_PipelineInstrNode : public A_InstructionNode
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T_String id_;
|
||||||
|
T_SRDLocation idLocation_;
|
||||||
|
T_StaticArray< T_String , 6 > pids_;
|
||||||
|
T_StaticArray< T_SRDLocation , 6 > pidLocations_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T_PipelineInstrNode(
|
||||||
|
T_InstrListNode& parent ,
|
||||||
|
T_SRDToken const& idToken ) noexcept;
|
||||||
|
explicit T_PipelineInstrNode(
|
||||||
|
T_InstrListNode& parent ) noexcept;
|
||||||
|
|
||||||
|
// Add a program identifier. The token is assumed to be a valid word,
|
||||||
|
// and the list of programs is assumed not to be full. If the identifer
|
||||||
|
// is already in the pipeline's list, the location of the first
|
||||||
|
// occurrence will be returned.
|
||||||
|
T_Optional< T_SRDLocation > addProgram(
|
||||||
|
T_SRDToken const& pidToken ) noexcept;
|
||||||
|
|
||||||
|
uint32_t size( ) const noexcept
|
||||||
|
{ return pids_.size( ); }
|
||||||
|
|
||||||
|
T_String const& program( const uint32_t index ) const noexcept
|
||||||
|
{ return pids_[ index ]; }
|
||||||
|
T_SRDLocation const& pLocation( const uint32_t index ) const noexcept
|
||||||
|
{ return pidLocations_[ index ]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Profiling instruction
|
||||||
|
class T_ProfileInstrNode : public A_InstructionNode
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T_String text_;
|
||||||
|
T_InstrListNode instructions_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T_ProfileInstrNode(
|
||||||
|
T_InstrListNode& parent ,
|
||||||
|
T_String const& text ) noexcept;
|
||||||
|
|
||||||
|
T_String const& text( ) const
|
||||||
|
{ return text_; }
|
||||||
|
|
||||||
|
T_InstrListNode& instructions( ) noexcept
|
||||||
|
{ return instructions_; }
|
||||||
|
T_InstrListNode const& instructions( ) const noexcept
|
||||||
|
{ return instructions_; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Program loader instruction
|
||||||
|
class T_ProgramInstrNode : public A_InstructionNode
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T_String id_;
|
||||||
|
T_SRDLocation idLocation_;
|
||||||
|
T_String path_;
|
||||||
|
T_SRDLocation pathLocation_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T_ProgramInstrNode(
|
||||||
|
T_InstrListNode& parent ,
|
||||||
|
T_SRDToken const& idToken ,
|
||||||
|
T_SRDToken const& pathToken ) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*============================================================================*/
|
||||||
|
|
||||||
class T_Parser : public A_PrivateImplementation
|
class T_Parser : public A_PrivateImplementation
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue