Parser - Input instruction

This commit is contained in:
Emmanuel BENOîT 2017-11-07 07:43:18 +01:00
parent 3f32dd7f6f
commit 103fbcb6f2
2 changed files with 94 additions and 42 deletions

View file

@ -304,6 +304,7 @@ struct T_ParserImpl_
enum class E_InstrType { enum class E_InstrType {
CALL , CALL ,
IF , IF ,
INPUT ,
PIPELINE , PIPELINE ,
PROFILE , PROFILE ,
PROGRAM , PROGRAM ,
@ -319,6 +320,7 @@ struct T_ParserImpl_
add( "call" , E_InstrType::CALL ); add( "call" , E_InstrType::CALL );
add( "if" , E_InstrType::IF ); add( "if" , E_InstrType::IF );
add( "input" , E_InstrType::INPUT );
add( "pipeline" , E_InstrType::PIPELINE ); add( "pipeline" , E_InstrType::PIPELINE );
add( "profiling" , E_InstrType::PROFILE ); add( "profiling" , E_InstrType::PROFILE );
add( "program" , E_InstrType::PROGRAM ); add( "program" , E_InstrType::PROGRAM );
@ -414,27 +416,21 @@ struct T_ParserImpl_
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
void parseCallInstruction( #define M_DPARSER_( NAME ) \
T_InstrListNode& instructions , void parse##NAME##Instruction( \
T_SRDList const& input ) noexcept; T_InstrListNode& instructions , \
void parseIfInstruction( T_SRDList const& input ) noexcept
T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept; M_DPARSER_( Call );
void parsePipelineInstruction( M_DPARSER_( If );
T_InstrListNode& instructions , M_DPARSER_( Input );
T_SRDList const& input ) noexcept; M_DPARSER_( Pipeline );
void parseProfileInstruction( M_DPARSER_( Profile );
T_InstrListNode& instructions , M_DPARSER_( Program );
T_SRDList const& input ) noexcept; M_DPARSER_( Set );
void parseProgramInstruction( M_DPARSER_( Texture );
T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept; #undef M_DPARSER_
void parseSetInstruction(
T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept;
void parseTextureInstruction(
T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept;
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -576,6 +572,7 @@ void T_ParserImpl_::parseInstructions(
switch ( *instrMap.get( iword ) ) { switch ( *instrMap.get( iword ) ) {
M_CASE_( CALL , Call ); M_CASE_( CALL , Call );
M_CASE_( IF , If ); M_CASE_( IF , If );
M_CASE_( INPUT , Input );
M_CASE_( PIPELINE , Pipeline ); M_CASE_( PIPELINE , Pipeline );
M_CASE_( PROFILE , Profile ); M_CASE_( PROFILE , Profile );
M_CASE_( PROGRAM , Program ); M_CASE_( PROGRAM , Program );
@ -603,9 +600,12 @@ P_InstrListNode T_ParserImpl_::parseBlock(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void T_ParserImpl_::parseCallInstruction( #define M_INSTR_( NAME ) \
T_InstrListNode& instructions , void T_ParserImpl_::parse##NAME##Instruction( \
T_InstrListNode& instructions , \
T_SRDList const& input ) noexcept T_SRDList const& input ) noexcept
M_INSTR_( Call )
{ {
if ( input.size( ) == 1 || input[ 1 ].type( ) != E_SRDTokenType::WORD ) { if ( input.size( ) == 1 || input[ 1 ].type( ) != E_SRDTokenType::WORD ) {
errors.addNew( "function identifier expected" , errors.addNew( "function identifier expected" ,
@ -621,9 +621,7 @@ void T_ParserImpl_::parseCallInstruction(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void T_ParserImpl_::parseIfInstruction( M_INSTR_( If )
T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept
{ {
if ( input.size( ) == 1 ) { if ( input.size( ) == 1 ) {
errors.addNew( "expression and 'then' block expected" , errors.addNew( "expression and 'then' block expected" ,
@ -652,9 +650,34 @@ void T_ParserImpl_::parseIfInstruction(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void T_ParserImpl_::parsePipelineInstruction( M_INSTR_( Input )
T_InstrListNode& instructions , {
T_SRDList const& input ) noexcept if ( input.size( ) < 2 || !input[ 1 ].isText( ) ) {
errors.addNew( "input identifier expected" ,
input[ input.size( ) < 2 ? 0 : 1 ].location( ) );
return;
}
if ( input.size( ) > 3 ) {
errors.addNew( "too many arguments" , input[ 3 ].location( ) );
}
if ( input.size( ) >= 3 && !input[ 2 ].isNumeric( ) ) {
errors.addNew( "default value expected" , input[ 2 ].location( ) );
}
const bool hasDefault( input.size( ) >= 3 && input[ 2 ].isNumeric( ) );
auto& instr( ([&]() -> T_InputInstrNode& {
if ( hasDefault ) {
return instructions.add< T_InputInstrNode >(
input[ 1 ] , input[ 2 ] );
}
return instructions.add< T_InputInstrNode >( input[ 1 ] );
})( ) );
instr.location( ) = input[ 0 ].location( );
}
/*----------------------------------------------------------------------------*/
M_INSTR_( Pipeline )
{ {
if ( input.size( ) < 3 ) { if ( input.size( ) < 3 ) {
errors.addNew( "identifier and program identifiers expected" , errors.addNew( "identifier and program identifiers expected" ,
@ -699,9 +722,7 @@ void T_ParserImpl_::parsePipelineInstruction(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void T_ParserImpl_::parseProfileInstruction( M_INSTR_( Profile )
T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept
{ {
const bool hasEnough( input.size( ) < 2 ); const bool hasEnough( input.size( ) < 2 );
if ( hasEnough || !input[ 1 ].isText( ) ) { if ( hasEnough || !input[ 1 ].isText( ) ) {
@ -720,9 +741,7 @@ void T_ParserImpl_::parseProfileInstruction(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void T_ParserImpl_::parseProgramInstruction( M_INSTR_( Program )
T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept
{ {
bool ok{ true }; bool ok{ true };
if ( input.size( ) == 1 ) { if ( input.size( ) == 1 ) {
@ -758,9 +777,7 @@ void T_ParserImpl_::parseProgramInstruction(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void T_ParserImpl_::parseSetInstruction( M_INSTR_( Set )
T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept
{ {
bool ok{ true }; bool ok{ true };
if ( input.size( ) == 1 ) { if ( input.size( ) == 1 ) {
@ -794,9 +811,7 @@ void T_ParserImpl_::parseSetInstruction(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void T_ParserImpl_::parseTextureInstruction( M_INSTR_( Texture )
T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept
{ {
if ( input.size( ) < 2 || input[ 1 ].type( ) != E_SRDTokenType::WORD ) { if ( input.size( ) < 2 || input[ 1 ].type( ) != E_SRDTokenType::WORD ) {
errors.addNew( "texture identifier expected" , errors.addNew( "texture identifier expected" ,

View file

@ -25,6 +25,7 @@ class A_Node
// //
OP_CALL , // Function call OP_CALL , // Function call
OP_COND , // Conditional instruction OP_COND , // Conditional instruction
OP_INPUT , // Input declaration
OP_PIPELINE , // Shader pipeline declaration OP_PIPELINE , // Shader pipeline declaration
OP_PROFILE , // Profiling block OP_PROFILE , // Profiling block
OP_PROGRAM , // Shader program declaration OP_PROGRAM , // Shader program declaration
@ -233,6 +234,7 @@ using P_ExpressionNode = T_OwnPtr< A_ExpressionNode >;
/*============================================================================*/ /*============================================================================*/
// Function call
class T_CallInstrNode : public A_InstructionNode class T_CallInstrNode : public A_InstructionNode
{ {
private: private:
@ -312,6 +314,41 @@ class T_CondInstrNode : public A_InstructionNode
{ return *defaultCase_; } { return *defaultCase_; }
}; };
// Input declaration
class T_InputInstrNode : public A_InstructionNode
{
private:
T_String name_;
T_SRDLocation nameLocation_;
float defValue_;
T_SRDLocation dvLocation_;
public:
T_InputInstrNode( T_InstrListNode& parent ,
T_SRDToken const& tName ) noexcept
: A_InstructionNode( OP_INPUT , parent ) ,
name_( tName.stringValue( ) ) , nameLocation_( tName.location( ) )
{}
T_InputInstrNode( T_InstrListNode& parent ,
T_SRDToken const& tName ,
T_SRDToken const& tDefault ) noexcept
: A_InstructionNode( OP_INPUT , parent ) ,
name_( tName.stringValue( ) ) , nameLocation_( tName.location( ) ) ,
defValue_( tDefault.floatValue( ) ) , dvLocation_( tDefault.location( ) )
{}
T_String const& name( ) const noexcept
{ return name_; }
T_SRDLocation const& nameLocation( ) const noexcept
{ return nameLocation_; }
float defValue( ) const noexcept
{ return defValue_; }
T_SRDLocation const& defValueLocation( ) const noexcept
{ return dvLocation_; }
};
// Pipeline declaration instruction // Pipeline declaration instruction
class T_PipelineInstrNode : public A_InstructionNode class T_PipelineInstrNode : public A_InstructionNode
{ {