Builder tool - Logging
Added logging using F_OPLogger wherever there were traces.
This commit is contained in:
parent
da0d419fab
commit
c4ce6e90d7
5 changed files with 210 additions and 146 deletions
151
c-opcomp.cc
151
c-opcomp.cc
|
@ -3,19 +3,26 @@
|
|||
#include "c-opcomp.hh"
|
||||
#include <ebcl/Algorithms.hh>
|
||||
|
||||
//#define INVASIVE_TRACES
|
||||
|
||||
using namespace ebcl;
|
||||
using namespace ops;
|
||||
using namespace opast;
|
||||
|
||||
|
||||
#define M_LOGSTR_( S , L ) \
|
||||
logger( [](){ return T_StringBuilder{ S }; } , L )
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct T_CompilerImpl_
|
||||
{
|
||||
T_CompilerImpl_( F_OPLogger* logger ) noexcept
|
||||
: logger( *logger ) {}
|
||||
|
||||
P_OpProgram compile( T_OpsParserOutput const& input ) noexcept;
|
||||
|
||||
private:
|
||||
F_OPLogger& logger;
|
||||
T_Visitor< A_Node > astVisitor{ ASTVisitorBrowser };
|
||||
T_Set< uint32_t > constants{ UseTag< IndexBacked< > >( ) };
|
||||
T_KeyValueTable< T_String , uint32_t > locations;
|
||||
|
@ -107,53 +114,66 @@ P_OpProgram T_CompilerImpl_::compile(
|
|||
// and frame is always 1
|
||||
output->init = input->root.functionIndex( "*init*" );
|
||||
output->frame = input->root.functionIndex( "*frame*" );
|
||||
#ifdef INVASIVE_TRACES
|
||||
printf( "function indices\n\t%d\tinit\n\t%d\tframe\n" ,
|
||||
output->init , output->frame );
|
||||
#endif
|
||||
logger( [this]( ) {
|
||||
T_StringBuilder sb;
|
||||
sb << "Function indices\n\tinit: " << output->init
|
||||
<< "\n\tframe: " << output->frame;
|
||||
return sb;
|
||||
} , 3 );
|
||||
|
||||
// Compile each function
|
||||
#ifdef INVASIVE_TRACES
|
||||
uint32_t nInstr = 0;
|
||||
#endif
|
||||
uint32_t cfi;
|
||||
for ( cfi = 0u ; cfi < input->root.nFunctions( ) ; cfi ++ ) {
|
||||
output->ops.next( );
|
||||
auto& func( input->root.function( cfi ) );
|
||||
#ifdef INVASIVE_TRACES
|
||||
printf( "compiling function %s\n" ,
|
||||
func.name( ).toOSString( ).data( ) );
|
||||
#endif
|
||||
logger( [&]( ) {
|
||||
T_StringBuilder sb;
|
||||
sb << "... Compiling function " << func.name( );
|
||||
return sb;
|
||||
} , 3 );
|
||||
|
||||
sdMain = sdFPU = 0;
|
||||
astVisitor.visit( func ,
|
||||
[=]( A_Node& node , const bool exit ) -> bool {
|
||||
return compileNode( cfi , node , exit );
|
||||
} );
|
||||
#ifdef INVASIVE_TRACES
|
||||
T_StringBuilder dump , temp;
|
||||
|
||||
logger( [&]( ) {
|
||||
T_StringBuilder sb , temp;
|
||||
sb << "...... Compiled function " << func.name( );
|
||||
for ( auto i = 0u ; i < output->ops.sizeOf( cfi ) ; i ++ ) {
|
||||
temp << "(" << output->ops.get( cfi , i ) << ")";
|
||||
while ( temp.length( ) < 30 ) {
|
||||
temp << ' ';
|
||||
}
|
||||
dump << "\t\t" << temp << "{ " << output->ops.get( cfi , i ).location << " }\n";
|
||||
sb << "\n\t\t" << temp << "{ "
|
||||
<< output->ops.get( cfi , i ).location
|
||||
<< " }";
|
||||
temp.clear( );
|
||||
}
|
||||
dump << '\t' << output->ops.sizeOf( cfi ) << " instructions\n"
|
||||
<< '\0';
|
||||
printf( "%s" , dump.data( ) );
|
||||
return sb;
|
||||
} , 4 );
|
||||
logger( [&]( ) {
|
||||
T_StringBuilder sb;
|
||||
sb << "...... " << output->ops.sizeOf( cfi )
|
||||
<< " instructions";
|
||||
return sb;
|
||||
} , 3 );
|
||||
nInstr += output->ops.sizeOf( cfi );
|
||||
#endif
|
||||
}
|
||||
#ifdef INVASIVE_TRACES
|
||||
printf( "total %d instructions\n" , nInstr );
|
||||
#endif
|
||||
logger( [=]( ) {
|
||||
T_StringBuilder sb;
|
||||
sb << "... Generated " << nInstr << " instructions";
|
||||
return sb;
|
||||
} , 2 );
|
||||
|
||||
return std::move( output );
|
||||
}
|
||||
|
||||
void T_CompilerImpl_::gatherConstants( ) noexcept
|
||||
{
|
||||
M_LOGSTR_( "... Gathering constants" , 2 );
|
||||
constants.clear( );
|
||||
astVisitor.visit( input->root , [&]( A_Node& node , const bool exit ) {
|
||||
if ( exit ) {
|
||||
|
@ -175,22 +195,24 @@ void T_CompilerImpl_::gatherConstants( ) noexcept
|
|||
output->constants.add( constants[ i ] );
|
||||
}
|
||||
|
||||
#ifdef INVASIVE_TRACES
|
||||
printf( "%d constants\n" , constants.size( ) );
|
||||
logger( [&]() {
|
||||
T_StringBuilder sb;
|
||||
char temp[ 9 ];
|
||||
sb << constants.size( ) << " constants\n\t";
|
||||
for ( auto i = 0u ; i < constants.size( ) ; i ++ ) {
|
||||
printf( " %08x" , constants[ i ] );
|
||||
if ( i % 4 == 3 ) {
|
||||
printf( "\n" );
|
||||
snprintf( temp , 9 , "%08x" , constants[ i ] );
|
||||
sb << " " << temp;
|
||||
if ( i % 4 == 3 && i != constants.size( ) - 1 ) {
|
||||
sb << "\n\t";
|
||||
}
|
||||
}
|
||||
if ( constants.size( ) % 4 ) {
|
||||
printf( "\n" );
|
||||
}
|
||||
#endif
|
||||
return sb;
|
||||
} , 3 );
|
||||
}
|
||||
|
||||
void T_CompilerImpl_::countAssets( ) noexcept
|
||||
{
|
||||
M_LOGSTR_( "... Counting resources" , 2 );
|
||||
locations.clear( );
|
||||
locations.add( T_String::Pooled( "time" ) , 0u );
|
||||
locations.add( T_String::Pooled( "width" ) , 1u );
|
||||
|
@ -268,27 +290,29 @@ void T_CompilerImpl_::countAssets( ) noexcept
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef INVASIVE_TRACES
|
||||
printf( "assets\n\t%d framebuffers\n\t%d pipelines\n"
|
||||
"\t%d programs\n\t%d samplers\n\t%d textures\n"
|
||||
"\t%d variables\n\t%d inputs\n" ,
|
||||
output->nFramebuffers , output->nPipelines ,
|
||||
output->nPrograms , output->nSamplers ,
|
||||
output->nTextures , output->nVariables ,
|
||||
output->inputs.size( ) );
|
||||
printf( "table ranges\n\t0\t2\tBuilt-ins\n"
|
||||
"\t3\t%d\tConstants\n"
|
||||
"\t%d\t%d\tVariables\n"
|
||||
"\t%d\t%d\tFramebuffers\n"
|
||||
"\t%d\t%d\tPipelines\n"
|
||||
"\t%d\t%d\tPrograms\n"
|
||||
"\t%d\t%d\tSamplers\n"
|
||||
"\t%d\t%d\tTextures\n" ,
|
||||
fiVariables - 1 , fiVariables , fiFramebuffers - 1 , fiFramebuffers ,
|
||||
fiPipelines - 1 , fiPipelines , fiPrograms - 1 , fiPrograms ,
|
||||
fiSamplers - 1 , fiSamplers , fiTextures - 1 , fiTextures ,
|
||||
fiTextures + output->nTextures - 1 );
|
||||
|
||||
logger( [&]() {
|
||||
T_StringBuilder sb;
|
||||
sb << "... Resource counts:\n"
|
||||
<< "\t\tFramebuffers:\t" << output->nFramebuffers << '\n'
|
||||
<< "\t\tPipelines: \t" << output->nPipelines << '\n'
|
||||
<< "\t\tPrograms: \t" << output->nPrograms << '\n'
|
||||
<< "\t\tSamplers: \t" << output->nSamplers << '\n'
|
||||
<< "\t\tTextures: \t" << output->nTextures << '\n'
|
||||
<< "\t\tInputs: \t" << output->inputs.size( ) << '\n'
|
||||
<< "\tTable ranges:\n"
|
||||
<< "\t\tBuilt-ins \t0\t2\n"
|
||||
<< "\t\tConstants \t3\t" << fiVariables - 1 << '\n'
|
||||
<< "\t\tVariables \t" << fiVariables << '\t' << fiFramebuffers - 1 << '\n'
|
||||
<< "\t\tFramebuffers \t" << fiFramebuffers << '\t' << fiPipelines - 1 << '\n'
|
||||
<< "\t\tPipelines \t" << fiPipelines << '\t' << fiPrograms - 1 << '\n'
|
||||
<< "\t\tPrograms \t" << fiPrograms << '\t' << fiSamplers - 1 << '\n'
|
||||
<< "\t\tSamplers \t" << fiSamplers << '\t' << fiTextures - 1 << '\n'
|
||||
<< "\t\tTextures \t" << fiTextures << '\t' << fiTextures + output->nTextures - 1
|
||||
;
|
||||
return sb;
|
||||
} , 3 );
|
||||
logger( [&]() {
|
||||
T_StringBuilder sb;
|
||||
T_Array< uint32_t > indices( locations.size( ) );
|
||||
indices.ensureCapacity( locations.size( ) );
|
||||
for ( auto i = 0u ; i < locations.size( ) ; i ++ ) {
|
||||
|
@ -299,16 +323,13 @@ void T_CompilerImpl_::countAssets( ) noexcept
|
|||
locations.values( )[ a ] ,
|
||||
locations.values( )[ b ] );
|
||||
} );
|
||||
T_StringBuilder lmap;
|
||||
lmap << "location map (constants not included)\n";
|
||||
sb << "... Location map (constants not included)";
|
||||
for ( auto idx : indices ) {
|
||||
lmap << '\t' << locations.values( )[ idx ]
|
||||
<< '\t' << locations.keys( )[ idx ]
|
||||
<< '\n';
|
||||
sb << "\n\t" << locations.values( )[ idx ]
|
||||
<< '\t' << locations.keys( )[ idx ];
|
||||
}
|
||||
lmap << '\0';
|
||||
printf( "%s" , lmap.data( ) );
|
||||
#endif
|
||||
return sb;
|
||||
} , 4 );
|
||||
}
|
||||
|
||||
bool T_CompilerImpl_::compileNode(
|
||||
|
@ -873,12 +894,12 @@ void T_CompilerImpl_::applyStackEffects(
|
|||
const auto m( DeltaMainStack( op.op ) );
|
||||
const auto f( DeltaFPUStack( op.op ) );
|
||||
|
||||
#ifdef INVASIVE_TRACES
|
||||
logger( [&]() {
|
||||
T_StringBuilder sb;
|
||||
sb << "applying stack effects for (" << op << ") - sdMain " << sdMain
|
||||
<< " (" << m << ") sdFPU " << sdFPU << " (" << f << ")" << '\n' << '\0';
|
||||
printf( "%s" , sb.data( ) );
|
||||
#endif
|
||||
<< " (" << m << ") sdFPU " << sdFPU << " (" << f << ')';
|
||||
return sb;
|
||||
} , 5 );
|
||||
|
||||
if ( m ) {
|
||||
assert( m > 0 || sdMain >= uint32_t( -m ) );
|
||||
|
@ -897,7 +918,7 @@ void T_CompilerImpl_::applyStackEffects(
|
|||
/*= T_OpsCompiler ==============================================================*/
|
||||
|
||||
T_OpsCompiler::T_OpsCompiler( ) noexcept
|
||||
: A_PrivateImplementation( new T_CompilerImpl_( ) )
|
||||
: A_PrivateImplementation( new T_CompilerImpl_( &logger_ ) )
|
||||
{ }
|
||||
|
||||
P_OpProgram T_OpsCompiler::compile(
|
||||
|
|
12
c-opcomp.hh
12
c-opcomp.hh
|
@ -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
|
||||
class T_OpsCompiler : public ebcl::A_PrivateImplementation
|
||||
{
|
||||
private:
|
||||
F_OPLogger logger_{ []( auto , auto ) { } };
|
||||
|
||||
public:
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
28
c-opopt.cc
28
c-opopt.cc
|
@ -9,6 +9,10 @@ using namespace opast;
|
|||
using namespace opopt;
|
||||
|
||||
|
||||
#define M_LOGSTR_( S , L ) \
|
||||
oData.logger( [](){ return T_StringBuilder{ S }; } , L )
|
||||
|
||||
|
||||
/*= T_OptData ================================================================*/
|
||||
|
||||
void T_OptData::findInputDecls(
|
||||
|
@ -140,7 +144,7 @@ template<
|
|||
T_StringBuilder sb;
|
||||
sb << "substituting node at " << child.location( );
|
||||
return sb;
|
||||
} , 2 );
|
||||
} , 3 );
|
||||
r->location( ) = node.location( );
|
||||
set( node , std::move( r ) );
|
||||
didFold = true;
|
||||
|
@ -235,17 +239,13 @@ P_ExpressionNode T_ConstantFolder_::doIdExpr(
|
|||
}
|
||||
|
||||
if ( node.id( ) == "width" ) {
|
||||
oData.logger( []{
|
||||
return T_StringBuilder{ "replacing $width with fixed width" };
|
||||
} , 2 );
|
||||
M_LOGSTR_( "replacing $width with fixed width" , 3 );
|
||||
return NewOwned< T_ConstantExprNode >( node.parent( ) ,
|
||||
double( oData.fixedSize->first ) );
|
||||
}
|
||||
|
||||
if ( node.id( ) == "height" ) {
|
||||
oData.logger( []{
|
||||
return T_StringBuilder{ "replacing $height with fixed height" };
|
||||
} , 2 );
|
||||
M_LOGSTR_( "replacing $height with fixed height" , 3 );
|
||||
return NewOwned< T_ConstantExprNode >( node.parent( ) ,
|
||||
float( oData.fixedSize->second ) );
|
||||
}
|
||||
|
@ -374,9 +374,7 @@ bool opopt::FoldConstants(
|
|||
T_OptData& oData ) noexcept
|
||||
{
|
||||
T_ConstantFolder_ folder{ oData };
|
||||
oData.logger( []() {
|
||||
return T_StringBuilder{ "constant folding pass" };
|
||||
} , 1 );
|
||||
M_LOGSTR_( "... Folding constants" , 2 );
|
||||
if ( oData.curves ) {
|
||||
oData.findInputDecls( program );
|
||||
}
|
||||
|
@ -384,10 +382,12 @@ bool opopt::FoldConstants(
|
|||
return folder( n , x );
|
||||
} );
|
||||
oData.logger( [&]() {
|
||||
return T_StringBuilder{
|
||||
folder.didFold ? "some constants were folded"
|
||||
: "no constants were folded" };
|
||||
} , 1 );
|
||||
T_StringBuilder sb{ "...... " };
|
||||
sb << ( folder.didFold
|
||||
? "Some constants were folded"
|
||||
: "No constants were folded" );
|
||||
return sb;
|
||||
} , 2 );
|
||||
return folder.didFold;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,11 @@ using namespace ebcl;
|
|||
using namespace opast;
|
||||
|
||||
|
||||
#define M_LOGSTR_( S , L ) \
|
||||
logger( [](){ return T_StringBuilder{ S }; } , L )
|
||||
|
||||
|
||||
|
||||
/*= T_Parser =================================================================*/
|
||||
|
||||
namespace {
|
||||
|
@ -308,7 +313,7 @@ inline T_ParserImpl_::T_ParserImpl_(
|
|||
T_Array< T_SRDError >* const errors ,
|
||||
T_OwnPtr< T_OpsParserOutput >* const output ,
|
||||
F_OPLogger* logger ) noexcept
|
||||
: output( *output ) , errors( *errors ) , logger( *logger ) ,
|
||||
: output( *output ) , errors( *errors ) , logger{ *logger } ,
|
||||
ovParserConfig( sov::GetParserConfig( ) ) ,
|
||||
ovParser( ovParserConfig )
|
||||
{ }
|
||||
|
@ -334,6 +339,7 @@ void T_ParserImpl_::main(
|
|||
bool T_ParserImpl_::checkRequiredBlocks(
|
||||
T_SRDList const& input ) noexcept
|
||||
{
|
||||
M_LOGSTR_( "... Checking for required blocks" , 2 );
|
||||
const T_SRDLocation missingErrLoc( ([&input]() {
|
||||
if ( input.size( ) != 0 ) {
|
||||
return T_SRDLocation( input[ 0 ].location( ).source( ) , 1 , 1 );
|
||||
|
@ -354,6 +360,7 @@ bool T_ParserImpl_::checkRequiredBlocks(
|
|||
*/
|
||||
bool T_ParserImpl_::checkCalls( ) noexcept
|
||||
{
|
||||
M_LOGSTR_( "... Gathering/checking calls" , 2 );
|
||||
calls.clear( );
|
||||
uint32_t cfi;
|
||||
for ( cfi = 0 ; cfi < output->root.nFunctions( ) ; cfi ++ ) {
|
||||
|
@ -399,6 +406,7 @@ bool T_ParserImpl_::checkCalls( ) noexcept
|
|||
*/
|
||||
bool T_ParserImpl_::checkInstructionRestrictions( ) noexcept
|
||||
{
|
||||
M_LOGSTR_( "... Checking instruction restrictions" , 2 );
|
||||
callInfo.clear( );
|
||||
callInfo.resize( calls.size( ) );
|
||||
|
||||
|
@ -449,6 +457,7 @@ bool T_ParserImpl_::checkInstructionRestrictions( ) noexcept
|
|||
*/
|
||||
bool T_ParserImpl_::checkLocalVariables( ) noexcept
|
||||
{
|
||||
M_LOGSTR_( "... Checking local variables" , 2 );
|
||||
uint32_t cfi;
|
||||
T_StringBuilder esb;
|
||||
for ( cfi = 0 ; cfi < output->root.nFunctions( ) ; cfi ++ ) {
|
||||
|
@ -486,6 +495,8 @@ bool T_ParserImpl_::checkLocalVariables( ) noexcept
|
|||
*/
|
||||
bool T_ParserImpl_::collectGlobalTypes( ) noexcept
|
||||
{
|
||||
M_LOGSTR_( "... Collecting global declaration types" , 2 );
|
||||
|
||||
// Temporary table for type / first declaration location
|
||||
struct T_Decl_ {
|
||||
E_DataType type;
|
||||
|
@ -538,7 +549,7 @@ bool T_ParserImpl_::collectGlobalTypes( ) noexcept
|
|||
T_StringBuilder sb;
|
||||
sb << "id " << id << " as " << dt << " at " << location;
|
||||
return sb;
|
||||
} , 2 );
|
||||
} , 3 );
|
||||
|
||||
// When we find a set instruction, we need to check whether
|
||||
// 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
|
||||
{
|
||||
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
|
||||
const auto nFunctions( output->root.nFunctions( ) );
|
||||
|
@ -629,12 +640,12 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
|
|||
} );
|
||||
}
|
||||
|
||||
#define TRACE( x ) \
|
||||
#define M_TRACE_( l , x ) \
|
||||
logger( [&]{ \
|
||||
T_StringBuilder sb; \
|
||||
sb << x; \
|
||||
return sb; \
|
||||
} , 2 )
|
||||
} , l )
|
||||
|
||||
T_StringBuilder esb;
|
||||
bool changed = true;
|
||||
|
@ -645,13 +656,13 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
|
|||
// resolved and check all calls.
|
||||
for ( auto i = 0u ; i < nFunctions ; 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 ] ) {
|
||||
TRACE( " -> arguments not resolved, skipped" );
|
||||
M_TRACE_( 3 , " -> arguments not resolved, skipped" );
|
||||
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 ++ ) {
|
||||
auto const* call( callInstuctions.get( i , c ) );
|
||||
if ( ! call ) {
|
||||
|
@ -662,13 +673,13 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
|
|||
const auto calledIdx( output->root.functionIndex( called ) );
|
||||
auto& calledFn( dynamic_cast< T_FuncNode& >(
|
||||
output->root.function( calledIdx ) ) );
|
||||
TRACE( " -> checking call to " << called << " (idx " << calledIdx
|
||||
M_TRACE_( 4 , " -> checking call to " << called << " (idx " << calledIdx
|
||||
<< ") at " << call->location( ) );
|
||||
assert( call->arguments( ) == calledFn.arguments( ) );
|
||||
if ( argsResolved[ calledIdx ] ) {
|
||||
TRACE( " argument types already resolved, checking" );
|
||||
M_TRACE_( 4 , " argument types already resolved, checking" );
|
||||
} else {
|
||||
TRACE( " resolving arguments" );
|
||||
M_TRACE_( 4 , " resolving arguments" );
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
|
@ -686,7 +697,7 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
|
|||
} else {
|
||||
ndt = E_DataType::VARIABLE;
|
||||
}
|
||||
TRACE( " [" << a << "] " << ndt );
|
||||
M_TRACE_( 4 , " [" << a << "] " << ndt );
|
||||
|
||||
// Arguments not resolved -> try setting the argument's type
|
||||
if ( !argsResolved[ calledIdx ] ) {
|
||||
|
@ -718,6 +729,8 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
|
|||
|
||||
bool T_ParserImpl_::checkIdentifiers( ) noexcept
|
||||
{
|
||||
M_LOGSTR_( "... Checking command argument types" , 2 );
|
||||
|
||||
uint32_t cfi;
|
||||
T_StringBuilder esb;
|
||||
for ( cfi = 0 ; cfi < output->root.nFunctions( ) ; cfi ++ ) {
|
||||
|
@ -914,6 +927,7 @@ E_DataType T_ParserImpl_::getTypeOf(
|
|||
bool T_ParserImpl_::parseTopLevel(
|
||||
T_SRDList const& input ) noexcept
|
||||
{
|
||||
M_LOGSTR_( "... Generating tree" , 2 );
|
||||
for ( auto const& t : input ) {
|
||||
if ( t.type( ) == E_SRDTokenType::LIST && t.list( ).size( ) > 0 ) {
|
||||
parseFunction( t.list( ) );
|
||||
|
|
61
m-builder.cc
61
m-builder.cc
|
@ -14,6 +14,9 @@
|
|||
using namespace ebcl;
|
||||
using namespace opast;
|
||||
|
||||
#define M_LOGSTR( S , L ) \
|
||||
logger( [](){ return T_StringBuilder{ S }; } , L )
|
||||
|
||||
namespace {
|
||||
|
||||
const struct option CmdLineOpts_[] = {
|
||||
|
@ -72,6 +75,20 @@ void WriteSRDErrors(
|
|||
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 const& path ,
|
||||
char const* const name ) noexcept
|
||||
|
@ -137,7 +154,7 @@ int main( int argc , char** argv )
|
|||
} };
|
||||
|
||||
// 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_BuildConfiguration cfg{ [&]() {
|
||||
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
|
||||
logger( [](){ return T_StringBuilder{ "Loading curves data" }; } , 1 );
|
||||
M_LOGSTR( "Loading curves data" , 1 );
|
||||
const T_String curvesFile{ FilePath( oSrcPath , "curves.srd" ) };
|
||||
T_SyncCurvesIO::T_Data p;
|
||||
try {
|
||||
|
@ -193,8 +200,18 @@ int main( int argc , char** argv )
|
|||
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_File input( inputName , E_FileMode::READ_ONLY );
|
||||
try {
|
||||
input.open( );
|
||||
} catch ( X_StreamError const& e ) {
|
||||
PrintStreamError( "Could not open" , inputName , e );
|
||||
return 1;
|
||||
}
|
||||
srdOut.clearComments( true ).clearFlushToken( true );
|
||||
try {
|
||||
T_SRDTextReader srdReader{ srdOut };
|
||||
|
@ -203,28 +220,26 @@ int main( int argc , char** argv )
|
|||
} catch ( X_StreamError const& e ) {
|
||||
fprintf( stderr , "===== SCRIPT\n" );
|
||||
PrintStreamError( "Could not open" , inputName , e );
|
||||
return 1;
|
||||
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;
|
||||
parser.setLogger( logger );
|
||||
if ( !parser.parse( srdOut.list( ) ) ) {
|
||||
T_StringBuilder sb;
|
||||
for ( auto const& err : parser.errors( ) ) {
|
||||
WriteSRDError( sb , err );
|
||||
}
|
||||
sb << "Parser failed\n" << '\0';
|
||||
fprintf( stderr , "%s" , sb.data( ) );
|
||||
return 3;
|
||||
WriteSRDErrors( "SCRIPT" , parser.errors( ) );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
auto parsed{ parser.result( ) };
|
||||
|
||||
// Optimize
|
||||
if ( cfg.optimize ) {
|
||||
M_LOGSTR( "Optimizing script tree" , 1 );
|
||||
opopt::T_OptData od;
|
||||
od.logger = logger;
|
||||
if ( !cfg.resolutionChooser && cfg.cfFixedSize ) {
|
||||
|
@ -251,7 +266,9 @@ int main( int argc , char** argv )
|
|||
}
|
||||
|
||||
// Compile
|
||||
M_LOGSTR( "Compiling script" , 1 );
|
||||
T_OpsCompiler compiler;
|
||||
compiler.setLogger( logger );
|
||||
compiler.compile( *parsed );
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue