diff --git a/.vim.local/syntax/demo-srd.vim b/.vim.local/syntax/demo-srd.vim index 048d734..a60071f 100644 --- a/.vim.local/syntax/demo-srd.vim +++ b/.vim.local/syntax/demo-srd.vim @@ -36,7 +36,7 @@ syn keyword srdTodo contained TODO TODO: FIXME FIXME: XXX XXX: " ------------------------------------------------------------------------------ " Keywords -syn keyword srdKWFlow if set call fn init frame +syn keyword srdKWFlow if set call fn init frame locals syn keyword srdKWDefAsset program pipeline input framebuffer texture sampler diff --git a/demo.srd b/demo.srd index 5a5d4c7..c2a6524 100644 --- a/demo.srd +++ b/demo.srd @@ -287,9 +287,10 @@ ) (fn bloom-downsample (target level) - (locals w h) - (set w (div $vp-width (pow 2 $level))) - (set h (div $vp-height (pow 2 $level))) + (locals m w h) + (set m (inv (pow 2 $level))) + (set w (mul $vp-width $m)) + (set h (mul $vp-height $m)) (use-pipeline pl-bloom-downsample) (use-framebuffer target) diff --git a/opast.cc b/opast.cc index a26027f..50f0678 100644 --- a/opast.cc +++ b/opast.cc @@ -101,7 +101,7 @@ A_Node* opast::ASTVisitorBrowser( // case A_Node::OP_PROGRAM: case A_Node::OP_PIPELINE: case A_Node::OP_INPUT: case A_Node::OP_FULLSCREEN: - case A_Node::OP_ODBG: + case A_Node::OP_ODBG: case A_Node::OP_LOCALS: // case A_Node::OP_USE_FRAMEBUFFER: case A_Node::OP_USE_PIPELINE: case A_Node::OP_USE_PROGRAM: case A_Node::OP_USE_TEXTURE: @@ -174,7 +174,7 @@ A_Node* opast::ASTVisitorBrowser( } c --; } - return n.lods( ); + return c == 0 ? n.lods( ) : nullptr; } // Framebuffer definition; may have LOD expressions @@ -191,7 +191,7 @@ A_Node* opast::ASTVisitorBrowser( c --; } } - if ( c == 0 && n.depthAttachmentLOD( ) ) { + if ( c == 0 && n.hasDepthAttachment( ) ) { return n.depthAttachmentLOD( ); } break; @@ -497,3 +497,16 @@ T_Optional< T_SRDLocation > T_SamplerInstrNode::setLOD( lod_ = T_LOD_{ location , std::move( min ) , std::move( max ) }; return {}; } + +/*= T_LocalsInstrNode ===========================================================*/ + +bool T_LocalsInstrNode::addVariable( + T_SRDToken const& token ) noexcept +{ + if ( vars_.contains( token.stringValue( ) ) ) { + return false; + } + vars_.add( token.stringValue( ) ); + varLocs_.add( token.location( ) ); + return true; +} diff --git a/opast.hh b/opast.hh index 0f0b5cc..be5e855 100644 --- a/opast.hh +++ b/opast.hh @@ -25,6 +25,7 @@ class A_Node OP_FRAMEBUFFER ,// Define framebuffer OP_FULLSCREEN , // Draw a fullscreen quad OP_INPUT , // Input declaration + OP_LOCALS , // Declare local variables OP_ODBG , // Output debugging OP_PIPELINE , // Shader pipeline declaration OP_PROFILE , // Profiling block @@ -484,6 +485,32 @@ class T_InputInstrNode : public A_InstructionNode { return dvLocation_; } }; +// Local variable declarations +class T_LocalsInstrNode : public A_InstructionNode +{ + private: + T_AutoArray< T_String , 8 > vars_; + T_AutoArray< T_SRDLocation , 8 > varLocs_; + + public: + T_LocalsInstrNode( T_InstrListNode& parent ) noexcept + : A_InstructionNode( OP_LOCALS , parent ) + { } + + bool addVariable( T_SRDToken const& token ) noexcept; + + uint32_t variables( ) const noexcept + { return vars_.size( ); } + + T_String const& varName( + const uint32_t index ) const noexcept + { return vars_[ index ]; } + + T_SRDLocation const& varLocation( + const uint32_t index ) const noexcept + { return varLocs_[ index ]; } +}; + // Output debugging class T_OutputDebugInstrNode : public A_InstructionNode { diff --git a/opparser.cc b/opparser.cc index 9808525..4874685 100644 --- a/opparser.cc +++ b/opparser.cc @@ -18,6 +18,7 @@ struct T_ParserImpl_ FULLSCREEN , IF , INPUT , + LOCALS , ODBG , PIPELINE , PROFILE , @@ -45,6 +46,7 @@ struct T_ParserImpl_ add( "fullscreen" , E_InstrType::FULLSCREEN ); add( "if" , E_InstrType::IF ); add( "input" , E_InstrType::INPUT ); + add( "locals" , E_InstrType::LOCALS ); add( "odbg" , E_InstrType::ODBG ); add( "pipeline" , E_InstrType::PIPELINE ); add( "profiling" , E_InstrType::PROFILE ); @@ -191,6 +193,7 @@ struct T_ParserImpl_ M_DPARSER_( If ); M_DPARSER_( Input ); + M_DPARSER_( Local ); M_DPARSER_( ODebug ); M_DPARSER_( Pipeline ); M_DPARSER_( Profile ); @@ -486,6 +489,7 @@ void T_ParserImpl_::parseInstructions( M_CASE_( FRAMEBUFFER , Framebuffer ); M_CASE_( IF , If ); M_CASE_( INPUT , Input ); + M_CASE_( LOCALS , Local ); M_CASE_( ODBG , ODebug ); M_CASE_( PIPELINE , Pipeline ); M_CASE_( PROFILE , Profile ); @@ -684,6 +688,31 @@ M_INSTR_( Input ) /*----------------------------------------------------------------------------*/ +M_INSTR_( Local ) +{ + const auto ni( input.size( ) ); + if ( ni < 2 ) { + errors.addNew( "variable identifier expected" , input[ 0 ].location( ) ); + return; + } + + auto& instr{ instructions.add< T_LocalsInstrNode >( ) }; + instr.location( ) = input[ 0 ].location( ); + + for ( auto i = 1u ; i < ni ; i ++ ) { + auto const& token( input[ i ] ); + if ( token.type( ) != E_SRDTokenType::WORD ) { + errors.addNew( "variable identifier expected" , + token.location( ) ); + } else if ( !instr.addVariable( token ) ) { + errors.addNew( "duplicate variable identifier" , + token.location( ) ); + } + } +} + +/*----------------------------------------------------------------------------*/ + M_INSTR_( ODebug ) { const auto ni( input.size( ) );