Parser - Conditionals

Structure for conditionals + support for the if instruction
This commit is contained in:
Emmanuel BENOîT 2017-11-06 17:09:05 +01:00
parent a9bd3cf507
commit a23dc75ec4
2 changed files with 131 additions and 16 deletions

View file

@ -366,13 +366,22 @@ struct T_ParserImpl_
void parseFunctionArguments( void parseFunctionArguments(
T_FuncNode& function , T_FuncNode& function ,
T_SRDToken const& argsToken ) noexcept; T_SRDToken const& argsToken ) noexcept;
// ---------------------------------------------------------------------
void parseInstructions( void parseInstructions(
T_InstrListNode& instructions , T_InstrListNode& instructions ,
T_SRDList const& input , T_SRDList const& input ,
uint32_t start ) noexcept; uint32_t start ) noexcept;
P_InstrListNode parseBlock(
A_Node& parent ,
T_SRDToken const& block ) noexcept;
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
void parseIfInstruction(
T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept;
void parsePipelineInstruction( void parsePipelineInstruction(
T_InstrListNode& instructions , T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept; T_SRDList const& input ) noexcept;
@ -388,17 +397,17 @@ struct T_ParserImpl_
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
T_OwnPtr< A_ExpressionNode > parseExpression( P_ExpressionNode parseExpression(
A_Node& parent , A_Node& parent ,
T_SRDToken const& token ) noexcept; T_SRDToken const& token ) noexcept;
T_OwnPtr< A_ExpressionNode > parseOperation( P_ExpressionNode parseOperation(
A_Node& parent , A_Node& parent ,
T_SRDList const& opList ) noexcept; T_SRDList const& opList ) noexcept;
T_OwnPtr< A_ExpressionNode > parseBinOp( P_ExpressionNode parseBinOp(
A_Node& parent , A_Node& parent ,
T_SRDList const& opList , T_SRDList const& opList ,
T_BinaryOperatorNode::E_Operator op ) noexcept; T_BinaryOperatorNode::E_Operator op ) noexcept;
T_OwnPtr< A_ExpressionNode > parseUnaryOp( P_ExpressionNode parseUnaryOp(
A_Node& parent , A_Node& parent ,
T_SRDList const& opList , T_SRDList const& opList ,
T_UnaryOperatorNode::E_Operator op ) noexcept; T_UnaryOperatorNode::E_Operator op ) noexcept;
@ -490,6 +499,8 @@ void T_ParserImpl_::parseFunctionArguments(
} }
} }
/*----------------------------------------------------------------------------*/
void T_ParserImpl_::parseInstructions( void T_ParserImpl_::parseInstructions(
T_InstrListNode& instructions , T_InstrListNode& instructions ,
T_SRDList const& input , T_SRDList const& input ,
@ -521,6 +532,9 @@ void T_ParserImpl_::parseInstructions(
} }
switch ( *instrMap.get( iword ) ) { switch ( *instrMap.get( iword ) ) {
case E_InstrType::IF:
parseIfInstruction( instructions , ilist );
break;
case E_InstrType::PIPELINE: case E_InstrType::PIPELINE:
parsePipelineInstruction( instructions , ilist ); parsePipelineInstruction( instructions , ilist );
break; break;
@ -537,6 +551,52 @@ void T_ParserImpl_::parseInstructions(
} }
} }
P_InstrListNode T_ParserImpl_::parseBlock(
A_Node& parent ,
T_SRDToken const& block ) noexcept
{
if ( block.type( ) != E_SRDTokenType::LIST ) {
errors.addNew( "block expected" , block.location( ) );
return {};
}
P_InstrListNode rv{ NewOwned< T_InstrListNode >( parent ) };
rv->location( ) = block.location( );
parseInstructions( *rv , block.list( ) , 0 );
return rv;
}
/*----------------------------------------------------------------------------*/
void T_ParserImpl_::parseIfInstruction(
T_InstrListNode& instructions ,
T_SRDList const& input ) noexcept
{
if ( input.size( ) == 1 ) {
errors.addNew( "expression and 'then' block expected" ,
input[ 0 ].location( ) );
return;
}
T_CondInstrNode& cond{ instructions.add< T_CondInstrNode >( ) };
cond.location( ) = input[ 0 ].location( );
cond.setExpression( parseExpression( cond , input[ 1 ] ) );
if ( input.size( ) == 2 ) {
errors.addNew( "'then' block expected" ,
input[ 0 ].location( ) );
return;
}
cond.setCase( 1 , parseBlock( cond , input[ 2 ] ) );
if ( input.size( ) > 3 ) {
cond.setDefaultCase( parseBlock( cond , input[ 3 ] ) );
if ( input.size( ) > 4 ) {
errors.addNew( "too many arguments" , input[ 4 ].location( ) );
}
}
}
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void T_ParserImpl_::parsePipelineInstruction( void T_ParserImpl_::parsePipelineInstruction(
@ -681,7 +741,7 @@ void T_ParserImpl_::parseSetInstruction(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseExpression( P_ExpressionNode T_ParserImpl_::parseExpression(
A_Node& parent , A_Node& parent ,
T_SRDToken const& token ) noexcept T_SRDToken const& token ) noexcept
{ {
@ -700,7 +760,7 @@ T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseExpression(
return {}; return {};
} }
T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseOperation( P_ExpressionNode T_ParserImpl_::parseOperation(
A_Node& parent , A_Node& parent ,
T_SRDList const& opList ) noexcept T_SRDList const& opList ) noexcept
{ {
@ -723,7 +783,7 @@ T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseOperation(
return {}; return {};
} }
T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseBinOp( P_ExpressionNode T_ParserImpl_::parseBinOp(
A_Node& parent , A_Node& parent ,
T_SRDList const& opList , T_SRDList const& opList ,
T_BinaryOperatorNode::E_Operator op ) noexcept T_BinaryOperatorNode::E_Operator op ) noexcept
@ -754,7 +814,7 @@ T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseBinOp(
return opNode; return opNode;
} }
T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseUnaryOp( P_ExpressionNode T_ParserImpl_::parseUnaryOp(
A_Node& parent , A_Node& parent ,
T_SRDList const& opList , T_SRDList const& opList ,
T_UnaryOperatorNode::E_Operator op ) noexcept T_UnaryOperatorNode::E_Operator op ) noexcept

View file

@ -23,6 +23,7 @@ class A_Node
DECL_FRAME , // Frame block DECL_FRAME , // Frame block
DECL_FN , // Function DECL_FN , // Function
// //
OP_COND , // Conditional instruction
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
@ -137,6 +138,7 @@ class A_FuncNode : public A_Node
T_InstrListNode const& instructions( ) const noexcept T_InstrListNode const& instructions( ) const noexcept
{ return instructions_; } { return instructions_; }
}; };
using P_InstrListNode = T_OwnPtr< T_InstrListNode >;
// 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,
// assets...) // assets...)
@ -225,9 +227,62 @@ class A_ExpressionNode : public A_Node
: A_Node( type , &parent ) : A_Node( type , &parent )
{ } { }
}; };
using P_ExpressionNode = T_OwnPtr< A_ExpressionNode >;
/*============================================================================*/ /*============================================================================*/
// Conditional instruction
class T_CondInstrNode : public A_InstructionNode
{
private:
P_ExpressionNode expression_;
T_KeyValueTable< int64_t , P_InstrListNode > cases_;
P_InstrListNode defaultCase_;
public:
explicit T_CondInstrNode( T_InstrListNode& parent ) noexcept
: A_InstructionNode( OP_COND , parent )
{ }
void setExpression( P_ExpressionNode expression ) noexcept
{ expression_ = std::move( expression ); }
bool hasExpression( ) const noexcept
{ return bool( expression_ ); }
A_ExpressionNode& expression( ) noexcept
{ return *expression_; }
A_ExpressionNode const& expression( ) const noexcept
{ return *expression_; }
void setCase( const int64_t value ,
P_InstrListNode instrList ) noexcept
{
if ( instrList ) {
cases_.set( value , std::move( instrList ) );
}
}
void rmCase( const int64_t value ) noexcept
{ cases_.remove( value ); }
T_Array< int64_t > const& cases( ) const noexcept
{ return cases_.keys( ); }
bool hasCase( const int64_t value ) const noexcept
{ return cases_.contains( value ); }
T_InstrListNode& getCase( const int64_t value ) noexcept
{ return **cases_.get( value ); }
T_InstrListNode const& getCase( const int64_t value ) const noexcept
{ return **cases_.get( value ); }
void setDefaultCase( P_InstrListNode defaultCase ) noexcept
{ defaultCase_ = std::move( defaultCase ); }
bool hasDefaultCase( ) const noexcept
{ return bool( defaultCase_ ); }
T_InstrListNode& defaultCase( ) noexcept
{ return *defaultCase_; }
T_InstrListNode const& defaultCase( ) const noexcept
{ return *defaultCase_; }
};
// Pipeline declaration instruction // Pipeline declaration instruction
class T_PipelineInstrNode : public A_InstructionNode class T_PipelineInstrNode : public A_InstructionNode
{ {
@ -303,7 +358,7 @@ class T_SetInstrNode : public A_InstructionNode
private: private:
T_String id_; T_String id_;
T_SRDLocation idLocation_; T_SRDLocation idLocation_;
T_OwnPtr< A_ExpressionNode > expression_; P_ExpressionNode expression_;
public: public:
T_SetInstrNode( T_InstrListNode& parent , T_SetInstrNode( T_InstrListNode& parent ,
@ -314,7 +369,7 @@ class T_SetInstrNode : public A_InstructionNode
T_SRDLocation const& idLocation( ) const noexcept T_SRDLocation const& idLocation( ) const noexcept
{ return idLocation_; } { return idLocation_; }
void setExpression( T_OwnPtr< A_ExpressionNode > expression ) noexcept void setExpression( P_ExpressionNode expression ) noexcept
{ expression_ = std::move( expression ); } { expression_ = std::move( expression ); }
bool hasExpression( ) const noexcept bool hasExpression( ) const noexcept
@ -380,7 +435,7 @@ class T_UnaryOperatorNode : public A_ExpressionNode
private: private:
E_Operator op_; E_Operator op_;
T_OwnPtr< A_ExpressionNode > argument_; P_ExpressionNode argument_;
public: public:
T_UnaryOperatorNode( T_UnaryOperatorNode(
@ -390,7 +445,7 @@ class T_UnaryOperatorNode : public A_ExpressionNode
E_Operator op( ) const noexcept E_Operator op( ) const noexcept
{ return op_; } { return op_; }
void setArgument( T_OwnPtr< A_ExpressionNode > argument ) noexcept void setArgument( P_ExpressionNode argument ) noexcept
{ argument_ = std::move( argument ); } { argument_ = std::move( argument ); }
bool hasArgument( ) const noexcept bool hasArgument( ) const noexcept
@ -418,8 +473,8 @@ class T_BinaryOperatorNode : public A_ExpressionNode
private: private:
E_Operator op_; E_Operator op_;
T_OwnPtr< A_ExpressionNode > left_; P_ExpressionNode left_;
T_OwnPtr< A_ExpressionNode > right_; P_ExpressionNode right_;
public: public:
T_BinaryOperatorNode( T_BinaryOperatorNode(
@ -429,9 +484,9 @@ class T_BinaryOperatorNode : public A_ExpressionNode
E_Operator op( ) const noexcept E_Operator op( ) const noexcept
{ return op_; } { return op_; }
void setLeft( T_OwnPtr< A_ExpressionNode > left ) noexcept void setLeft( P_ExpressionNode left ) noexcept
{ left_ = std::move( left ); } { left_ = std::move( left ); }
void setRight( T_OwnPtr< A_ExpressionNode > right ) noexcept void setRight( P_ExpressionNode right ) noexcept
{ right_ = std::move( right ); } { right_ = std::move( right ); }
bool hasLeft( ) const noexcept bool hasLeft( ) const noexcept