Parser - Expressions
Constants, identifier references, binary and unary ops
This commit is contained in:
parent
ab999d222b
commit
a9bd3cf507
2 changed files with 485 additions and 6 deletions
307
opast.cc
307
opast.cc
|
@ -179,6 +179,108 @@ T_ProgramInstrNode::T_ProgramInstrNode(
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
/*= T_SetInstrNode ===========================================================*/
|
||||||
|
|
||||||
|
T_SetInstrNode::T_SetInstrNode(
|
||||||
|
T_InstrListNode& parent ,
|
||||||
|
T_SRDToken const& idToken ) noexcept
|
||||||
|
: A_InstructionNode( OP_PROGRAM , parent ) ,
|
||||||
|
id_( idToken.stringValue( ) ) ,
|
||||||
|
idLocation_( idToken.location( ) )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
/*= T_ConstantExprNode =======================================================*/
|
||||||
|
|
||||||
|
T_ConstantExprNode::T_ConstantExprNode(
|
||||||
|
A_Node& parent ,
|
||||||
|
T_SRDToken const& token ) noexcept
|
||||||
|
: A_ExpressionNode( EXPR_CONST , parent ) ,
|
||||||
|
wasFloat_( token.type( ) == E_SRDTokenType::FLOAT ) ,
|
||||||
|
vFloat_( token.floatValue( ) ) ,
|
||||||
|
vInt_( token.longValue( ) )
|
||||||
|
{
|
||||||
|
location( ) = token.location( );
|
||||||
|
}
|
||||||
|
|
||||||
|
T_ConstantExprNode::T_ConstantExprNode(
|
||||||
|
A_Node& parent ,
|
||||||
|
double value ) noexcept
|
||||||
|
: A_ExpressionNode( EXPR_CONST , parent ) , wasFloat_( true ) ,
|
||||||
|
vFloat_( value ) , vInt_( (int64_t) value )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
T_ConstantExprNode::T_ConstantExprNode(
|
||||||
|
A_Node& parent ,
|
||||||
|
int64_t value ) noexcept
|
||||||
|
: A_ExpressionNode( EXPR_CONST , parent ) , wasFloat_( false ) ,
|
||||||
|
vFloat_( value ) , vInt_( value )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
/*= T_IdentifierExprNode =====================================================*/
|
||||||
|
|
||||||
|
T_IdentifierExprNode::T_IdentifierExprNode(
|
||||||
|
A_Node& parent ,
|
||||||
|
T_SRDToken const& token ) noexcept
|
||||||
|
: T_IdentifierExprNode( parent , token.stringValue( ) )
|
||||||
|
{
|
||||||
|
location( ) = token.location( );
|
||||||
|
}
|
||||||
|
|
||||||
|
T_IdentifierExprNode::T_IdentifierExprNode(
|
||||||
|
A_Node& parent ,
|
||||||
|
T_String const& id ) noexcept
|
||||||
|
: A_ExpressionNode( EXPR_ID , parent ) , id_( id )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
/*= T_UnaryOperatorNode ======================================================*/
|
||||||
|
|
||||||
|
T_UnaryOperatorNode::T_UnaryOperatorNode(
|
||||||
|
A_Node& parent ,
|
||||||
|
const E_Operator op ) noexcept
|
||||||
|
: A_ExpressionNode( ([op]() {
|
||||||
|
switch ( op ) {
|
||||||
|
case NEG: return EXPR_NEG;
|
||||||
|
case INV: return EXPR_INV;
|
||||||
|
case NOT: return EXPR_NOT;
|
||||||
|
case SIN: return EXPR_SIN;
|
||||||
|
case COS: return EXPR_COS;
|
||||||
|
case TAN: return EXPR_TAN;
|
||||||
|
case SQRT: return EXPR_SQRT;
|
||||||
|
case EXP: return EXPR_EXP;
|
||||||
|
case LN: return EXPR_LN;
|
||||||
|
}
|
||||||
|
std::abort( );
|
||||||
|
})( ) , parent ) , op_( op )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
/*= T_BinaryOperatorNode =====================================================*/
|
||||||
|
|
||||||
|
T_BinaryOperatorNode::T_BinaryOperatorNode(
|
||||||
|
A_Node& parent ,
|
||||||
|
const E_Operator op ) noexcept
|
||||||
|
: A_ExpressionNode( ([op]() {
|
||||||
|
switch ( op ) {
|
||||||
|
case ADD: return EXPR_ADD;
|
||||||
|
case SUB: return EXPR_SUB;
|
||||||
|
case MUL: return EXPR_MUL;
|
||||||
|
case DIV: return EXPR_DIV;
|
||||||
|
case POW: return EXPR_POW;
|
||||||
|
case CMP_EQ: return EXPR_CMP_EQ;
|
||||||
|
case CMP_NE: return EXPR_CMP_NE;
|
||||||
|
case CMP_GT: return EXPR_CMP_GT;
|
||||||
|
case CMP_GE: return EXPR_CMP_GE;
|
||||||
|
case CMP_LT: return EXPR_CMP_LT;
|
||||||
|
case CMP_LE: return EXPR_CMP_LE;
|
||||||
|
}
|
||||||
|
std::abort( );
|
||||||
|
})( ) , parent ) , op_( op )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
/*= T_Parser =================================================================*/
|
/*= T_Parser =================================================================*/
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -190,10 +292,11 @@ struct T_ParserImpl_
|
||||||
PIPELINE ,
|
PIPELINE ,
|
||||||
PROFILE ,
|
PROFILE ,
|
||||||
PROGRAM ,
|
PROGRAM ,
|
||||||
|
SET ,
|
||||||
};
|
};
|
||||||
|
|
||||||
const T_KeyValueTable< T_String , E_InstrType > instrMap{ ([]() {
|
const T_KeyValueTable< T_String , E_InstrType > instrMap{ ([]() {
|
||||||
T_KeyValueTable< T_String , E_InstrType > temp;
|
T_KeyValueTable< T_String , E_InstrType > temp{ 256 , 64 , 64 };
|
||||||
const auto add{ [&temp]( char const* name , E_InstrType it ) {
|
const auto add{ [&temp]( char const* name , E_InstrType it ) {
|
||||||
temp.add( T_String::Pooled( name ) , it );
|
temp.add( T_String::Pooled( name ) , it );
|
||||||
} };
|
} };
|
||||||
|
@ -202,6 +305,49 @@ struct T_ParserImpl_
|
||||||
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 );
|
||||||
|
add( "set" , E_InstrType::SET );
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
})( ) };
|
||||||
|
|
||||||
|
const T_KeyValueTable< T_String , T_UnaryOperatorNode::E_Operator > unaryOpMap{ ([]() {
|
||||||
|
T_KeyValueTable< T_String , T_UnaryOperatorNode::E_Operator > temp{ 64 , 32 , 32 };
|
||||||
|
const auto add{ [&temp]( char const* name ,
|
||||||
|
const T_UnaryOperatorNode::E_Operator it ) {
|
||||||
|
temp.add( T_String::Pooled( name ) , it );
|
||||||
|
} };
|
||||||
|
|
||||||
|
add( "neg" , T_UnaryOperatorNode::NEG );
|
||||||
|
add( "inv" , T_UnaryOperatorNode::INV );
|
||||||
|
add( "not" , T_UnaryOperatorNode::NOT );
|
||||||
|
add( "sin" , T_UnaryOperatorNode::SIN );
|
||||||
|
add( "cos" , T_UnaryOperatorNode::COS );
|
||||||
|
add( "tan" , T_UnaryOperatorNode::TAN );
|
||||||
|
add( "sqrt" , T_UnaryOperatorNode::SQRT );
|
||||||
|
add( "exp" , T_UnaryOperatorNode::EXP );
|
||||||
|
add( "ln" , T_UnaryOperatorNode::LN );
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
})( ) };
|
||||||
|
|
||||||
|
const T_KeyValueTable< T_String , T_BinaryOperatorNode::E_Operator > binOpMap{ ([]() {
|
||||||
|
T_KeyValueTable< T_String , T_BinaryOperatorNode::E_Operator > temp{ 64 , 32 , 32 };
|
||||||
|
const auto add{ [&temp]( char const* name ,
|
||||||
|
const T_BinaryOperatorNode::E_Operator it ) {
|
||||||
|
temp.add( T_String::Pooled( name ) , it );
|
||||||
|
} };
|
||||||
|
|
||||||
|
add( "add" , T_BinaryOperatorNode::ADD );
|
||||||
|
add( "sub" , T_BinaryOperatorNode::SUB );
|
||||||
|
add( "mul" , T_BinaryOperatorNode::MUL );
|
||||||
|
add( "div" , T_BinaryOperatorNode::DIV );
|
||||||
|
add( "pow" , T_BinaryOperatorNode::POW );
|
||||||
|
add( "cmp-eq" , T_BinaryOperatorNode::CMP_EQ );
|
||||||
|
add( "cmp-ne" , T_BinaryOperatorNode::CMP_NE );
|
||||||
|
add( "cmp-gt" , T_BinaryOperatorNode::CMP_GT );
|
||||||
|
add( "cmp-ge" , T_BinaryOperatorNode::CMP_GE );
|
||||||
|
add( "cmp-lt" , T_BinaryOperatorNode::CMP_LT );
|
||||||
|
add( "cmp-le" , T_BinaryOperatorNode::CMP_LE );
|
||||||
|
|
||||||
return temp;
|
return temp;
|
||||||
})( ) };
|
})( ) };
|
||||||
|
@ -236,6 +382,26 @@ struct T_ParserImpl_
|
||||||
void parseProgramInstruction(
|
void parseProgramInstruction(
|
||||||
T_InstrListNode& instructions ,
|
T_InstrListNode& instructions ,
|
||||||
T_SRDList const& input ) noexcept;
|
T_SRDList const& input ) noexcept;
|
||||||
|
void parseSetInstruction(
|
||||||
|
T_InstrListNode& instructions ,
|
||||||
|
T_SRDList const& input ) noexcept;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
T_OwnPtr< A_ExpressionNode > parseExpression(
|
||||||
|
A_Node& parent ,
|
||||||
|
T_SRDToken const& token ) noexcept;
|
||||||
|
T_OwnPtr< A_ExpressionNode > parseOperation(
|
||||||
|
A_Node& parent ,
|
||||||
|
T_SRDList const& opList ) noexcept;
|
||||||
|
T_OwnPtr< A_ExpressionNode > parseBinOp(
|
||||||
|
A_Node& parent ,
|
||||||
|
T_SRDList const& opList ,
|
||||||
|
T_BinaryOperatorNode::E_Operator op ) noexcept;
|
||||||
|
T_OwnPtr< A_ExpressionNode > parseUnaryOp(
|
||||||
|
A_Node& parent ,
|
||||||
|
T_SRDList const& opList ,
|
||||||
|
T_UnaryOperatorNode::E_Operator op ) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_ParserImpl_::T_ParserImpl_(
|
T_ParserImpl_::T_ParserImpl_(
|
||||||
|
@ -364,6 +530,9 @@ void T_ParserImpl_::parseInstructions(
|
||||||
case E_InstrType::PROGRAM:
|
case E_InstrType::PROGRAM:
|
||||||
parseProgramInstruction( instructions , ilist );
|
parseProgramInstruction( instructions , ilist );
|
||||||
break;
|
break;
|
||||||
|
case E_InstrType::SET:
|
||||||
|
parseSetInstruction( instructions , ilist );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -474,6 +643,142 @@ void T_ParserImpl_::parseProgramInstruction(
|
||||||
program.location( ) = input[ 0 ].location( );
|
program.location( ) = input[ 0 ].location( );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void T_ParserImpl_::parseSetInstruction(
|
||||||
|
T_InstrListNode& instructions ,
|
||||||
|
T_SRDList const& input ) noexcept
|
||||||
|
{
|
||||||
|
bool ok{ true };
|
||||||
|
if ( input.size( ) == 1 ) {
|
||||||
|
errors.addNew( "identifier and expression required" ,
|
||||||
|
input[ 0 ].location( ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( input[ 1 ].type( ) != E_SRDTokenType::WORD ) {
|
||||||
|
errors.addNew( "variable identifier expected" , input[ 1 ].location( ) );
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
if ( input.size( ) == 2 ) {
|
||||||
|
errors.addNew( "expression required" , input[ 0 ].location( ) );
|
||||||
|
}
|
||||||
|
if ( input.size( ) > 3 ) {
|
||||||
|
errors.addNew( "too many arguments" , input[ 3 ].location( ) );
|
||||||
|
}
|
||||||
|
if ( !ok ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
T_SetInstrNode& set{ instructions.add< T_SetInstrNode >( input[ 1 ] ) };
|
||||||
|
set.location( ) = input[ 0 ].location( );
|
||||||
|
if ( input.size( ) > 2 ) {
|
||||||
|
auto expr( parseExpression( set , input[ 2 ] ) );
|
||||||
|
if ( expr ) {
|
||||||
|
set.setExpression( std::move( expr ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseExpression(
|
||||||
|
A_Node& parent ,
|
||||||
|
T_SRDToken const& token ) noexcept
|
||||||
|
{
|
||||||
|
if ( token.isNumeric( ) ) {
|
||||||
|
return NewOwned< T_ConstantExprNode >( parent , token );
|
||||||
|
}
|
||||||
|
if ( token.type( ) == E_SRDTokenType::WORD || token.type( ) == E_SRDTokenType::VAR ) {
|
||||||
|
return NewOwned< T_IdentifierExprNode >( parent , token );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( token.type( ) == E_SRDTokenType::LIST && !token.list( ).empty( ) ) {
|
||||||
|
return parseOperation( parent , token.list( ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
errors.addNew( "invalid expression" , token.location( ) );
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseOperation(
|
||||||
|
A_Node& parent ,
|
||||||
|
T_SRDList const& opList ) noexcept
|
||||||
|
{
|
||||||
|
T_SRDToken const& opId( opList[ 0 ] );
|
||||||
|
if ( opId.type( ) != E_SRDTokenType::WORD ) {
|
||||||
|
errors.addNew( "operator expected" , opId.location( ) );
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( binOpMap.contains( opId.stringValue( ) ) ) {
|
||||||
|
return parseBinOp( parent , opList ,
|
||||||
|
*binOpMap.get( opId.stringValue( ) ) );
|
||||||
|
}
|
||||||
|
if ( unaryOpMap.contains( opId.stringValue( ) ) ) {
|
||||||
|
return parseUnaryOp( parent , opList ,
|
||||||
|
*unaryOpMap.get( opId.stringValue( ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
errors.addNew( "unknown operator" , opId.location( ) );
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseBinOp(
|
||||||
|
A_Node& parent ,
|
||||||
|
T_SRDList const& opList ,
|
||||||
|
T_BinaryOperatorNode::E_Operator op ) noexcept
|
||||||
|
{
|
||||||
|
if ( opList.size( ) < 3 ) {
|
||||||
|
errors.addNew( "not enough arguments" , opList[ 0 ].location( ) );
|
||||||
|
} else if ( opList.size( ) > 3 ) {
|
||||||
|
errors.addNew( "too many arguments" , opList[ 3 ].location( ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
T_OwnPtr< T_BinaryOperatorNode > opNode{
|
||||||
|
NewOwned< T_BinaryOperatorNode >( parent , op ) };
|
||||||
|
opNode->location( ) = opList[ 0 ].location( );
|
||||||
|
|
||||||
|
if ( opList.size( ) > 1 ) {
|
||||||
|
auto left{ parseExpression( *opNode , opList[ 1 ] ) };
|
||||||
|
if ( left ) {
|
||||||
|
opNode->setLeft( std::move( left ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( opList.size( ) > 2 ) {
|
||||||
|
auto right{ parseExpression( *opNode , opList[ 2 ] ) };
|
||||||
|
if ( right ) {
|
||||||
|
opNode->setRight( std::move( right ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return opNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
T_OwnPtr< A_ExpressionNode > T_ParserImpl_::parseUnaryOp(
|
||||||
|
A_Node& parent ,
|
||||||
|
T_SRDList const& opList ,
|
||||||
|
T_UnaryOperatorNode::E_Operator op ) noexcept
|
||||||
|
{
|
||||||
|
if ( opList.size( ) < 2 ) {
|
||||||
|
errors.addNew( "not enough arguments" , opList[ 0 ].location( ) );
|
||||||
|
} else if ( opList.size( ) > 2 ) {
|
||||||
|
errors.addNew( "too many arguments" , opList[ 2 ].location( ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
T_OwnPtr< T_UnaryOperatorNode > opNode{
|
||||||
|
NewOwned< T_UnaryOperatorNode >( parent , op ) };
|
||||||
|
opNode->location( ) = opList[ 0 ].location( );
|
||||||
|
|
||||||
|
if ( opList.size( ) > 1 ) {
|
||||||
|
auto argument{ parseExpression( *opNode , opList[ 1 ] ) };
|
||||||
|
if ( argument ) {
|
||||||
|
opNode->setArgument( std::move( argument ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return opNode;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
184
opast.hh
184
opast.hh
|
@ -27,12 +27,20 @@ class A_Node
|
||||||
OP_PROFILE , // Profiling block
|
OP_PROFILE , // Profiling block
|
||||||
OP_PROGRAM , // Shader program declaration
|
OP_PROGRAM , // Shader program declaration
|
||||||
OP_SET , // Set instruction
|
OP_SET , // Set instruction
|
||||||
|
// Unary operators
|
||||||
|
EXPR_NEG , EXPR_INV , EXPR_NOT ,
|
||||||
|
EXPR_SIN , EXPR_COS , EXPR_TAN ,
|
||||||
|
EXPR_SQRT , EXPR_EXP , EXPR_LN ,
|
||||||
|
// Binary operators
|
||||||
|
EXPR_ADD , EXPR_SUB ,
|
||||||
|
EXPR_MUL , EXPR_DIV ,
|
||||||
|
EXPR_POW ,
|
||||||
|
// Binary operators - comparisons
|
||||||
|
EXPR_CMP_EQ , EXPR_CMP_NE ,
|
||||||
|
EXPR_CMP_GT , EXPR_CMP_GE ,
|
||||||
|
EXPR_CMP_LT , EXPR_CMP_LE ,
|
||||||
//
|
//
|
||||||
EXPR_ADD , // Binary ops: add
|
EXPR_ID , // Variable access
|
||||||
EXPR_MUL , // Binary ops: mul
|
|
||||||
EXPR_SUB , // Binary ops: sub
|
|
||||||
EXPR_DIV , // Binary ops: div
|
|
||||||
EXPR_VAR , // Variable access
|
|
||||||
EXPR_CONST , // Numeric constant
|
EXPR_CONST , // Numeric constant
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,6 +72,7 @@ class A_Node
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Base class for instruction nodes
|
||||||
class A_InstructionNode : public A_Node
|
class A_InstructionNode : public A_Node
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -205,6 +214,18 @@ class T_FuncNode : public A_FuncNode
|
||||||
T_SRDToken const& token ) noexcept;
|
T_SRDToken const& token ) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Base class for expressions
|
||||||
|
class A_ExpressionNode : public A_Node
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
A_ExpressionNode( E_Type type ,
|
||||||
|
A_Node& parent ) noexcept
|
||||||
|
: A_Node( type , &parent )
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
/*============================================================================*/
|
/*============================================================================*/
|
||||||
|
|
||||||
// Pipeline declaration instruction
|
// Pipeline declaration instruction
|
||||||
|
@ -276,6 +297,159 @@ class T_ProgramInstrNode : public A_InstructionNode
|
||||||
T_SRDToken const& pathToken ) noexcept;
|
T_SRDToken const& pathToken ) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Setting a global variable
|
||||||
|
class T_SetInstrNode : public A_InstructionNode
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T_String id_;
|
||||||
|
T_SRDLocation idLocation_;
|
||||||
|
T_OwnPtr< A_ExpressionNode > expression_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T_SetInstrNode( T_InstrListNode& parent ,
|
||||||
|
T_SRDToken const& idToken ) noexcept;
|
||||||
|
|
||||||
|
T_String const& identifier( ) const noexcept
|
||||||
|
{ return id_; }
|
||||||
|
T_SRDLocation const& idLocation( ) const noexcept
|
||||||
|
{ return idLocation_; }
|
||||||
|
|
||||||
|
void setExpression( T_OwnPtr< A_ExpressionNode > expression ) noexcept
|
||||||
|
{ expression_ = std::move( expression ); }
|
||||||
|
|
||||||
|
bool hasExpression( ) const noexcept
|
||||||
|
{ return bool( expression_ ); }
|
||||||
|
A_ExpressionNode const& expression( ) const noexcept
|
||||||
|
{ return *expression_; }
|
||||||
|
A_ExpressionNode& expression( ) noexcept
|
||||||
|
{ return *expression_; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*============================================================================*/
|
||||||
|
|
||||||
|
// A constant value
|
||||||
|
class T_ConstantExprNode : public A_ExpressionNode
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool wasFloat_;
|
||||||
|
double vFloat_;
|
||||||
|
int64_t vInt_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T_ConstantExprNode( A_Node& parent ,
|
||||||
|
T_SRDToken const& token ) noexcept;
|
||||||
|
|
||||||
|
T_ConstantExprNode( A_Node& parent ,
|
||||||
|
int64_t value ) noexcept;
|
||||||
|
T_ConstantExprNode( A_Node& parent ,
|
||||||
|
double value ) noexcept;
|
||||||
|
|
||||||
|
bool wasFloat( ) const noexcept
|
||||||
|
{ return wasFloat_; }
|
||||||
|
double floatValue( ) const noexcept
|
||||||
|
{ return vFloat_; }
|
||||||
|
int64_t intValue( ) const noexcept
|
||||||
|
{ return vInt_; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// An identifier used in an expression
|
||||||
|
class T_IdentifierExprNode : public A_ExpressionNode
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T_String id_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T_IdentifierExprNode( A_Node& parent ,
|
||||||
|
T_SRDToken const& token ) noexcept;
|
||||||
|
T_IdentifierExprNode( A_Node& parent ,
|
||||||
|
T_String const& id ) noexcept;
|
||||||
|
|
||||||
|
T_String const& id( ) const noexcept
|
||||||
|
{ return id_; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// A unary operator
|
||||||
|
class T_UnaryOperatorNode : public A_ExpressionNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum E_Operator {
|
||||||
|
NEG , INV , NOT ,
|
||||||
|
SIN , COS , TAN ,
|
||||||
|
SQRT , EXP , LN
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
E_Operator op_;
|
||||||
|
T_OwnPtr< A_ExpressionNode > argument_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T_UnaryOperatorNode(
|
||||||
|
A_Node& parent ,
|
||||||
|
const E_Operator op ) noexcept;
|
||||||
|
|
||||||
|
E_Operator op( ) const noexcept
|
||||||
|
{ return op_; }
|
||||||
|
|
||||||
|
void setArgument( T_OwnPtr< A_ExpressionNode > argument ) noexcept
|
||||||
|
{ argument_ = std::move( argument ); }
|
||||||
|
|
||||||
|
bool hasArgument( ) const noexcept
|
||||||
|
{ return bool( argument_ ); }
|
||||||
|
|
||||||
|
A_ExpressionNode const& argument( ) const noexcept
|
||||||
|
{ return *argument_; }
|
||||||
|
A_ExpressionNode& argument( ) noexcept
|
||||||
|
{ return *argument_; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// A binary operator
|
||||||
|
class T_BinaryOperatorNode : public A_ExpressionNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum E_Operator {
|
||||||
|
ADD , SUB ,
|
||||||
|
MUL , DIV ,
|
||||||
|
POW ,
|
||||||
|
|
||||||
|
CMP_EQ , CMP_NE ,
|
||||||
|
CMP_GT , CMP_GE ,
|
||||||
|
CMP_LT , CMP_LE ,
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
E_Operator op_;
|
||||||
|
T_OwnPtr< A_ExpressionNode > left_;
|
||||||
|
T_OwnPtr< A_ExpressionNode > right_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T_BinaryOperatorNode(
|
||||||
|
A_Node& parent ,
|
||||||
|
const E_Operator op ) noexcept;
|
||||||
|
|
||||||
|
E_Operator op( ) const noexcept
|
||||||
|
{ return op_; }
|
||||||
|
|
||||||
|
void setLeft( T_OwnPtr< A_ExpressionNode > left ) noexcept
|
||||||
|
{ left_ = std::move( left ); }
|
||||||
|
void setRight( T_OwnPtr< A_ExpressionNode > right ) noexcept
|
||||||
|
{ right_ = std::move( right ); }
|
||||||
|
|
||||||
|
bool hasLeft( ) const noexcept
|
||||||
|
{ return bool( left_ ); }
|
||||||
|
bool hasRight( ) const noexcept
|
||||||
|
{ return bool( right_ ); }
|
||||||
|
|
||||||
|
A_ExpressionNode const& left( ) const noexcept
|
||||||
|
{ return *left_; }
|
||||||
|
A_ExpressionNode& left( ) noexcept
|
||||||
|
{ return *left_; }
|
||||||
|
|
||||||
|
A_ExpressionNode const& right( ) const noexcept
|
||||||
|
{ return *right_; }
|
||||||
|
A_ExpressionNode& right( ) noexcept
|
||||||
|
{ return *right_; }
|
||||||
|
};
|
||||||
|
|
||||||
/*============================================================================*/
|
/*============================================================================*/
|
||||||
|
|
||||||
class T_Parser : public A_PrivateImplementation
|
class T_Parser : public A_PrivateImplementation
|
||||||
|
|
Loading…
Reference in a new issue