diff --git a/opast.cc b/opast.cc index 92a388a..22af1ef 100644 --- a/opast.cc +++ b/opast.cc @@ -1,3 +1,4 @@ +#include "externals.hh" #include "opast.hh" using namespace ebcl; @@ -190,6 +191,19 @@ T_SetInstrNode::T_SetInstrNode( { } +/*= T_TextureInstrNode =======================================================*/ + +T_TextureInstrNode::T_TextureInstrNode( + T_InstrListNode& parent , + T_SRDToken const& idToken , + const E_TexType type ) noexcept + : A_InstructionNode( OP_PROGRAM , parent ) , + id_( idToken.stringValue( ) ) , + idLocation_( idToken.location( ) ) , + type_( type ) +{ } + + /*= T_ConstantExprNode =======================================================*/ T_ConstantExprNode::T_ConstantExprNode( @@ -293,6 +307,7 @@ struct T_ParserImpl_ PROFILE , PROGRAM , SET , + TEXTURE , }; const T_KeyValueTable< T_String , E_InstrType > instrMap{ ([]() { @@ -306,6 +321,7 @@ struct T_ParserImpl_ add( "profiling" , E_InstrType::PROFILE ); add( "program" , E_InstrType::PROGRAM ); add( "set" , E_InstrType::SET ); + add( "texture" , E_InstrType::TEXTURE ); return temp; })( ) }; @@ -330,6 +346,23 @@ struct T_ParserImpl_ return temp; })( ) }; + const T_KeyValueTable< T_String , E_TexType > texTypeMap{ ([]() { + T_KeyValueTable< T_String , E_TexType > temp{ 64 , 16 , 16 }; + const auto add{ [&temp]( char const* name , + const E_TexType it ) { + temp.add( T_String::Pooled( name ) , it ); + } }; + + add( "rgba-nu8" , E_TexType::RGBA8 ); + add( "rgba-f16" , E_TexType::RGBA16F ); + add( "rgb-nu8" , E_TexType::RGB8 ); + add( "rgb-f16" , E_TexType::RGB16F ); + add( "r-nu8" , E_TexType::R8 ); + add( "r-f16" , E_TexType::R16F ); + + 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 , @@ -394,6 +427,9 @@ struct T_ParserImpl_ void parseSetInstruction( T_InstrListNode& instructions , T_SRDList const& input ) noexcept; + void parseTextureInstruction( + T_InstrListNode& instructions , + T_SRDList const& input ) noexcept; // --------------------------------------------------------------------- @@ -531,23 +567,16 @@ void T_ParserImpl_::parseInstructions( continue; } +#define M_CASE_( NAME , FNAME ) case E_InstrType::NAME: parse##FNAME##Instruction( instructions , ilist ); break switch ( *instrMap.get( iword ) ) { - case E_InstrType::IF: - parseIfInstruction( instructions , ilist ); - break; - case E_InstrType::PIPELINE: - parsePipelineInstruction( instructions , ilist ); - break; - case E_InstrType::PROFILE: - parseProfileInstruction( instructions , ilist ); - break; - case E_InstrType::PROGRAM: - parseProgramInstruction( instructions , ilist ); - break; - case E_InstrType::SET: - parseSetInstruction( instructions , ilist ); - break; + M_CASE_( IF , If ); + M_CASE_( PIPELINE , Pipeline ); + M_CASE_( PROFILE , Profile ); + M_CASE_( PROGRAM , Program ); + M_CASE_( SET , Set ); + M_CASE_( TEXTURE , Texture ); } +#undef M_CASE_ } } @@ -741,6 +770,47 @@ void T_ParserImpl_::parseSetInstruction( /*----------------------------------------------------------------------------*/ +void T_ParserImpl_::parseTextureInstruction( + T_InstrListNode& instructions , + T_SRDList const& input ) noexcept +{ + if ( input.size( ) < 2 || input[ 1 ].type( ) != E_SRDTokenType::WORD ) { + errors.addNew( "texture identifier expected" , + ( input.size( ) < 2 ? input[ 0 ] : input[ 1 ] ).location( ) ); + return; + } + if ( input.size( ) < 3 || input[ 2 ].type( ) != E_SRDTokenType::WORD ) { + errors.addNew( "texture type expected" , + ( input.size( ) < 3 ? input[ 0 ] : input[ 2 ] ).location( ) ); + return; + } + + auto const* const ttt( texTypeMap.get( input[ 2 ].stringValue( ) ) ); + if ( !ttt ) { + errors.addNew( "invalid texture type" , + ( input.size( ) < 3 ? input[ 0 ] : input[ 2 ] ).location( ) ); + } + const auto tt( ttt ? *ttt : E_TexType::RGB8 ); + + auto& instr{ instructions.add< T_TextureInstrNode >( input[ 1 ] , tt ) }; + instr.location( ) = input[ 0 ].location( ); + if ( input.size( ) > 4 ) { + instr.setWidth( parseExpression( instr , input[ 3 ] ) ); + } else { + errors.addNew( "width expected" , input[ 0 ].location( ) ); + } + if ( input.size( ) > 4 ) { + instr.setHeight( parseExpression( instr , input[ 3 ] ) ); + } else { + errors.addNew( "height expected" , input[ 0 ].location( ) ); + } + if ( input.size( ) > 5 ) { + errors.addNew( "too many arguments" , input[ 5 ].location( ) ); + } +} + +/*----------------------------------------------------------------------------*/ + P_ExpressionNode T_ParserImpl_::parseExpression( A_Node& parent , T_SRDToken const& token ) noexcept diff --git a/opast.hh b/opast.hh index 59002a3..28cbdc4 100644 --- a/opast.hh +++ b/opast.hh @@ -1,8 +1,8 @@ #pragma once -//#ifndef REAL_BUILD +#ifndef REAL_BUILD # include "externals.hh" -//#endif - +#endif +#include "texture.hh" #include @@ -28,6 +28,7 @@ class A_Node OP_PROFILE , // Profiling block OP_PROGRAM , // Shader program declaration OP_SET , // Set instruction + OP_TEXTURE , // Define texture // Unary operators EXPR_NEG , EXPR_INV , EXPR_NOT , EXPR_SIN , EXPR_COS , EXPR_TAN , @@ -248,9 +249,7 @@ class T_CondInstrNode : public A_InstructionNode { expression_ = std::move( expression ); } bool hasExpression( ) const noexcept { return bool( expression_ ); } - A_ExpressionNode& expression( ) noexcept - { return *expression_; } - A_ExpressionNode const& expression( ) const noexcept + A_ExpressionNode& expression( ) const noexcept { return *expression_; } void setCase( const int64_t value , @@ -268,18 +267,14 @@ class T_CondInstrNode : public A_InstructionNode { 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 + T_InstrListNode& 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 + T_InstrListNode& defaultCase( ) const noexcept { return *defaultCase_; } }; @@ -371,15 +366,43 @@ class T_SetInstrNode : public A_InstructionNode void setExpression( P_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 + A_ExpressionNode& expression( ) const noexcept { return *expression_; } }; +// 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_; } +}; + /*============================================================================*/ // A constant value