From a23dc75ec4c5a99efe026551bfa31a061a506bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Mon, 6 Nov 2017 17:09:05 +0100 Subject: [PATCH] Parser - Conditionals Structure for conditionals + support for the if instruction --- opast.cc | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++------ opast.hh | 71 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 131 insertions(+), 16 deletions(-) diff --git a/opast.cc b/opast.cc index 720b3fe..92a388a 100644 --- a/opast.cc +++ b/opast.cc @@ -366,13 +366,22 @@ struct T_ParserImpl_ void parseFunctionArguments( T_FuncNode& function , T_SRDToken const& argsToken ) noexcept; + + // --------------------------------------------------------------------- + void parseInstructions( T_InstrListNode& instructions , T_SRDList const& input , 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( T_InstrListNode& instructions , T_SRDList const& input ) noexcept; @@ -388,17 +397,17 @@ struct T_ParserImpl_ // --------------------------------------------------------------------- - T_OwnPtr< A_ExpressionNode > parseExpression( + P_ExpressionNode parseExpression( A_Node& parent , T_SRDToken const& token ) noexcept; - T_OwnPtr< A_ExpressionNode > parseOperation( + P_ExpressionNode parseOperation( A_Node& parent , T_SRDList const& opList ) noexcept; - T_OwnPtr< A_ExpressionNode > parseBinOp( + P_ExpressionNode parseBinOp( A_Node& parent , T_SRDList const& opList , T_BinaryOperatorNode::E_Operator op ) noexcept; - T_OwnPtr< A_ExpressionNode > parseUnaryOp( + P_ExpressionNode parseUnaryOp( A_Node& parent , T_SRDList const& opList , T_UnaryOperatorNode::E_Operator op ) noexcept; @@ -490,6 +499,8 @@ void T_ParserImpl_::parseFunctionArguments( } } +/*----------------------------------------------------------------------------*/ + void T_ParserImpl_::parseInstructions( T_InstrListNode& instructions , T_SRDList const& input , @@ -521,6 +532,9 @@ void T_ParserImpl_::parseInstructions( } switch ( *instrMap.get( iword ) ) { + case E_InstrType::IF: + parseIfInstruction( instructions , ilist ); + break; case E_InstrType::PIPELINE: parsePipelineInstruction( instructions , ilist ); 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( @@ -681,7 +741,7 @@ void T_ParserImpl_::parseSetInstruction( /*----------------------------------------------------------------------------*/ -T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseExpression( +P_ExpressionNode T_ParserImpl_::parseExpression( A_Node& parent , T_SRDToken const& token ) noexcept { @@ -700,7 +760,7 @@ T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseExpression( return {}; } -T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseOperation( +P_ExpressionNode T_ParserImpl_::parseOperation( A_Node& parent , T_SRDList const& opList ) noexcept { @@ -723,7 +783,7 @@ T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseOperation( return {}; } -T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseBinOp( +P_ExpressionNode T_ParserImpl_::parseBinOp( A_Node& parent , T_SRDList const& opList , T_BinaryOperatorNode::E_Operator op ) noexcept @@ -754,7 +814,7 @@ T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseBinOp( return opNode; } -T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseUnaryOp( +P_ExpressionNode T_ParserImpl_::parseUnaryOp( A_Node& parent , T_SRDList const& opList , T_UnaryOperatorNode::E_Operator op ) noexcept diff --git a/opast.hh b/opast.hh index f84a43d..59002a3 100644 --- a/opast.hh +++ b/opast.hh @@ -23,6 +23,7 @@ class A_Node DECL_FRAME , // Frame block DECL_FN , // Function // + OP_COND , // Conditional instruction OP_PIPELINE , // Shader pipeline declaration OP_PROFILE , // Profiling block OP_PROGRAM , // Shader program declaration @@ -137,6 +138,7 @@ class A_FuncNode : public A_Node T_InstrListNode const& instructions( ) const noexcept { return instructions_; } }; +using P_InstrListNode = T_OwnPtr< T_InstrListNode >; // Root node, keeps track of the whole tree and related data (function table, // assets...) @@ -225,9 +227,62 @@ class A_ExpressionNode : public A_Node : 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 class T_PipelineInstrNode : public A_InstructionNode { @@ -303,7 +358,7 @@ class T_SetInstrNode : public A_InstructionNode private: T_String id_; T_SRDLocation idLocation_; - T_OwnPtr< A_ExpressionNode > expression_; + P_ExpressionNode expression_; public: T_SetInstrNode( T_InstrListNode& parent , @@ -314,7 +369,7 @@ class T_SetInstrNode : public A_InstructionNode T_SRDLocation const& idLocation( ) const noexcept { return idLocation_; } - void setExpression( T_OwnPtr< A_ExpressionNode > expression ) noexcept + void setExpression( P_ExpressionNode expression ) noexcept { expression_ = std::move( expression ); } bool hasExpression( ) const noexcept @@ -380,7 +435,7 @@ class T_UnaryOperatorNode : public A_ExpressionNode private: E_Operator op_; - T_OwnPtr< A_ExpressionNode > argument_; + P_ExpressionNode argument_; public: T_UnaryOperatorNode( @@ -390,7 +445,7 @@ class T_UnaryOperatorNode : public A_ExpressionNode E_Operator op( ) const noexcept { return op_; } - void setArgument( T_OwnPtr< A_ExpressionNode > argument ) noexcept + void setArgument( P_ExpressionNode argument ) noexcept { argument_ = std::move( argument ); } bool hasArgument( ) const noexcept @@ -418,8 +473,8 @@ class T_BinaryOperatorNode : public A_ExpressionNode private: E_Operator op_; - T_OwnPtr< A_ExpressionNode > left_; - T_OwnPtr< A_ExpressionNode > right_; + P_ExpressionNode left_; + P_ExpressionNode right_; public: T_BinaryOperatorNode( @@ -429,9 +484,9 @@ class T_BinaryOperatorNode : public A_ExpressionNode E_Operator op( ) const noexcept { return op_; } - void setLeft( T_OwnPtr< A_ExpressionNode > left ) noexcept + void setLeft( P_ExpressionNode left ) noexcept { left_ = std::move( left ); } - void setRight( T_OwnPtr< A_ExpressionNode > right ) noexcept + void setRight( P_ExpressionNode right ) noexcept { right_ = std::move( right ); } bool hasLeft( ) const noexcept