diff --git a/parsercheck.cc b/parsercheck.cc index 63b7c7b..fd88e39 100644 --- a/parsercheck.cc +++ b/parsercheck.cc @@ -42,16 +42,6 @@ T_Array< T_SRDError > parserPrototypes( T_Visitor< opast::A_Node > visitor{ ASTVisitorBrowser }; T_Array< T_SRDError > errors; - enum class E_DataType { - UNKNOWN , - ALIAS , - VARIABLE , - FRAMEBUFFER , - INPUT , - PIPELINE , - PROGRAM , - TEXTURE , - }; struct T_Decl_ { E_DataType type; T_SRDLocation location; @@ -60,8 +50,15 @@ T_Array< T_SRDError > parserPrototypes( T_SRDLocation const& loc ) noexcept : type( dt ) , location( loc ) { } + + T_Decl_( const E_DataType dt ) noexcept + : type( dt ) , location{} + { } }; T_KeyValueTable< T_String , T_Decl_ > type; + type.add( T_String::Pooled( "time" ) , T_Decl_{ E_DataType::BUILTIN } ); + type.add( T_String::Pooled( "width" ) , T_Decl_{ E_DataType::BUILTIN } ); + type.add( T_String::Pooled( "height" ) , T_Decl_{ E_DataType::BUILTIN } ); visitor.visit( *root , [&]( A_Node& node , bool exit ) -> bool { if ( exit ) { @@ -71,79 +68,40 @@ T_Array< T_SRDError > parserPrototypes( E_DataType dt{ E_DataType::UNKNOWN }; T_String id; T_SRDLocation location; - switch ( node.type( ) ) { - - case A_Node::OP_FRAMEBUFFER: - dt = E_DataType::FRAMEBUFFER; - id = dynamic_cast< T_FramebufferInstrNode& >( node ).id( ); - location = dynamic_cast< T_FramebufferInstrNode& >( node ).idLocation( ); - break; - - case A_Node::OP_INPUT: - dt = E_DataType::INPUT; - id = dynamic_cast< T_InputInstrNode& >( node ).name( ); - location = dynamic_cast< T_InputInstrNode& >( node ).nameLocation( ); - break; - - case A_Node::OP_PIPELINE: - dt = E_DataType::PIPELINE; - id = dynamic_cast< T_PipelineInstrNode& >( node ).id( ); - location = dynamic_cast< T_PipelineInstrNode& >( node ).idLocation( ); - break; - - case A_Node::OP_PROGRAM: - dt = E_DataType::PROGRAM; - id = dynamic_cast< T_ProgramInstrNode& >( node ).id( ); - location = dynamic_cast< T_ProgramInstrNode& >( node ).idLocation( ); - break; - - case A_Node::OP_SET: + if ( node.type( ) == A_Node::OP_SET ) { dt = E_DataType::VARIABLE; id = dynamic_cast< T_SetInstrNode& >( node ).id( ); location = dynamic_cast< T_SetInstrNode& >( node ).idLocation( ); - break; - - case A_Node::OP_TEXTURE: - dt = E_DataType::TEXTURE; - id = dynamic_cast< T_TextureInstrNode& >( node ).id( ); - location = dynamic_cast< T_TextureInstrNode& >( node ).idLocation( ); - break; - - // TODO: samplers - - default: - return !dynamic_cast< A_ExpressionNode* >( &node ); + } else { + auto* np{ dynamic_cast< A_ResourceDefInstrNode* >( &node ) }; + if ( !np ) { + return !dynamic_cast< A_ExpressionNode* >( &node ); + } + dt = np->dataType( ); + id = np->id( ); + location = np->idLocation( ); } - assert( dt != E_DataType::UNKNOWN ); + T_Decl_ const* const existing( type.get( id ) ); if ( !existing ) { type.add( id , T_Decl_{ dt , location } ); - } else if ( existing->type != dt ) { - T_StringBuilder sb; - sb << "'" << id << "' redeclared as "; - switch ( dt ) { - case E_DataType::VARIABLE: sb << "variable"; break; - case E_DataType::FRAMEBUFFER: sb << "framebuffer"; break; - case E_DataType::INPUT: sb << "input"; break; - case E_DataType::PIPELINE: sb << "pipeline"; break; - case E_DataType::PROGRAM: sb << "program"; break; - case E_DataType::TEXTURE: sb << "texture"; break; - default: std::abort( ); - } - sb << "; previous declaration as "; - switch ( existing->type ) { - case E_DataType::VARIABLE: sb << "variable"; break; - case E_DataType::FRAMEBUFFER: sb << "framebuffer"; break; - case E_DataType::INPUT: sb << "input"; break; - case E_DataType::PIPELINE: sb << "pipeline"; break; - case E_DataType::PROGRAM: sb << "program"; break; - case E_DataType::TEXTURE: sb << "texture"; break; - default: std::abort( ); - } - sb << " at " << existing->location; - errors.addNew( std::move( sb ) , location ); + return false; } + if ( existing->type == dt ) { + return false; + } + + T_StringBuilder sb; + if ( existing->type == E_DataType::BUILTIN ) { + sb << "trying to redefine built-in variable " << id; + } else { + sb << "'" << id << "' redeclared as " << dt + << "; previous declaration as " + << existing->type << " at " + << existing->location; + } + errors.addNew( std::move( sb ) , location ); return false; } );