Parser - Conditionals
Structure for conditionals + support for the if instruction
This commit is contained in:
parent
a9bd3cf507
commit
a23dc75ec4
2 changed files with 131 additions and 16 deletions
76
opast.cc
76
opast.cc
|
@ -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
|
||||||
|
|
71
opast.hh
71
opast.hh
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue