Parser - Partial prototype for type registry

This commit is contained in:
Emmanuel BENOîT 2017-11-10 14:29:36 +01:00
parent eae82f1f9a
commit b6738aff95

View file

@ -2,6 +2,7 @@
#include "opast.hh"
#include <ebcl/Files.hh>
#include <ebcl/SRDText.hh>
#include <ebcl/Algorithms.hh>
using namespace ebcl;
using namespace opast;
@ -35,6 +36,121 @@ void WriteSRDError(
/*============================================================================*/
T_Array< T_SRDError > parserPrototypes(
T_OwnPtr< T_RootNode > const& root )
{
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;
T_Decl_( const E_DataType dt ,
T_SRDLocation const& loc ) noexcept
: type( dt ) , location( loc )
{ }
};
T_KeyValueTable< T_String , T_Decl_ > type;
visitor.visit( *root , [&]( A_Node& node , bool exit ) -> bool {
if ( exit ) {
return false;
}
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:
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 );
}
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;
} );
return errors;
}
/*============================================================================*/
@ -76,8 +192,20 @@ int main( int argc , char** argv )
// Parse the fuck
T_Parser parser;
if ( parser.parse( srdOut.list( ) ) ) {
printf( "Success - now running prototypes\n" );
T_Array< T_SRDError > errors{ parserPrototypes( parser.result( ) ) };
if ( errors.empty( ) ) {
printf( "Success!\n" );
return 0;
}
T_StringBuilder sb;
for ( auto const& err : errors ) {
WriteSRDError( sb , err );
}
sb << "Parser prototypes failed\n" << '\0';
fprintf( stderr , "%s" , sb.data( ) );
return 4;
} else {
T_StringBuilder sb;
for ( auto const& err : parser.errors( ) ) {