2017-11-06 10:15:38 +01:00
|
|
|
#pragma once
|
2017-11-06 18:15:56 +01:00
|
|
|
#ifndef REAL_BUILD
|
2017-11-06 10:15:38 +01:00
|
|
|
# include "externals.hh"
|
2017-11-06 18:15:56 +01:00
|
|
|
#endif
|
|
|
|
#include "texture.hh"
|
2017-11-06 10:15:38 +01:00
|
|
|
#include <ebcl/SRDData.hh>
|
|
|
|
|
|
|
|
|
|
|
|
namespace opast {
|
|
|
|
|
|
|
|
using namespace ebcl;
|
|
|
|
|
|
|
|
class T_RootNode;
|
|
|
|
|
|
|
|
class A_Node
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum E_Type {
|
2017-11-06 14:06:21 +01:00
|
|
|
ROOT , // Root node
|
|
|
|
ILIST , // Instruction list
|
2017-11-06 10:15:38 +01:00
|
|
|
//
|
2017-11-06 14:06:21 +01:00
|
|
|
DECL_INIT , // Initialisation block
|
|
|
|
DECL_FRAME , // Frame block
|
|
|
|
DECL_FN , // Function
|
2017-11-06 10:15:38 +01:00
|
|
|
//
|
2017-11-06 17:09:05 +01:00
|
|
|
OP_COND , // Conditional instruction
|
2017-11-06 14:06:21 +01:00
|
|
|
OP_PIPELINE , // Shader pipeline declaration
|
|
|
|
OP_PROFILE , // Profiling block
|
|
|
|
OP_PROGRAM , // Shader program declaration
|
|
|
|
OP_SET , // Set instruction
|
2017-11-06 18:15:56 +01:00
|
|
|
OP_TEXTURE , // Define texture
|
2017-11-06 16:38:04 +01:00
|
|
|
// 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 ,
|
2017-11-06 10:15:38 +01:00
|
|
|
//
|
2017-11-06 16:38:04 +01:00
|
|
|
EXPR_ID , // Variable access
|
2017-11-06 14:06:21 +01:00
|
|
|
EXPR_CONST , // Numeric constant
|
2017-11-06 10:15:38 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
const E_Type type_;
|
|
|
|
A_Node* const parent_;
|
|
|
|
T_SRDLocation location_;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
explicit A_Node( const E_Type type ,
|
|
|
|
A_Node* const parent ) noexcept;
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual ~A_Node( ) = 0;
|
|
|
|
|
|
|
|
E_Type type( ) const noexcept
|
|
|
|
{ return type_; }
|
|
|
|
|
|
|
|
T_SRDLocation& location( ) noexcept
|
|
|
|
{ return location_; }
|
|
|
|
T_SRDLocation const& location( ) const noexcept
|
|
|
|
{ return location_; }
|
|
|
|
|
|
|
|
A_Node& parent( ) const noexcept
|
|
|
|
{ assert( parent_ ); return *parent_; }
|
|
|
|
|
|
|
|
T_RootNode& root( ) const noexcept;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
2017-11-06 16:38:04 +01:00
|
|
|
// Base class for instruction nodes
|
2017-11-06 14:06:21 +01:00
|
|
|
class A_InstructionNode : public A_Node
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
A_InstructionNode( E_Type type ,
|
|
|
|
A_Node& parent ) noexcept
|
|
|
|
: A_Node( type , &parent )
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Nodes that store lists of instructions
|
|
|
|
class T_InstrListNode : public A_Node
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_Array< T_OwnPtr< A_InstructionNode > > instructions_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_InstrListNode( A_Node& parent ) noexcept;
|
|
|
|
|
|
|
|
template<
|
|
|
|
typename IType ,
|
|
|
|
typename... ArgTypes
|
|
|
|
> IType& add( ArgTypes&&... args );
|
|
|
|
};
|
|
|
|
|
|
|
|
template<
|
|
|
|
typename IType ,
|
|
|
|
typename... ArgTypes
|
|
|
|
> inline IType& T_InstrListNode::add(
|
|
|
|
ArgTypes&&... args )
|
|
|
|
{
|
|
|
|
instructions_.add( NewOwned< IType >( *this ,
|
|
|
|
std::forward< ArgTypes >( args ) ... ) );
|
|
|
|
return (IType&) *instructions_.last( );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
2017-11-06 10:15:38 +01:00
|
|
|
// Function-like nodes
|
|
|
|
class A_FuncNode : public A_Node
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String name_;
|
2017-11-06 14:06:21 +01:00
|
|
|
T_InstrListNode instructions_;
|
2017-11-06 10:15:38 +01:00
|
|
|
|
|
|
|
protected:
|
|
|
|
// For init or frame entry points.
|
|
|
|
// isInit = true => init entry point
|
|
|
|
// isInit = false => frame entry point
|
|
|
|
explicit A_FuncNode( bool isInit ,
|
|
|
|
T_RootNode* const parent ) noexcept;
|
|
|
|
|
|
|
|
// For normal functions
|
|
|
|
explicit A_FuncNode( T_String const& name ,
|
|
|
|
T_RootNode* const parent ) noexcept;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_String const& name( ) const noexcept
|
|
|
|
{ return name_; }
|
2017-11-06 14:06:21 +01:00
|
|
|
|
|
|
|
T_InstrListNode& instructions( ) noexcept
|
|
|
|
{ return instructions_; }
|
|
|
|
T_InstrListNode const& instructions( ) const noexcept
|
|
|
|
{ return instructions_; }
|
2017-11-06 10:15:38 +01:00
|
|
|
};
|
2017-11-06 17:09:05 +01:00
|
|
|
using P_InstrListNode = T_OwnPtr< T_InstrListNode >;
|
2017-11-06 10:15:38 +01:00
|
|
|
|
|
|
|
// Root node, keeps track of the whole tree and related data (function table,
|
|
|
|
// assets...)
|
|
|
|
class T_RootNode : public A_Node
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_ObjectTable< T_String , T_OwnPtr< A_FuncNode > > functions_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_RootNode( ) noexcept;
|
|
|
|
|
2017-11-06 14:06:21 +01:00
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
2017-11-06 10:15:38 +01:00
|
|
|
// Return type for addFunction. We'll always return a reference to a
|
|
|
|
// function node (which may or may not be the same as the initial one,
|
|
|
|
// if there were duplicates), and we'll return the location of the
|
|
|
|
// initial function in the case of a duplicate.
|
|
|
|
struct T_AddFunctionResult
|
|
|
|
{
|
|
|
|
A_FuncNode& function;
|
|
|
|
T_Optional< T_SRDLocation > dupLocation;
|
|
|
|
|
|
|
|
T_AddFunctionResult( A_FuncNode& function ) noexcept
|
|
|
|
: function{ function } , dupLocation{}
|
|
|
|
{}
|
|
|
|
|
|
|
|
T_AddFunctionResult( A_FuncNode& function ,
|
|
|
|
T_SRDLocation const& dupLocation ) noexcept
|
|
|
|
: function{ function } , dupLocation{ dupLocation }
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Attempts to add a function. If the function is already present in
|
|
|
|
// the table, the result will be set up with the previous declaration's
|
|
|
|
// location, and the specified function will not be modified (a duplicate
|
|
|
|
// entry will be added to the table instead).
|
|
|
|
T_AddFunctionResult addFunction(
|
|
|
|
T_OwnPtr< A_FuncNode >& function ) noexcept;
|
2017-11-06 14:06:21 +01:00
|
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
|
|
|
bool hasFunction( T_String const& name ) noexcept
|
|
|
|
{ return functions_.contains( name ); }
|
|
|
|
bool hasInit( ) noexcept
|
|
|
|
{ return hasFunction( "*init*" ); }
|
|
|
|
bool hasFrame( ) noexcept
|
|
|
|
{ return hasFunction( "*frame*" ); }
|
2017-11-06 10:15:38 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
// Init & frame functions
|
|
|
|
class T_SpecialFuncNode : public A_FuncNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
T_SpecialFuncNode(
|
|
|
|
bool isInit ,
|
|
|
|
T_RootNode& parent ) noexcept;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Normal functions
|
|
|
|
class T_FuncNode : public A_FuncNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_AutoArray< T_String , 8 > argNames_;
|
|
|
|
T_AutoArray< T_SRDLocation , 8 > argLocations_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_FuncNode( T_String const& name ,
|
|
|
|
T_RootNode& parent ) noexcept;
|
|
|
|
|
|
|
|
// Add an argument. If the argument is a duplicate, return the location
|
|
|
|
// of the initial argument.
|
|
|
|
T_Optional< T_SRDLocation > addArgument(
|
|
|
|
T_SRDToken const& token ) noexcept;
|
|
|
|
};
|
|
|
|
|
2017-11-06 16:38:04 +01:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
// Base class for expressions
|
|
|
|
class A_ExpressionNode : public A_Node
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
A_ExpressionNode( E_Type type ,
|
|
|
|
A_Node& parent ) noexcept
|
|
|
|
: A_Node( type , &parent )
|
|
|
|
{ }
|
|
|
|
};
|
2017-11-06 17:09:05 +01:00
|
|
|
using P_ExpressionNode = T_OwnPtr< A_ExpressionNode >;
|
2017-11-06 16:38:04 +01:00
|
|
|
|
2017-11-06 14:06:21 +01:00
|
|
|
/*============================================================================*/
|
|
|
|
|
2017-11-06 17:09:05 +01:00
|
|
|
// 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_ ); }
|
2017-11-06 18:15:56 +01:00
|
|
|
A_ExpressionNode& expression( ) const noexcept
|
2017-11-06 17:09:05 +01:00
|
|
|
{ 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 ); }
|
2017-11-06 18:15:56 +01:00
|
|
|
T_InstrListNode& getCase( const int64_t value ) const noexcept
|
2017-11-06 17:09:05 +01:00
|
|
|
{ return **cases_.get( value ); }
|
|
|
|
|
|
|
|
void setDefaultCase( P_InstrListNode defaultCase ) noexcept
|
|
|
|
{ defaultCase_ = std::move( defaultCase ); }
|
|
|
|
bool hasDefaultCase( ) const noexcept
|
|
|
|
{ return bool( defaultCase_ ); }
|
2017-11-06 18:15:56 +01:00
|
|
|
T_InstrListNode& defaultCase( ) const noexcept
|
2017-11-06 17:09:05 +01:00
|
|
|
{ return *defaultCase_; }
|
|
|
|
};
|
|
|
|
|
2017-11-06 14:06:21 +01:00
|
|
|
// Pipeline declaration instruction
|
|
|
|
class T_PipelineInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String id_;
|
|
|
|
T_SRDLocation idLocation_;
|
|
|
|
T_StaticArray< T_String , 6 > pids_;
|
|
|
|
T_StaticArray< T_SRDLocation , 6 > pidLocations_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_PipelineInstrNode(
|
|
|
|
T_InstrListNode& parent ,
|
|
|
|
T_SRDToken const& idToken ) noexcept;
|
|
|
|
explicit T_PipelineInstrNode(
|
|
|
|
T_InstrListNode& parent ) noexcept;
|
|
|
|
|
|
|
|
// Add a program identifier. The token is assumed to be a valid word,
|
|
|
|
// and the list of programs is assumed not to be full. If the identifer
|
|
|
|
// is already in the pipeline's list, the location of the first
|
|
|
|
// occurrence will be returned.
|
|
|
|
T_Optional< T_SRDLocation > addProgram(
|
|
|
|
T_SRDToken const& pidToken ) noexcept;
|
|
|
|
|
|
|
|
uint32_t size( ) const noexcept
|
|
|
|
{ return pids_.size( ); }
|
|
|
|
|
|
|
|
T_String const& program( const uint32_t index ) const noexcept
|
|
|
|
{ return pids_[ index ]; }
|
|
|
|
T_SRDLocation const& pLocation( const uint32_t index ) const noexcept
|
|
|
|
{ return pidLocations_[ index ]; }
|
|
|
|
};
|
|
|
|
|
|
|
|
// Profiling instruction
|
|
|
|
class T_ProfileInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String text_;
|
|
|
|
T_InstrListNode instructions_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_ProfileInstrNode(
|
|
|
|
T_InstrListNode& parent ,
|
|
|
|
T_String const& text ) noexcept;
|
|
|
|
|
|
|
|
T_String const& text( ) const
|
|
|
|
{ return text_; }
|
|
|
|
|
|
|
|
T_InstrListNode& instructions( ) noexcept
|
|
|
|
{ return instructions_; }
|
|
|
|
T_InstrListNode const& instructions( ) const noexcept
|
|
|
|
{ return instructions_; }
|
|
|
|
};
|
|
|
|
|
|
|
|
// Program loader instruction
|
|
|
|
class T_ProgramInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String id_;
|
|
|
|
T_SRDLocation idLocation_;
|
|
|
|
T_String path_;
|
|
|
|
T_SRDLocation pathLocation_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_ProgramInstrNode(
|
|
|
|
T_InstrListNode& parent ,
|
|
|
|
T_SRDToken const& idToken ,
|
|
|
|
T_SRDToken const& pathToken ) noexcept;
|
|
|
|
};
|
|
|
|
|
2017-11-06 16:38:04 +01:00
|
|
|
// Setting a global variable
|
|
|
|
class T_SetInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String id_;
|
|
|
|
T_SRDLocation idLocation_;
|
2017-11-06 17:09:05 +01:00
|
|
|
P_ExpressionNode expression_;
|
2017-11-06 16:38:04 +01:00
|
|
|
|
|
|
|
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_; }
|
|
|
|
|
2017-11-06 17:09:05 +01:00
|
|
|
void setExpression( P_ExpressionNode expression ) noexcept
|
2017-11-06 16:38:04 +01:00
|
|
|
{ expression_ = std::move( expression ); }
|
|
|
|
bool hasExpression( ) const noexcept
|
|
|
|
{ return bool( expression_ ); }
|
2017-11-06 18:15:56 +01:00
|
|
|
A_ExpressionNode& expression( ) const noexcept
|
2017-11-06 16:38:04 +01:00
|
|
|
{ return *expression_; }
|
|
|
|
};
|
|
|
|
|
2017-11-06 18:15:56 +01:00
|
|
|
// Texture definition
|
|
|
|
class T_TextureInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String id_;
|
|
|
|
T_SRDLocation idLocation_;
|
|
|
|
E_TexType type_;
|
|
|
|
P_ExpressionNode width_;
|
|
|
|
P_ExpressionNode height_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_TextureInstrNode(
|
|
|
|
T_InstrListNode& parent ,
|
|
|
|
T_SRDToken const& id ,
|
|
|
|
E_TexType type ) noexcept;
|
|
|
|
|
|
|
|
void setWidth( P_ExpressionNode width ) noexcept
|
|
|
|
{ width_ = std::move( width ); }
|
|
|
|
bool hasWidth( ) const noexcept
|
|
|
|
{ return bool( width_ ); }
|
|
|
|
A_ExpressionNode& width( ) const noexcept
|
|
|
|
{ return *width_; }
|
|
|
|
|
|
|
|
void setHeight( P_ExpressionNode height ) noexcept
|
|
|
|
{ height_ = std::move( height ); }
|
|
|
|
bool hasHeight( ) const noexcept
|
|
|
|
{ return bool( height_ ); }
|
|
|
|
A_ExpressionNode& height( ) const noexcept
|
|
|
|
{ return *height_; }
|
|
|
|
};
|
|
|
|
|
2017-11-06 16:38:04 +01:00
|
|
|
/*============================================================================*/
|
|
|
|
|
|
|
|
// 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_;
|
2017-11-06 17:09:05 +01:00
|
|
|
P_ExpressionNode argument_;
|
2017-11-06 16:38:04 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_UnaryOperatorNode(
|
|
|
|
A_Node& parent ,
|
|
|
|
const E_Operator op ) noexcept;
|
|
|
|
|
|
|
|
E_Operator op( ) const noexcept
|
|
|
|
{ return op_; }
|
|
|
|
|
2017-11-06 17:09:05 +01:00
|
|
|
void setArgument( P_ExpressionNode argument ) noexcept
|
2017-11-06 16:38:04 +01:00
|
|
|
{ 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_;
|
2017-11-06 17:09:05 +01:00
|
|
|
P_ExpressionNode left_;
|
|
|
|
P_ExpressionNode right_;
|
2017-11-06 16:38:04 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_BinaryOperatorNode(
|
|
|
|
A_Node& parent ,
|
|
|
|
const E_Operator op ) noexcept;
|
|
|
|
|
|
|
|
E_Operator op( ) const noexcept
|
|
|
|
{ return op_; }
|
|
|
|
|
2017-11-06 17:09:05 +01:00
|
|
|
void setLeft( P_ExpressionNode left ) noexcept
|
2017-11-06 16:38:04 +01:00
|
|
|
{ left_ = std::move( left ); }
|
2017-11-06 17:09:05 +01:00
|
|
|
void setRight( P_ExpressionNode right ) noexcept
|
2017-11-06 16:38:04 +01:00
|
|
|
{ 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_; }
|
|
|
|
};
|
|
|
|
|
2017-11-06 14:06:21 +01:00
|
|
|
/*============================================================================*/
|
2017-11-06 10:15:38 +01:00
|
|
|
|
|
|
|
class T_Parser : public A_PrivateImplementation
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_Array< T_SRDError > errors_;
|
|
|
|
T_OwnPtr< T_RootNode > rootNode_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_Parser( ) noexcept;
|
|
|
|
|
|
|
|
bool parse( T_SRDList const& input ) noexcept;
|
|
|
|
|
|
|
|
T_Array< T_SRDError > const& errors( ) const noexcept
|
|
|
|
{ return errors_; }
|
|
|
|
T_OwnPtr< T_RootNode > result( ) noexcept
|
|
|
|
{ return std::move( rootNode_ ); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace opast
|