Scripting - Includes work!

This commit is contained in:
Emmanuel BENOîT 2017-12-28 10:27:23 +01:00
parent 68f6c49066
commit 542e791199
10 changed files with 164 additions and 56 deletions

2
3rdparty/ebcl vendored

@ -1 +1 @@
Subproject commit 5497856be2761a6f4f1848636304cff134668766 Subproject commit 7b97993448d086a92d9875db2c2815afa249ba65

View file

@ -1,4 +1,6 @@
#include "externals.hh" #include "externals.hh"
#include "common.hh"
#include "c-project.hh"
#include "c-buildcfg.hh" #include "c-buildcfg.hh"
#include <ebcl/Files.hh> #include <ebcl/Files.hh>
@ -159,11 +161,12 @@ T_SRDParserConfig BCLInitDefinitions_( ) noexcept
struct T_BCLImpl_ struct T_BCLImpl_
{ {
const T_String fileName{ T_String::Pooled( "build.srd" ) };
T_SRDParserConfig pConfig; T_SRDParserConfig pConfig;
T_BCLImpl_( ) noexcept; T_BCLImpl_( ) noexcept;
T_BuildConfigurations load( T_String const& path ); T_BuildConfigurations load( );
}; };
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -172,16 +175,16 @@ T_BCLImpl_::T_BCLImpl_( ) noexcept
: pConfig{ BCLInitDefinitions_( ) } : pConfig{ BCLInitDefinitions_( ) }
{ } { }
T_BuildConfigurations T_BCLImpl_::load( T_BuildConfigurations T_BCLImpl_::load( )
T_String const& path )
{ {
// TODO: keep errors so we get warnings/notes too // TODO: keep errors so we get warnings/notes too
T_SRDParser parser{ pConfig }; T_SRDParser parser{ pConfig };
T_SRDTextReader srdReader{ parser }; T_SRDTextReader srdReader{ parser };
T_File input{ path , E_FileMode::READ_ONLY }; T_File input{ Common::Project( ).pathOf( fileName ) ,
E_FileMode::READ_ONLY };
T_FileInputStream fis{ input }; T_FileInputStream fis{ input };
srdReader.read( path , fis ); srdReader.read( fileName , fis );
return std::move( *parser.getData< T_SharedPtr< T_BuildConfigurations > >( ) ); return std::move( *parser.getData< T_SharedPtr< T_BuildConfigurations > >( ) );
} }
@ -195,8 +198,7 @@ T_BuildConfigurationLoader::T_BuildConfigurationLoader( ) noexcept
{ } { }
T_BuildConfigurations T_BuildConfigurationLoader::load( T_BuildConfigurations T_BuildConfigurationLoader::load( )
T_String const& path )
{ {
return p< T_BCLImpl_ >( ).load( path ); return p< T_BCLImpl_ >( ).load( );
} }

View file

@ -50,7 +50,7 @@ struct T_BuildConfigurationLoader : public ebcl::A_PrivateImplementation
// Load build configurations from the specified path; may throw // Load build configurations from the specified path; may throw
// X_StreamError or X_SRDErrors // X_StreamError or X_SRDErrors
T_BuildConfigurations load( T_String const& path ); T_BuildConfigurations load( );
}; };
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/

View file

@ -6,7 +6,9 @@
#include "c-syncoverrides.hh" #include "c-syncoverrides.hh"
#include <ebcl/Algorithms.hh> #include <ebcl/Algorithms.hh>
#include <ebcl/Files.hh>
#include <ebcl/SRDParser.hh> #include <ebcl/SRDParser.hh>
#include <ebcl/SRDText.hh>
using namespace ebcl; using namespace ebcl;
using namespace opast; using namespace opast;
@ -172,8 +174,9 @@ struct T_ParserImpl_
T_SRDParserConfig ovParserConfig; T_SRDParserConfig ovParserConfig;
T_SRDParser ovParser; T_SRDParser ovParser;
T_String curFile; T_FSPath curFile;
T_AutoArray< T_String , 32 > inclStack; T_FSPath baseDir;
T_AutoArray< T_FSPath , 32 > inclStack;
T_Visitor< A_Node > visitor{ opast::ASTVisitorBrowser }; T_Visitor< A_Node > visitor{ opast::ASTVisitorBrowser };
T_Visitor< uint32_t , uint32_t > callGraphVisitor{ T_Visitor< uint32_t , uint32_t > callGraphVisitor{
@ -192,7 +195,8 @@ struct T_ParserImpl_
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
void main( T_SRDList const& list ) noexcept; void main( T_FSPath const& file ,
T_SRDList const& list ) noexcept;
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -221,7 +225,8 @@ struct T_ParserImpl_
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
bool parseTopLevel( T_SRDList const& list ) noexcept; bool parseTopLevel( T_SRDList const& list ) noexcept;
void parseTLList( T_SRDList const& funcList ) noexcept; void parseTLList( T_SRDList const& list ) noexcept;
void parseTLListItem( T_SRDList const& funcList ) noexcept;
void handleInclude( T_SRDToken const& tFileName ) noexcept; void handleInclude( T_SRDToken const& tFileName ) noexcept;
@ -331,8 +336,12 @@ inline T_ParserImpl_::T_ParserImpl_(
{ } { }
void T_ParserImpl_::main( void T_ParserImpl_::main(
T_FSPath const& file ,
T_SRDList const& input ) noexcept T_SRDList const& input ) noexcept
{ {
assert( file.isAbsolute( ) );
curFile = file.canonical( );
baseDir = file.parent( );
parseTopLevel( input ) parseTopLevel( input )
&& checkRequiredBlocks( input ) && checkRequiredBlocks( input )
&& checkCalls( ) && checkCalls( )
@ -948,18 +957,24 @@ bool T_ParserImpl_::parseTopLevel(
T_SRDList const& input ) noexcept T_SRDList const& input ) noexcept
{ {
M_LOGSTR_( "... Generating tree" , 2 ); M_LOGSTR_( "... Generating tree" , 2 );
for ( auto const& t : input ) { parseTLList( input );
if ( t.type( ) == E_SRDTokenType::LIST && t.list( ).size( ) > 0 ) {
parseTLList( t.list( ) );
} else {
errors.addNew( "top-level list expected" , t.location( ) );
}
}
return errors.empty( ); return errors.empty( );
} }
void T_ParserImpl_::parseTLList( void T_ParserImpl_::parseTLList(
T_SRDList const& input ) noexcept T_SRDList const& input ) noexcept
{
for ( auto const& t : input ) {
if ( t.type( ) == E_SRDTokenType::LIST && t.list( ).size( ) > 0 ) {
parseTLListItem( t.list( ) );
} else {
errors.addNew( "top-level list expected" , t.location( ) );
}
}
}
void T_ParserImpl_::parseTLListItem(
T_SRDList const& input ) noexcept
{ {
assert( input.size( ) != 0 ); assert( input.size( ) != 0 );
auto const& ft{ input[ 0 ] }; auto const& ft{ input[ 0 ] };
@ -970,7 +985,6 @@ void T_ParserImpl_::parseTLList(
auto const& fw{ ft.stringValue( ) }; auto const& fw{ ft.stringValue( ) };
if ( fw == "include" ) { if ( fw == "include" ) {
// TODO
if ( input.size( ) == 1 ) { if ( input.size( ) == 1 ) {
errors.addNew( "file name expected" , errors.addNew( "file name expected" ,
ft.location( ) ); ft.location( ) );
@ -999,14 +1013,78 @@ void T_ParserImpl_::handleInclude(
return; return;
} }
if ( !curFile ) { // Resolve included file path
curFile = tFileName.location( ).source( ); T_FSPath inclPath{ tFileName.stringValue( ) };
if ( !inclPath.isValid( ) ) {
errors.addNew( "invalid file name" ,
tFileName.location( ) );
return;
}
if ( !inclPath.isAbsolute( ) ) {
inclPath = curFile.parent( ) + inclPath;
}
inclPath = inclPath.canonical( );
if ( !inclPath.isUnder( baseDir ) ) {
errors.addNew( "file is not in the project's directory" ,
tFileName.location( ) );
return;
} }
// TODO: resolve included file path // Check for recursive includes
// TODO: check for recursive includes if ( inclStack.contains( inclPath ) ) {
// TODO: load file errors.addNew( "recursive file inclusion" ,
// TODO: parse it tFileName.location( ) );
return;
}
// Load file
const auto relPath{ inclPath.makeRelative( baseDir ) };
T_SRDMemoryTarget srdOut;
{
T_File input{ inclPath , E_FileMode::READ_ONLY };
try {
input.open( );
} catch ( X_StreamError const& e ) {
T_StringBuilder sb;
sb << "could not open '" << relPath << "': " << e.what( );
if ( e.code( ) == E_StreamError::SYSTEM_ERROR ) {
sb << " (error code " << e.systemError( ) << ")";
}
errors.addNew( std::move( sb ) , tFileName.location( ) );
return;
}
srdOut.clearComments( true ).clearFlushToken( true );
try {
T_SRDTextReader srdReader{ srdOut };
T_FileInputStream fis{ input };
srdReader.read( relPath.toString( ) , fis );
} catch ( X_StreamError const& e ) {
T_StringBuilder sb;
sb << "could not read '" << relPath << "': " << e.what( );
if ( e.code( ) == E_StreamError::SYSTEM_ERROR ) {
sb << " (error code " << e.systemError( ) << ")";
}
errors.addNew( std::move( sb ) , tFileName.location( ) );
return;
} catch ( X_SRDErrors const& e ) {
const auto ne{ e.errors.size( ) };
for ( auto i = 0u ; i < ne ; i ++ ) {
errors.add( e.errors[ i ] );
}
return;
}
}
// Parse included file
inclStack.add( curFile );
curFile = inclPath;
parseTLList( srdOut.list( ) );
curFile = inclStack.last( );
inclStack.removeLast( );
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -2224,6 +2302,6 @@ bool T_OpsParser::parse(
{ {
errors_.clear( ); errors_.clear( );
output_ = NewOwned< T_OpsParserOutput >( ); output_ = NewOwned< T_OpsParserOutput >( );
p< T_ParserImpl_ >( ).main( input ); p< T_ParserImpl_ >( ).main( filePath , input );
return errors_.empty( ); return errors_.empty( );
} }

View file

@ -24,22 +24,28 @@ struct CommonData_
{} {}
}; };
uint32_t Initialised_{ 0 };
std::aligned_storage_t< sizeof( CommonData_ ) , alignof( CommonData_ ) > Instance_; std::aligned_storage_t< sizeof( CommonData_ ) , alignof( CommonData_ ) > Instance_;
} // namespace <anon> } // namespace <anon>
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void Common::Init( Common::Common(
T_FSPath const& path ) noexcept T_FSPath const& path ) noexcept
{ {
if ( !Initialised_ ++ ) {
new ((char*)&Instance_) CommonData_( path ); new ((char*)&Instance_) CommonData_( path );
} }
}
void Common::Shutdown( ) noexcept Common::~Common( ) noexcept
{ {
assert( Initialised_ );
if ( !-- Initialised_ ) {
((CommonData_*)(char*)&Instance_)->~CommonData_( ); ((CommonData_*)(char*)&Instance_)->~CommonData_( );
} }
}
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/

View file

@ -13,8 +13,8 @@ class T_UndoManager;
struct Common struct Common
{ {
static void Init( T_FSPath const& path = {} ) noexcept; explicit Common( T_FSPath const& path = {} ) noexcept;
static void Shutdown( ) noexcept; ~Common( ) noexcept;
static T_Project& Project( ) noexcept; static T_Project& Project( ) noexcept;
static T_FilesWatcher& Watcher( ) noexcept; static T_FilesWatcher& Watcher( ) noexcept;

View file

@ -1,5 +1,6 @@
#include "externals.hh" #include "externals.hh"
#include "common.hh"
#include "c-opast.hh" #include "c-opast.hh"
#include "c-ops.hh" #include "c-ops.hh"
#include "c-opcomp.hh" #include "c-opcomp.hh"
@ -34,7 +35,13 @@ void PrintStreamError(
T_FSPath const& name , T_FSPath const& name ,
X_StreamError const& error ) noexcept X_StreamError const& error ) noexcept
{ {
const T_FSPath rp{ name.makeRelative( Filesystem::Cwd( ) ) }; const T_FSPath rp{ ([&]() {
if ( error.path( ) ) {
return *( error.path( ) );
}
return name;
}()).makeRelative( Filesystem::Cwd( ) ) };
T_StringBuilder sb; T_StringBuilder sb;
sb << prefix << " '" << rp << "': " << error.what( ); sb << prefix << " '" << rp << "': " << error.what( );
if ( error.code( ) == E_StreamError::SYSTEM_ERROR ) { if ( error.code( ) == E_StreamError::SYSTEM_ERROR ) {
@ -138,6 +145,8 @@ int main( int argc , char** argv )
} }
} }
// Initialise common layer
const T_FSPath srcPath{ ([&](){ const T_FSPath srcPath{ ([&](){
const T_FSPath raw{ oSrcPath }; const T_FSPath raw{ oSrcPath };
if ( !raw.isAbsolute( ) ) { if ( !raw.isAbsolute( ) ) {
@ -149,6 +158,7 @@ int main( int argc , char** argv )
fprintf( stderr , "Invalid source path\n" ); fprintf( stderr , "Invalid source path\n" );
return EXIT_FAILURE; return EXIT_FAILURE;
} }
Common common{ srcPath };
// Logger setup // Logger setup
const uint32_t logLevel{ oLogLevel ? *oLogLevel : 0 }; const uint32_t logLevel{ oLogLevel ? *oLogLevel : 0 };
@ -163,11 +173,11 @@ int main( int argc , char** argv )
// Build configurations // Build configurations
M_LOGSTR( "Loading build configurations" , 1 ); M_LOGSTR( "Loading build configurations" , 1 );
const auto bcfgFile{ FilePath( srcPath , "build.srd" ) };
const T_BuildConfiguration cfg{ [&]() { const T_BuildConfiguration cfg{ [&]() {
try { try {
T_BuildConfigurationLoader bcfgLoader; T_BuildConfigurations cfs{
T_BuildConfigurations cfs{ bcfgLoader.load( bcfgFile.toString( ) ) }; T_BuildConfigurationLoader{ }.load( )
};
if ( oBuildCfg && !cfs.contains( oBuildCfg ) ) { if ( oBuildCfg && !cfs.contains( oBuildCfg ) ) {
fprintf( stderr , "===== BUILD CONFIGURATIONS\n" ); fprintf( stderr , "===== BUILD CONFIGURATIONS\n" );
fprintf( stderr , "Build configuration not found\n" ); fprintf( stderr , "Build configuration not found\n" );
@ -183,7 +193,9 @@ int main( int argc , char** argv )
} catch ( X_StreamError const& e ) { } catch ( X_StreamError const& e ) {
fprintf( stderr , "===== BUILD CONFIGURATIONS\n" ); fprintf( stderr , "===== BUILD CONFIGURATIONS\n" );
PrintStreamError( "Could not open" , bcfgFile , e ); PrintStreamError( "Could not open" ,
Common::Project( ).pathOf( "build.srd" ) ,
e );
exit( EXIT_FAILURE ); exit( EXIT_FAILURE );
} catch ( X_SRDErrors const& e ) { } catch ( X_SRDErrors const& e ) {
@ -210,24 +222,25 @@ int main( int argc , char** argv )
// Open and load script // Open and load script
M_LOGSTR( "Loading script" , 1 ); M_LOGSTR( "Loading script" , 1 );
const auto inputName{ FilePath( srcPath , "demo.srd" ) }; char const* const scriptName{ "demo.srd" };
const auto scriptPath{ Common::Project( ).pathOf( scriptName ) };
T_SRDMemoryTarget srdOut; T_SRDMemoryTarget srdOut;
{ {
T_File input( inputName.toString( ) , E_FileMode::READ_ONLY ); T_File input( scriptPath , E_FileMode::READ_ONLY );
try { try {
input.open( ); input.open( );
} catch ( X_StreamError const& e ) { } catch ( X_StreamError const& e ) {
PrintStreamError( "Could not open" , inputName , e ); PrintStreamError( "Could not open" , scriptPath , e );
return 1; return 1;
} }
srdOut.clearComments( true ).clearFlushToken( true ); srdOut.clearComments( true ).clearFlushToken( true );
try { try {
T_SRDTextReader srdReader{ srdOut }; T_SRDTextReader srdReader{ srdOut };
T_FileInputStream fis{ input }; T_FileInputStream fis{ input };
srdReader.read( inputName.toString( ) , fis ); srdReader.read( scriptName , fis );
} 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" , scriptPath , e );
exit( EXIT_FAILURE ); exit( EXIT_FAILURE );
} catch ( X_SRDErrors const& e ) { } catch ( X_SRDErrors const& e ) {
WriteSRDErrors( "SCRIPT" , e.errors ); WriteSRDErrors( "SCRIPT" , e.errors );
@ -239,7 +252,7 @@ int main( int argc , char** argv )
M_LOGSTR( "Parsing script" , 1 ); M_LOGSTR( "Parsing script" , 1 );
T_OpsParser parser; T_OpsParser parser;
parser.setLogger( logger ); parser.setLogger( logger );
if ( !parser.parse( inputName , srdOut.list( ) ) ) { if ( !parser.parse( scriptPath , srdOut.list( ) ) ) {
WriteSRDErrors( "SCRIPT" , parser.errors( ) ); WriteSRDErrors( "SCRIPT" , parser.errors( ) );
exit( EXIT_FAILURE ); exit( EXIT_FAILURE );
} }

View file

@ -33,6 +33,7 @@ struct T_Main
uint32_t stopResize = 0; uint32_t stopResize = 0;
ImVec2 prevSize; ImVec2 prevSize;
UI ui;
T_Optional< T_Demo > demo; T_Optional< T_Demo > demo;
T_Optional< T_SyncView > sequencer; T_Optional< T_SyncView > sequencer;
@ -46,8 +47,8 @@ struct T_Main
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
T_Main::T_Main( T_FSPath const& path ) T_Main::T_Main( T_FSPath const& path )
: ui{ path }
{ {
UI::Init( path );
prevSize = ImVec2( -1 , -1 ); prevSize = ImVec2( -1 , -1 );
} }
@ -103,7 +104,6 @@ void T_Main::mainLoop( )
T_Main::~T_Main( ) T_Main::~T_Main( )
{ {
demo.clear( ); demo.clear( );
UI::Shutdown( );
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/

19
ui.cc
View file

@ -23,6 +23,7 @@ const char CopyShader_[] = {
struct UIData_ struct UIData_
{ {
Common common;
T_UIApp window; T_UIApp window;
T_Profiler profiler; T_Profiler profiler;
T_TextureManager textures; T_TextureManager textures;
@ -35,24 +36,32 @@ struct UIData_
}; };
T_OutputDebugger odbg; T_OutputDebugger odbg;
T_UISync sync; T_UISync sync;
UIData_( T_FSPath const& path ) noexcept
: common{ path }
{}
}; };
uint32_t Initialised_{ 0 };
std::aligned_storage_t< sizeof( UIData_ ) , alignof( UIData_ ) > Instance_; std::aligned_storage_t< sizeof( UIData_ ) , alignof( UIData_ ) > Instance_;
} // namespace <anon> } // namespace <anon>
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void UI::Init( T_FSPath const& path ) noexcept UI::UI( T_FSPath const& path ) noexcept
{ {
Common::Init( path ); if ( !Initialised_ ++ ) {
new ((char*)&Instance_) UIData_( ); new ((char*)&Instance_) UIData_( path );
}
} }
void UI::Shutdown( ) noexcept UI::~UI( ) noexcept
{ {
assert( Initialised_ );
if ( !-- Initialised_ ) {
((UIData_*)(char*)&Instance_)->~UIData_( ); ((UIData_*)(char*)&Instance_)->~UIData_( );
Common::Shutdown( ); }
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/

4
ui.hh
View file

@ -15,8 +15,8 @@ struct T_UISync;
struct UI struct UI
{ {
public: public:
static void Init( T_FSPath const& path = {} ) noexcept; explicit UI( T_FSPath const& path = {} ) noexcept;
static void Shutdown( ) noexcept; ~UI( ) noexcept;
static T_UIApp& Main( ) noexcept; static T_UIApp& Main( ) noexcept;
static T_Profiler& Profiler( ) noexcept; static T_Profiler& Profiler( ) noexcept;