Builder tool - Logging

Added logging using F_OPLogger wherever there were traces.
This commit is contained in:
Emmanuel BENOîT 2017-12-03 13:05:54 +01:00
parent da0d419fab
commit c4ce6e90d7
5 changed files with 210 additions and 146 deletions

View file

@ -3,19 +3,26 @@
#include "c-opcomp.hh" #include "c-opcomp.hh"
#include <ebcl/Algorithms.hh> #include <ebcl/Algorithms.hh>
//#define INVASIVE_TRACES
using namespace ebcl; using namespace ebcl;
using namespace ops; using namespace ops;
using namespace opast; using namespace opast;
#define M_LOGSTR_( S , L ) \
logger( [](){ return T_StringBuilder{ S }; } , L )
namespace { namespace {
struct T_CompilerImpl_ struct T_CompilerImpl_
{ {
T_CompilerImpl_( F_OPLogger* logger ) noexcept
: logger( *logger ) {}
P_OpProgram compile( T_OpsParserOutput const& input ) noexcept; P_OpProgram compile( T_OpsParserOutput const& input ) noexcept;
private: private:
F_OPLogger& logger;
T_Visitor< A_Node > astVisitor{ ASTVisitorBrowser }; T_Visitor< A_Node > astVisitor{ ASTVisitorBrowser };
T_Set< uint32_t > constants{ UseTag< IndexBacked< > >( ) }; T_Set< uint32_t > constants{ UseTag< IndexBacked< > >( ) };
T_KeyValueTable< T_String , uint32_t > locations; T_KeyValueTable< T_String , uint32_t > locations;
@ -107,53 +114,66 @@ P_OpProgram T_CompilerImpl_::compile(
// and frame is always 1 // and frame is always 1
output->init = input->root.functionIndex( "*init*" ); output->init = input->root.functionIndex( "*init*" );
output->frame = input->root.functionIndex( "*frame*" ); output->frame = input->root.functionIndex( "*frame*" );
#ifdef INVASIVE_TRACES logger( [this]( ) {
printf( "function indices\n\t%d\tinit\n\t%d\tframe\n" , T_StringBuilder sb;
output->init , output->frame ); sb << "Function indices\n\tinit: " << output->init
#endif << "\n\tframe: " << output->frame;
return sb;
} , 3 );
// Compile each function // Compile each function
#ifdef INVASIVE_TRACES
uint32_t nInstr = 0; uint32_t nInstr = 0;
#endif
uint32_t cfi; uint32_t cfi;
for ( cfi = 0u ; cfi < input->root.nFunctions( ) ; cfi ++ ) { for ( cfi = 0u ; cfi < input->root.nFunctions( ) ; cfi ++ ) {
output->ops.next( ); output->ops.next( );
auto& func( input->root.function( cfi ) ); auto& func( input->root.function( cfi ) );
#ifdef INVASIVE_TRACES logger( [&]( ) {
printf( "compiling function %s\n" , T_StringBuilder sb;
func.name( ).toOSString( ).data( ) ); sb << "... Compiling function " << func.name( );
#endif return sb;
} , 3 );
sdMain = sdFPU = 0; sdMain = sdFPU = 0;
astVisitor.visit( func , astVisitor.visit( func ,
[=]( A_Node& node , const bool exit ) -> bool { [=]( A_Node& node , const bool exit ) -> bool {
return compileNode( cfi , node , exit ); return compileNode( cfi , node , exit );
} ); } );
#ifdef INVASIVE_TRACES
T_StringBuilder dump , temp; logger( [&]( ) {
for ( auto i = 0u ; i < output->ops.sizeOf( cfi ) ; i ++ ) { T_StringBuilder sb , temp;
temp << "(" << output->ops.get( cfi , i ) << ")"; sb << "...... Compiled function " << func.name( );
while ( temp.length( ) < 30 ) { for ( auto i = 0u ; i < output->ops.sizeOf( cfi ) ; i ++ ) {
temp << ' '; temp << "(" << output->ops.get( cfi , i ) << ")";
while ( temp.length( ) < 30 ) {
temp << ' ';
}
sb << "\n\t\t" << temp << "{ "
<< output->ops.get( cfi , i ).location
<< " }";
temp.clear( );
} }
dump << "\t\t" << temp << "{ " << output->ops.get( cfi , i ).location << " }\n"; return sb;
temp.clear( ); } , 4 );
} logger( [&]( ) {
dump << '\t' << output->ops.sizeOf( cfi ) << " instructions\n" T_StringBuilder sb;
<< '\0'; sb << "...... " << output->ops.sizeOf( cfi )
printf( "%s" , dump.data( ) ); << " instructions";
return sb;
} , 3 );
nInstr += output->ops.sizeOf( cfi ); nInstr += output->ops.sizeOf( cfi );
#endif
} }
#ifdef INVASIVE_TRACES logger( [=]( ) {
printf( "total %d instructions\n" , nInstr ); T_StringBuilder sb;
#endif sb << "... Generated " << nInstr << " instructions";
return sb;
} , 2 );
return std::move( output ); return std::move( output );
} }
void T_CompilerImpl_::gatherConstants( ) noexcept void T_CompilerImpl_::gatherConstants( ) noexcept
{ {
M_LOGSTR_( "... Gathering constants" , 2 );
constants.clear( ); constants.clear( );
astVisitor.visit( input->root , [&]( A_Node& node , const bool exit ) { astVisitor.visit( input->root , [&]( A_Node& node , const bool exit ) {
if ( exit ) { if ( exit ) {
@ -175,22 +195,24 @@ void T_CompilerImpl_::gatherConstants( ) noexcept
output->constants.add( constants[ i ] ); output->constants.add( constants[ i ] );
} }
#ifdef INVASIVE_TRACES logger( [&]() {
printf( "%d constants\n" , constants.size( ) ); T_StringBuilder sb;
for ( auto i = 0u ; i < constants.size( ) ; i ++ ) { char temp[ 9 ];
printf( " %08x" , constants[ i ] ); sb << constants.size( ) << " constants\n\t";
if ( i % 4 == 3 ) { for ( auto i = 0u ; i < constants.size( ) ; i ++ ) {
printf( "\n" ); snprintf( temp , 9 , "%08x" , constants[ i ] );
sb << " " << temp;
if ( i % 4 == 3 && i != constants.size( ) - 1 ) {
sb << "\n\t";
}
} }
} return sb;
if ( constants.size( ) % 4 ) { } , 3 );
printf( "\n" );
}
#endif
} }
void T_CompilerImpl_::countAssets( ) noexcept void T_CompilerImpl_::countAssets( ) noexcept
{ {
M_LOGSTR_( "... Counting resources" , 2 );
locations.clear( ); locations.clear( );
locations.add( T_String::Pooled( "time" ) , 0u ); locations.add( T_String::Pooled( "time" ) , 0u );
locations.add( T_String::Pooled( "width" ) , 1u ); locations.add( T_String::Pooled( "width" ) , 1u );
@ -268,47 +290,46 @@ void T_CompilerImpl_::countAssets( ) noexcept
} }
} }
#ifdef INVASIVE_TRACES logger( [&]() {
printf( "assets\n\t%d framebuffers\n\t%d pipelines\n" T_StringBuilder sb;
"\t%d programs\n\t%d samplers\n\t%d textures\n" sb << "... Resource counts:\n"
"\t%d variables\n\t%d inputs\n" , << "\t\tFramebuffers:\t" << output->nFramebuffers << '\n'
output->nFramebuffers , output->nPipelines , << "\t\tPipelines: \t" << output->nPipelines << '\n'
output->nPrograms , output->nSamplers , << "\t\tPrograms: \t" << output->nPrograms << '\n'
output->nTextures , output->nVariables , << "\t\tSamplers: \t" << output->nSamplers << '\n'
output->inputs.size( ) ); << "\t\tTextures: \t" << output->nTextures << '\n'
printf( "table ranges\n\t0\t2\tBuilt-ins\n" << "\t\tInputs: \t" << output->inputs.size( ) << '\n'
"\t3\t%d\tConstants\n" << "\tTable ranges:\n"
"\t%d\t%d\tVariables\n" << "\t\tBuilt-ins \t0\t2\n"
"\t%d\t%d\tFramebuffers\n" << "\t\tConstants \t3\t" << fiVariables - 1 << '\n'
"\t%d\t%d\tPipelines\n" << "\t\tVariables \t" << fiVariables << '\t' << fiFramebuffers - 1 << '\n'
"\t%d\t%d\tPrograms\n" << "\t\tFramebuffers \t" << fiFramebuffers << '\t' << fiPipelines - 1 << '\n'
"\t%d\t%d\tSamplers\n" << "\t\tPipelines \t" << fiPipelines << '\t' << fiPrograms - 1 << '\n'
"\t%d\t%d\tTextures\n" , << "\t\tPrograms \t" << fiPrograms << '\t' << fiSamplers - 1 << '\n'
fiVariables - 1 , fiVariables , fiFramebuffers - 1 , fiFramebuffers , << "\t\tSamplers \t" << fiSamplers << '\t' << fiTextures - 1 << '\n'
fiPipelines - 1 , fiPipelines , fiPrograms - 1 , fiPrograms , << "\t\tTextures \t" << fiTextures << '\t' << fiTextures + output->nTextures - 1
fiSamplers - 1 , fiSamplers , fiTextures - 1 , fiTextures , ;
fiTextures + output->nTextures - 1 ); return sb;
} , 3 );
T_Array< uint32_t > indices( locations.size( ) ); logger( [&]() {
indices.ensureCapacity( locations.size( ) ); T_StringBuilder sb;
for ( auto i = 0u ; i < locations.size( ) ; i ++ ) { T_Array< uint32_t > indices( locations.size( ) );
indices.add( i ); indices.ensureCapacity( locations.size( ) );
} for ( auto i = 0u ; i < locations.size( ) ; i ++ ) {
indices.sort( [this]( uint32_t a , uint32_t b ) { indices.add( i );
return T_Comparator< uint32_t >::compare( }
locations.values( )[ a ] , indices.sort( [this]( uint32_t a , uint32_t b ) {
locations.values( )[ b ] ); return T_Comparator< uint32_t >::compare(
} ); locations.values( )[ a ] ,
T_StringBuilder lmap; locations.values( )[ b ] );
lmap << "location map (constants not included)\n"; } );
for ( auto idx : indices ) { sb << "... Location map (constants not included)";
lmap << '\t' << locations.values( )[ idx ] for ( auto idx : indices ) {
<< '\t' << locations.keys( )[ idx ] sb << "\n\t" << locations.values( )[ idx ]
<< '\n'; << '\t' << locations.keys( )[ idx ];
} }
lmap << '\0'; return sb;
printf( "%s" , lmap.data( ) ); } , 4 );
#endif
} }
bool T_CompilerImpl_::compileNode( bool T_CompilerImpl_::compileNode(
@ -873,12 +894,12 @@ void T_CompilerImpl_::applyStackEffects(
const auto m( DeltaMainStack( op.op ) ); const auto m( DeltaMainStack( op.op ) );
const auto f( DeltaFPUStack( op.op ) ); const auto f( DeltaFPUStack( op.op ) );
#ifdef INVASIVE_TRACES logger( [&]() {
T_StringBuilder sb; T_StringBuilder sb;
sb << "applying stack effects for (" << op << ") - sdMain " << sdMain sb << "applying stack effects for (" << op << ") - sdMain " << sdMain
<< " (" << m << ") sdFPU " << sdFPU << " (" << f << ")" << '\n' << '\0'; << " (" << m << ") sdFPU " << sdFPU << " (" << f << ')';
printf( "%s" , sb.data( ) ); return sb;
#endif } , 5 );
if ( m ) { if ( m ) {
assert( m > 0 || sdMain >= uint32_t( -m ) ); assert( m > 0 || sdMain >= uint32_t( -m ) );
@ -897,7 +918,7 @@ void T_CompilerImpl_::applyStackEffects(
/*= T_OpsCompiler ==============================================================*/ /*= T_OpsCompiler ==============================================================*/
T_OpsCompiler::T_OpsCompiler( ) noexcept T_OpsCompiler::T_OpsCompiler( ) noexcept
: A_PrivateImplementation( new T_CompilerImpl_( ) ) : A_PrivateImplementation( new T_CompilerImpl_( &logger_ ) )
{ } { }
P_OpProgram T_OpsCompiler::compile( P_OpProgram T_OpsCompiler::compile(

View file

@ -53,9 +53,21 @@ namespace ops { struct T_OpProgram; using P_OpProgram = T_OwnPtr< T_OpProgram >;
// Generates bytecode based on the type-checked tree produced by the parser // Generates bytecode based on the type-checked tree produced by the parser
class T_OpsCompiler : public ebcl::A_PrivateImplementation class T_OpsCompiler : public ebcl::A_PrivateImplementation
{ {
private:
F_OPLogger logger_{ []( auto , auto ) { } };
public: public:
T_OpsCompiler( ) noexcept; T_OpsCompiler( ) noexcept;
void setLogger( F_OPLogger logger )
{
if ( logger ) {
logger_ = std::move( logger );
} else {
logger_ = []( auto , auto ) { };
}
}
ops::P_OpProgram compile( T_OpsParserOutput const& input ) noexcept; ops::P_OpProgram compile( T_OpsParserOutput const& input ) noexcept;
}; };

View file

@ -9,6 +9,10 @@ using namespace opast;
using namespace opopt; using namespace opopt;
#define M_LOGSTR_( S , L ) \
oData.logger( [](){ return T_StringBuilder{ S }; } , L )
/*= T_OptData ================================================================*/ /*= T_OptData ================================================================*/
void T_OptData::findInputDecls( void T_OptData::findInputDecls(
@ -140,7 +144,7 @@ template<
T_StringBuilder sb; T_StringBuilder sb;
sb << "substituting node at " << child.location( ); sb << "substituting node at " << child.location( );
return sb; return sb;
} , 2 ); } , 3 );
r->location( ) = node.location( ); r->location( ) = node.location( );
set( node , std::move( r ) ); set( node , std::move( r ) );
didFold = true; didFold = true;
@ -235,17 +239,13 @@ P_ExpressionNode T_ConstantFolder_::doIdExpr(
} }
if ( node.id( ) == "width" ) { if ( node.id( ) == "width" ) {
oData.logger( []{ M_LOGSTR_( "replacing $width with fixed width" , 3 );
return T_StringBuilder{ "replacing $width with fixed width" };
} , 2 );
return NewOwned< T_ConstantExprNode >( node.parent( ) , return NewOwned< T_ConstantExprNode >( node.parent( ) ,
double( oData.fixedSize->first ) ); double( oData.fixedSize->first ) );
} }
if ( node.id( ) == "height" ) { if ( node.id( ) == "height" ) {
oData.logger( []{ M_LOGSTR_( "replacing $height with fixed height" , 3 );
return T_StringBuilder{ "replacing $height with fixed height" };
} , 2 );
return NewOwned< T_ConstantExprNode >( node.parent( ) , return NewOwned< T_ConstantExprNode >( node.parent( ) ,
float( oData.fixedSize->second ) ); float( oData.fixedSize->second ) );
} }
@ -374,9 +374,7 @@ bool opopt::FoldConstants(
T_OptData& oData ) noexcept T_OptData& oData ) noexcept
{ {
T_ConstantFolder_ folder{ oData }; T_ConstantFolder_ folder{ oData };
oData.logger( []() { M_LOGSTR_( "... Folding constants" , 2 );
return T_StringBuilder{ "constant folding pass" };
} , 1 );
if ( oData.curves ) { if ( oData.curves ) {
oData.findInputDecls( program ); oData.findInputDecls( program );
} }
@ -384,10 +382,12 @@ bool opopt::FoldConstants(
return folder( n , x ); return folder( n , x );
} ); } );
oData.logger( [&]() { oData.logger( [&]() {
return T_StringBuilder{ T_StringBuilder sb{ "...... " };
folder.didFold ? "some constants were folded" sb << ( folder.didFold
: "no constants were folded" }; ? "Some constants were folded"
} , 1 ); : "No constants were folded" );
return sb;
} , 2 );
return folder.didFold; return folder.didFold;
} }

View file

@ -12,6 +12,11 @@ using namespace ebcl;
using namespace opast; using namespace opast;
#define M_LOGSTR_( S , L ) \
logger( [](){ return T_StringBuilder{ S }; } , L )
/*= T_Parser =================================================================*/ /*= T_Parser =================================================================*/
namespace { namespace {
@ -308,7 +313,7 @@ inline T_ParserImpl_::T_ParserImpl_(
T_Array< T_SRDError >* const errors , T_Array< T_SRDError >* const errors ,
T_OwnPtr< T_OpsParserOutput >* const output , T_OwnPtr< T_OpsParserOutput >* const output ,
F_OPLogger* logger ) noexcept F_OPLogger* logger ) noexcept
: output( *output ) , errors( *errors ) , logger( *logger ) , : output( *output ) , errors( *errors ) , logger{ *logger } ,
ovParserConfig( sov::GetParserConfig( ) ) , ovParserConfig( sov::GetParserConfig( ) ) ,
ovParser( ovParserConfig ) ovParser( ovParserConfig )
{ } { }
@ -334,6 +339,7 @@ void T_ParserImpl_::main(
bool T_ParserImpl_::checkRequiredBlocks( bool T_ParserImpl_::checkRequiredBlocks(
T_SRDList const& input ) noexcept T_SRDList const& input ) noexcept
{ {
M_LOGSTR_( "... Checking for required blocks" , 2 );
const T_SRDLocation missingErrLoc( ([&input]() { const T_SRDLocation missingErrLoc( ([&input]() {
if ( input.size( ) != 0 ) { if ( input.size( ) != 0 ) {
return T_SRDLocation( input[ 0 ].location( ).source( ) , 1 , 1 ); return T_SRDLocation( input[ 0 ].location( ).source( ) , 1 , 1 );
@ -354,6 +360,7 @@ bool T_ParserImpl_::checkRequiredBlocks(
*/ */
bool T_ParserImpl_::checkCalls( ) noexcept bool T_ParserImpl_::checkCalls( ) noexcept
{ {
M_LOGSTR_( "... Gathering/checking calls" , 2 );
calls.clear( ); calls.clear( );
uint32_t cfi; uint32_t cfi;
for ( cfi = 0 ; cfi < output->root.nFunctions( ) ; cfi ++ ) { for ( cfi = 0 ; cfi < output->root.nFunctions( ) ; cfi ++ ) {
@ -399,6 +406,7 @@ bool T_ParserImpl_::checkCalls( ) noexcept
*/ */
bool T_ParserImpl_::checkInstructionRestrictions( ) noexcept bool T_ParserImpl_::checkInstructionRestrictions( ) noexcept
{ {
M_LOGSTR_( "... Checking instruction restrictions" , 2 );
callInfo.clear( ); callInfo.clear( );
callInfo.resize( calls.size( ) ); callInfo.resize( calls.size( ) );
@ -449,6 +457,7 @@ bool T_ParserImpl_::checkInstructionRestrictions( ) noexcept
*/ */
bool T_ParserImpl_::checkLocalVariables( ) noexcept bool T_ParserImpl_::checkLocalVariables( ) noexcept
{ {
M_LOGSTR_( "... Checking local variables" , 2 );
uint32_t cfi; uint32_t cfi;
T_StringBuilder esb; T_StringBuilder esb;
for ( cfi = 0 ; cfi < output->root.nFunctions( ) ; cfi ++ ) { for ( cfi = 0 ; cfi < output->root.nFunctions( ) ; cfi ++ ) {
@ -486,6 +495,8 @@ bool T_ParserImpl_::checkLocalVariables( ) noexcept
*/ */
bool T_ParserImpl_::collectGlobalTypes( ) noexcept bool T_ParserImpl_::collectGlobalTypes( ) noexcept
{ {
M_LOGSTR_( "... Collecting global declaration types" , 2 );
// Temporary table for type / first declaration location // Temporary table for type / first declaration location
struct T_Decl_ { struct T_Decl_ {
E_DataType type; E_DataType type;
@ -538,7 +549,7 @@ bool T_ParserImpl_::collectGlobalTypes( ) noexcept
T_StringBuilder sb; T_StringBuilder sb;
sb << "id " << id << " as " << dt << " at " << location; sb << "id " << id << " as " << dt << " at " << location;
return sb; return sb;
} , 2 ); } , 3 );
// When we find a set instruction, we need to check whether // When we find a set instruction, we need to check whether
// it is affecting a local variable. If it is we'll just skip // it is affecting a local variable. If it is we'll just skip
@ -589,7 +600,7 @@ bool T_ParserImpl_::collectGlobalTypes( ) noexcept
bool T_ParserImpl_::checkArgumentTypes( ) noexcept bool T_ParserImpl_::checkArgumentTypes( ) noexcept
{ {
logger( []{ return T_StringBuilder{ "Checking argument types" }; } , 1 ); M_LOGSTR_( "... Checking function argument types" , 2 );
// Find functions for which arguments types need to be resolved // Find functions for which arguments types need to be resolved
const auto nFunctions( output->root.nFunctions( ) ); const auto nFunctions( output->root.nFunctions( ) );
@ -629,12 +640,12 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
} ); } );
} }
#define TRACE( x ) \ #define M_TRACE_( l , x ) \
logger( [&]{ \ logger( [&]{ \
T_StringBuilder sb; \ T_StringBuilder sb; \
sb << x; \ sb << x; \
return sb; \ return sb; \
} , 2 ) } , l )
T_StringBuilder esb; T_StringBuilder esb;
bool changed = true; bool changed = true;
@ -645,13 +656,13 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
// resolved and check all calls. // resolved and check all calls.
for ( auto i = 0u ; i < nFunctions ; i ++ ) { for ( auto i = 0u ; i < nFunctions ; i ++ ) {
auto& f( output->root.function( i ) ); auto& f( output->root.function( i ) );
TRACE( "about to check function " << f.name( ) ); M_TRACE_( 3 , "about to check function " << f.name( ) );
if ( !argsResolved[ i ] ) { if ( !argsResolved[ i ] ) {
TRACE( " -> arguments not resolved, skipped" ); M_TRACE_( 3 , " -> arguments not resolved, skipped" );
continue; continue;
} }
TRACE( " -> " << callInstuctions.sizeOf( i ) << " calls w/ arguments" ); M_TRACE_( 3 , " -> " << callInstuctions.sizeOf( i ) << " calls w/ arguments" );
for ( auto c = 0u ; c < callInstuctions.sizeOf( i ) ; c ++ ) { for ( auto c = 0u ; c < callInstuctions.sizeOf( i ) ; c ++ ) {
auto const* call( callInstuctions.get( i , c ) ); auto const* call( callInstuctions.get( i , c ) );
if ( ! call ) { if ( ! call ) {
@ -662,13 +673,13 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
const auto calledIdx( output->root.functionIndex( called ) ); const auto calledIdx( output->root.functionIndex( called ) );
auto& calledFn( dynamic_cast< T_FuncNode& >( auto& calledFn( dynamic_cast< T_FuncNode& >(
output->root.function( calledIdx ) ) ); output->root.function( calledIdx ) ) );
TRACE( " -> checking call to " << called << " (idx " << calledIdx M_TRACE_( 4 , " -> checking call to " << called << " (idx " << calledIdx
<< ") at " << call->location( ) ); << ") at " << call->location( ) );
assert( call->arguments( ) == calledFn.arguments( ) ); assert( call->arguments( ) == calledFn.arguments( ) );
if ( argsResolved[ calledIdx ] ) { if ( argsResolved[ calledIdx ] ) {
TRACE( " argument types already resolved, checking" ); M_TRACE_( 4 , " argument types already resolved, checking" );
} else { } else {
TRACE( " resolving arguments" ); M_TRACE_( 4 , " resolving arguments" );
} }
bool ok = true; bool ok = true;
@ -686,7 +697,7 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
} else { } else {
ndt = E_DataType::VARIABLE; ndt = E_DataType::VARIABLE;
} }
TRACE( " [" << a << "] " << ndt ); M_TRACE_( 4 , " [" << a << "] " << ndt );
// Arguments not resolved -> try setting the argument's type // Arguments not resolved -> try setting the argument's type
if ( !argsResolved[ calledIdx ] ) { if ( !argsResolved[ calledIdx ] ) {
@ -718,6 +729,8 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
bool T_ParserImpl_::checkIdentifiers( ) noexcept bool T_ParserImpl_::checkIdentifiers( ) noexcept
{ {
M_LOGSTR_( "... Checking command argument types" , 2 );
uint32_t cfi; uint32_t cfi;
T_StringBuilder esb; T_StringBuilder esb;
for ( cfi = 0 ; cfi < output->root.nFunctions( ) ; cfi ++ ) { for ( cfi = 0 ; cfi < output->root.nFunctions( ) ; cfi ++ ) {
@ -914,6 +927,7 @@ E_DataType T_ParserImpl_::getTypeOf(
bool T_ParserImpl_::parseTopLevel( bool T_ParserImpl_::parseTopLevel(
T_SRDList const& input ) noexcept T_SRDList const& input ) noexcept
{ {
M_LOGSTR_( "... Generating tree" , 2 );
for ( auto const& t : input ) { for ( auto const& t : input ) {
if ( t.type( ) == E_SRDTokenType::LIST && t.list( ).size( ) > 0 ) { if ( t.type( ) == E_SRDTokenType::LIST && t.list( ).size( ) > 0 ) {
parseFunction( t.list( ) ); parseFunction( t.list( ) );

View file

@ -14,6 +14,9 @@
using namespace ebcl; using namespace ebcl;
using namespace opast; using namespace opast;
#define M_LOGSTR( S , L ) \
logger( [](){ return T_StringBuilder{ S }; } , L )
namespace { namespace {
const struct option CmdLineOpts_[] = { const struct option CmdLineOpts_[] = {
@ -72,6 +75,20 @@ void WriteSRDErrors(
fprintf( stderr , "%s" , sb.data( ) ); fprintf( stderr , "%s" , sb.data( ) );
} }
void WriteSRDErrors(
char const* const title ,
T_Array< T_SRDError > const& errors ) noexcept
{
T_StringBuilder sb;
sb << "===== " << title << '\n';
const auto nErrors( errors.size( ) );
for ( auto i = 0u ; i < nErrors ; i ++ ) {
WriteSRDError( sb , errors[ i ] );
}
sb << '\0';
fprintf( stderr , "%s" , sb.data( ) );
}
T_String FilePath( T_String FilePath(
T_String const& path , T_String const& path ,
char const* const name ) noexcept char const* const name ) noexcept
@ -137,7 +154,7 @@ int main( int argc , char** argv )
} }; } };
// Build configurations // Build configurations
logger( [](){ return T_StringBuilder{ "Loading build configurations" }; } , 1 ); M_LOGSTR( "Loading build configurations" , 1 );
const T_String bcfgFile{ FilePath( oSrcPath , "build.srd" ) }; const T_String bcfgFile{ FilePath( oSrcPath , "build.srd" ) };
const T_BuildConfiguration cfg{ [&]() { const T_BuildConfiguration cfg{ [&]() {
try { try {
@ -167,18 +184,8 @@ int main( int argc , char** argv )
} }
} () }; } () };
// Open file
const T_String inputName{ FilePath( oSrcPath , "demo.srd" ) };
T_File input( inputName , E_FileMode::READ_ONLY );
try {
input.open( );
} catch ( X_StreamError const& e ) {
PrintStreamError( "Could not open" , inputName , e );
return 1;
}
// Load curves // Load curves
logger( [](){ return T_StringBuilder{ "Loading curves data" }; } , 1 ); M_LOGSTR( "Loading curves data" , 1 );
const T_String curvesFile{ FilePath( oSrcPath , "curves.srd" ) }; const T_String curvesFile{ FilePath( oSrcPath , "curves.srd" ) };
T_SyncCurvesIO::T_Data p; T_SyncCurvesIO::T_Data p;
try { try {
@ -193,38 +200,46 @@ int main( int argc , char** argv )
exit( EXIT_FAILURE ); exit( EXIT_FAILURE );
} }
// Load script // Open and load script
M_LOGSTR( "Loading script" , 1 );
const T_String inputName{ FilePath( oSrcPath , "demo.srd" ) };
T_SRDMemoryTarget srdOut; T_SRDMemoryTarget srdOut;
srdOut.clearComments( true ).clearFlushToken( true ); {
try { T_File input( inputName , E_FileMode::READ_ONLY );
T_SRDTextReader srdReader{ srdOut }; try {
T_FileInputStream fis{ input }; input.open( );
srdReader.read( inputName , fis ); } catch ( X_StreamError const& e ) {
} catch ( X_StreamError const& e ) { PrintStreamError( "Could not open" , inputName , e );
fprintf( stderr , "===== SCRIPT\n" ); return 1;
PrintStreamError( "Could not open" , inputName , e ); }
return 1; srdOut.clearComments( true ).clearFlushToken( true );
} catch ( X_SRDErrors const& e ) { try {
WriteSRDErrors( "SCRIPT" , e.errors ); T_SRDTextReader srdReader{ srdOut };
exit( EXIT_FAILURE ); T_FileInputStream fis{ input };
srdReader.read( inputName , fis );
} catch ( X_StreamError const& e ) {
fprintf( stderr , "===== SCRIPT\n" );
PrintStreamError( "Could not open" , inputName , e );
exit( EXIT_FAILURE );
} catch ( X_SRDErrors const& e ) {
WriteSRDErrors( "SCRIPT" , e.errors );
exit( EXIT_FAILURE );
}
} }
// Parse // Parse script
M_LOGSTR( "Parsing script" , 1 );
T_OpsParser parser; T_OpsParser parser;
parser.setLogger( logger ); parser.setLogger( logger );
if ( !parser.parse( srdOut.list( ) ) ) { if ( !parser.parse( srdOut.list( ) ) ) {
T_StringBuilder sb; WriteSRDErrors( "SCRIPT" , parser.errors( ) );
for ( auto const& err : parser.errors( ) ) { exit( EXIT_FAILURE );
WriteSRDError( sb , err );
}
sb << "Parser failed\n" << '\0';
fprintf( stderr , "%s" , sb.data( ) );
return 3;
} }
auto parsed{ parser.result( ) }; auto parsed{ parser.result( ) };
// Optimize // Optimize
if ( cfg.optimize ) { if ( cfg.optimize ) {
M_LOGSTR( "Optimizing script tree" , 1 );
opopt::T_OptData od; opopt::T_OptData od;
od.logger = logger; od.logger = logger;
if ( !cfg.resolutionChooser && cfg.cfFixedSize ) { if ( !cfg.resolutionChooser && cfg.cfFixedSize ) {
@ -251,7 +266,9 @@ int main( int argc , char** argv )
} }
// Compile // Compile
M_LOGSTR( "Compiling script" , 1 );
T_OpsCompiler compiler; T_OpsCompiler compiler;
compiler.setLogger( logger );
compiler.compile( *parsed ); compiler.compile( *parsed );
return 0; return 0;
} }