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 "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( [&]( ) {
|
||||||
|
T_StringBuilder sb , temp;
|
||||||
|
sb << "...... Compiled function " << func.name( );
|
||||||
for ( auto i = 0u ; i < output->ops.sizeOf( cfi ) ; i ++ ) {
|
for ( auto i = 0u ; i < output->ops.sizeOf( cfi ) ; i ++ ) {
|
||||||
temp << "(" << output->ops.get( cfi , i ) << ")";
|
temp << "(" << output->ops.get( cfi , i ) << ")";
|
||||||
while ( temp.length( ) < 30 ) {
|
while ( temp.length( ) < 30 ) {
|
||||||
temp << ' ';
|
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( );
|
temp.clear( );
|
||||||
}
|
}
|
||||||
dump << '\t' << output->ops.sizeOf( cfi ) << " instructions\n"
|
return sb;
|
||||||
<< '\0';
|
} , 4 );
|
||||||
printf( "%s" , dump.data( ) );
|
logger( [&]( ) {
|
||||||
|
T_StringBuilder sb;
|
||||||
|
sb << "...... " << output->ops.sizeOf( cfi )
|
||||||
|
<< " 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;
|
||||||
|
char temp[ 9 ];
|
||||||
|
sb << constants.size( ) << " constants\n\t";
|
||||||
for ( auto i = 0u ; i < constants.size( ) ; i ++ ) {
|
for ( auto i = 0u ; i < constants.size( ) ; i ++ ) {
|
||||||
printf( " %08x" , constants[ i ] );
|
snprintf( temp , 9 , "%08x" , constants[ i ] );
|
||||||
if ( i % 4 == 3 ) {
|
sb << " " << temp;
|
||||||
printf( "\n" );
|
if ( i % 4 == 3 && i != constants.size( ) - 1 ) {
|
||||||
|
sb << "\n\t";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( constants.size( ) % 4 ) {
|
return sb;
|
||||||
printf( "\n" );
|
} , 3 );
|
||||||
}
|
|
||||||
#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,27 +290,29 @@ 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 );
|
||||||
|
logger( [&]() {
|
||||||
|
T_StringBuilder sb;
|
||||||
T_Array< uint32_t > indices( locations.size( ) );
|
T_Array< uint32_t > indices( locations.size( ) );
|
||||||
indices.ensureCapacity( locations.size( ) );
|
indices.ensureCapacity( locations.size( ) );
|
||||||
for ( auto i = 0u ; i < locations.size( ) ; i ++ ) {
|
for ( auto i = 0u ; i < locations.size( ) ; i ++ ) {
|
||||||
|
@ -299,16 +323,13 @@ void T_CompilerImpl_::countAssets( ) noexcept
|
||||||
locations.values( )[ a ] ,
|
locations.values( )[ a ] ,
|
||||||
locations.values( )[ b ] );
|
locations.values( )[ b ] );
|
||||||
} );
|
} );
|
||||||
T_StringBuilder lmap;
|
sb << "... Location map (constants not included)";
|
||||||
lmap << "location map (constants not included)\n";
|
|
||||||
for ( auto idx : indices ) {
|
for ( auto idx : indices ) {
|
||||||
lmap << '\t' << locations.values( )[ idx ]
|
sb << "\n\t" << locations.values( )[ idx ]
|
||||||
<< '\t' << locations.keys( )[ idx ]
|
<< '\t' << locations.keys( )[ idx ];
|
||||||
<< '\n';
|
|
||||||
}
|
}
|
||||||
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(
|
||||||
|
|
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
|
// 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
28
c-opopt.cc
28
c-opopt.cc
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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( ) );
|
||||||
|
|
61
m-builder.cc
61
m-builder.cc
|
@ -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,8 +200,18 @@ 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;
|
||||||
|
{
|
||||||
|
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 );
|
srdOut.clearComments( true ).clearFlushToken( true );
|
||||||
try {
|
try {
|
||||||
T_SRDTextReader srdReader{ srdOut };
|
T_SRDTextReader srdReader{ srdOut };
|
||||||
|
@ -203,28 +220,26 @@ int main( int argc , char** argv )
|
||||||
} catch ( X_StreamError const& e ) {
|
} catch ( X_StreamError const& e ) {
|
||||||
fprintf( stderr , "===== SCRIPT\n" );
|
fprintf( stderr , "===== SCRIPT\n" );
|
||||||
PrintStreamError( "Could not open" , inputName , e );
|
PrintStreamError( "Could not open" , inputName , e );
|
||||||
return 1;
|
exit( EXIT_FAILURE );
|
||||||
} catch ( X_SRDErrors const& e ) {
|
} catch ( X_SRDErrors const& e ) {
|
||||||
WriteSRDErrors( "SCRIPT" , e.errors );
|
WriteSRDErrors( "SCRIPT" , e.errors );
|
||||||
exit( EXIT_FAILURE );
|
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue