Scripting - Includes work!
This commit is contained in:
parent
68f6c49066
commit
542e791199
10 changed files with 164 additions and 56 deletions
2
3rdparty/ebcl
vendored
2
3rdparty/ebcl
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 5497856be2761a6f4f1848636304cff134668766
|
||||
Subproject commit 7b97993448d086a92d9875db2c2815afa249ba65
|
|
@ -1,4 +1,6 @@
|
|||
#include "externals.hh"
|
||||
#include "common.hh"
|
||||
#include "c-project.hh"
|
||||
#include "c-buildcfg.hh"
|
||||
|
||||
#include <ebcl/Files.hh>
|
||||
|
@ -159,11 +161,12 @@ T_SRDParserConfig BCLInitDefinitions_( ) noexcept
|
|||
|
||||
struct T_BCLImpl_
|
||||
{
|
||||
const T_String fileName{ T_String::Pooled( "build.srd" ) };
|
||||
T_SRDParserConfig pConfig;
|
||||
|
||||
T_BCLImpl_( ) noexcept;
|
||||
|
||||
T_BuildConfigurations load( T_String const& path );
|
||||
T_BuildConfigurations load( );
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
@ -172,16 +175,16 @@ T_BCLImpl_::T_BCLImpl_( ) noexcept
|
|||
: pConfig{ BCLInitDefinitions_( ) }
|
||||
{ }
|
||||
|
||||
T_BuildConfigurations T_BCLImpl_::load(
|
||||
T_String const& path )
|
||||
T_BuildConfigurations T_BCLImpl_::load( )
|
||||
{
|
||||
// TODO: keep errors so we get warnings/notes too
|
||||
T_SRDParser parser{ pConfig };
|
||||
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 };
|
||||
srdReader.read( path , fis );
|
||||
srdReader.read( fileName , fis );
|
||||
|
||||
return std::move( *parser.getData< T_SharedPtr< T_BuildConfigurations > >( ) );
|
||||
}
|
||||
|
@ -195,8 +198,7 @@ T_BuildConfigurationLoader::T_BuildConfigurationLoader( ) noexcept
|
|||
{ }
|
||||
|
||||
|
||||
T_BuildConfigurations T_BuildConfigurationLoader::load(
|
||||
T_String const& path )
|
||||
T_BuildConfigurations T_BuildConfigurationLoader::load( )
|
||||
{
|
||||
return p< T_BCLImpl_ >( ).load( path );
|
||||
return p< T_BCLImpl_ >( ).load( );
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ struct T_BuildConfigurationLoader : public ebcl::A_PrivateImplementation
|
|||
|
||||
// Load build configurations from the specified path; may throw
|
||||
// X_StreamError or X_SRDErrors
|
||||
T_BuildConfigurations load( T_String const& path );
|
||||
T_BuildConfigurations load( );
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
|
116
c-opparser.cc
116
c-opparser.cc
|
@ -6,7 +6,9 @@
|
|||
#include "c-syncoverrides.hh"
|
||||
|
||||
#include <ebcl/Algorithms.hh>
|
||||
#include <ebcl/Files.hh>
|
||||
#include <ebcl/SRDParser.hh>
|
||||
#include <ebcl/SRDText.hh>
|
||||
|
||||
using namespace ebcl;
|
||||
using namespace opast;
|
||||
|
@ -172,8 +174,9 @@ struct T_ParserImpl_
|
|||
T_SRDParserConfig ovParserConfig;
|
||||
T_SRDParser ovParser;
|
||||
|
||||
T_String curFile;
|
||||
T_AutoArray< T_String , 32 > inclStack;
|
||||
T_FSPath curFile;
|
||||
T_FSPath baseDir;
|
||||
T_AutoArray< T_FSPath , 32 > inclStack;
|
||||
|
||||
T_Visitor< A_Node > visitor{ opast::ASTVisitorBrowser };
|
||||
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;
|
||||
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;
|
||||
|
||||
|
@ -331,8 +336,12 @@ inline T_ParserImpl_::T_ParserImpl_(
|
|||
{ }
|
||||
|
||||
void T_ParserImpl_::main(
|
||||
T_FSPath const& file ,
|
||||
T_SRDList const& input ) noexcept
|
||||
{
|
||||
assert( file.isAbsolute( ) );
|
||||
curFile = file.canonical( );
|
||||
baseDir = file.parent( );
|
||||
parseTopLevel( input )
|
||||
&& checkRequiredBlocks( input )
|
||||
&& checkCalls( )
|
||||
|
@ -948,18 +957,24 @@ 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 ) {
|
||||
parseTLList( t.list( ) );
|
||||
} else {
|
||||
errors.addNew( "top-level list expected" , t.location( ) );
|
||||
}
|
||||
}
|
||||
parseTLList( input );
|
||||
return errors.empty( );
|
||||
}
|
||||
|
||||
void T_ParserImpl_::parseTLList(
|
||||
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 );
|
||||
auto const& ft{ input[ 0 ] };
|
||||
|
@ -970,7 +985,6 @@ void T_ParserImpl_::parseTLList(
|
|||
|
||||
auto const& fw{ ft.stringValue( ) };
|
||||
if ( fw == "include" ) {
|
||||
// TODO
|
||||
if ( input.size( ) == 1 ) {
|
||||
errors.addNew( "file name expected" ,
|
||||
ft.location( ) );
|
||||
|
@ -999,14 +1013,78 @@ void T_ParserImpl_::handleInclude(
|
|||
return;
|
||||
}
|
||||
|
||||
if ( !curFile ) {
|
||||
curFile = tFileName.location( ).source( );
|
||||
// Resolve included file path
|
||||
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
|
||||
// TODO: check for recursive includes
|
||||
// TODO: load file
|
||||
// TODO: parse it
|
||||
// Check for recursive includes
|
||||
if ( inclStack.contains( inclPath ) ) {
|
||||
errors.addNew( "recursive file inclusion" ,
|
||||
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( );
|
||||
output_ = NewOwned< T_OpsParserOutput >( );
|
||||
p< T_ParserImpl_ >( ).main( input );
|
||||
p< T_ParserImpl_ >( ).main( filePath , input );
|
||||
return errors_.empty( );
|
||||
}
|
||||
|
|
10
common.cc
10
common.cc
|
@ -24,21 +24,27 @@ struct CommonData_
|
|||
{}
|
||||
};
|
||||
|
||||
uint32_t Initialised_{ 0 };
|
||||
std::aligned_storage_t< sizeof( CommonData_ ) , alignof( CommonData_ ) > Instance_;
|
||||
|
||||
} // namespace <anon>
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
void Common::Init(
|
||||
Common::Common(
|
||||
T_FSPath const& path ) noexcept
|
||||
{
|
||||
if ( !Initialised_ ++ ) {
|
||||
new ((char*)&Instance_) CommonData_( path );
|
||||
}
|
||||
}
|
||||
|
||||
void Common::Shutdown( ) noexcept
|
||||
Common::~Common( ) noexcept
|
||||
{
|
||||
assert( Initialised_ );
|
||||
if ( !-- Initialised_ ) {
|
||||
((CommonData_*)(char*)&Instance_)->~CommonData_( );
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -13,8 +13,8 @@ class T_UndoManager;
|
|||
|
||||
struct Common
|
||||
{
|
||||
static void Init( T_FSPath const& path = {} ) noexcept;
|
||||
static void Shutdown( ) noexcept;
|
||||
explicit Common( T_FSPath const& path = {} ) noexcept;
|
||||
~Common( ) noexcept;
|
||||
|
||||
static T_Project& Project( ) noexcept;
|
||||
static T_FilesWatcher& Watcher( ) noexcept;
|
||||
|
|
35
m-builder.cc
35
m-builder.cc
|
@ -1,5 +1,6 @@
|
|||
#include "externals.hh"
|
||||
|
||||
#include "common.hh"
|
||||
#include "c-opast.hh"
|
||||
#include "c-ops.hh"
|
||||
#include "c-opcomp.hh"
|
||||
|
@ -34,7 +35,13 @@ void PrintStreamError(
|
|||
T_FSPath const& name ,
|
||||
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;
|
||||
sb << prefix << " '" << rp << "': " << error.what( );
|
||||
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 raw{ oSrcPath };
|
||||
if ( !raw.isAbsolute( ) ) {
|
||||
|
@ -149,6 +158,7 @@ int main( int argc , char** argv )
|
|||
fprintf( stderr , "Invalid source path\n" );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
Common common{ srcPath };
|
||||
|
||||
// Logger setup
|
||||
const uint32_t logLevel{ oLogLevel ? *oLogLevel : 0 };
|
||||
|
@ -163,11 +173,11 @@ int main( int argc , char** argv )
|
|||
|
||||
// Build configurations
|
||||
M_LOGSTR( "Loading build configurations" , 1 );
|
||||
const auto bcfgFile{ FilePath( srcPath , "build.srd" ) };
|
||||
const T_BuildConfiguration cfg{ [&]() {
|
||||
try {
|
||||
T_BuildConfigurationLoader bcfgLoader;
|
||||
T_BuildConfigurations cfs{ bcfgLoader.load( bcfgFile.toString( ) ) };
|
||||
T_BuildConfigurations cfs{
|
||||
T_BuildConfigurationLoader{ }.load( )
|
||||
};
|
||||
if ( oBuildCfg && !cfs.contains( oBuildCfg ) ) {
|
||||
fprintf( stderr , "===== BUILD CONFIGURATIONS\n" );
|
||||
fprintf( stderr , "Build configuration not found\n" );
|
||||
|
@ -183,7 +193,9 @@ int main( int argc , char** argv )
|
|||
|
||||
} catch ( X_StreamError const& e ) {
|
||||
fprintf( stderr , "===== BUILD CONFIGURATIONS\n" );
|
||||
PrintStreamError( "Could not open" , bcfgFile , e );
|
||||
PrintStreamError( "Could not open" ,
|
||||
Common::Project( ).pathOf( "build.srd" ) ,
|
||||
e );
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
} catch ( X_SRDErrors const& e ) {
|
||||
|
@ -210,24 +222,25 @@ int main( int argc , char** argv )
|
|||
|
||||
// Open and load script
|
||||
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_File input( inputName.toString( ) , E_FileMode::READ_ONLY );
|
||||
T_File input( scriptPath , E_FileMode::READ_ONLY );
|
||||
try {
|
||||
input.open( );
|
||||
} catch ( X_StreamError const& e ) {
|
||||
PrintStreamError( "Could not open" , inputName , e );
|
||||
PrintStreamError( "Could not open" , scriptPath , e );
|
||||
return 1;
|
||||
}
|
||||
srdOut.clearComments( true ).clearFlushToken( true );
|
||||
try {
|
||||
T_SRDTextReader srdReader{ srdOut };
|
||||
T_FileInputStream fis{ input };
|
||||
srdReader.read( inputName.toString( ) , fis );
|
||||
srdReader.read( scriptName , fis );
|
||||
} catch ( X_StreamError const& e ) {
|
||||
fprintf( stderr , "===== SCRIPT\n" );
|
||||
PrintStreamError( "Could not open" , inputName , e );
|
||||
PrintStreamError( "Could not open" , scriptPath , e );
|
||||
exit( EXIT_FAILURE );
|
||||
} catch ( X_SRDErrors const& e ) {
|
||||
WriteSRDErrors( "SCRIPT" , e.errors );
|
||||
|
@ -239,7 +252,7 @@ int main( int argc , char** argv )
|
|||
M_LOGSTR( "Parsing script" , 1 );
|
||||
T_OpsParser parser;
|
||||
parser.setLogger( logger );
|
||||
if ( !parser.parse( inputName , srdOut.list( ) ) ) {
|
||||
if ( !parser.parse( scriptPath , srdOut.list( ) ) ) {
|
||||
WriteSRDErrors( "SCRIPT" , parser.errors( ) );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ struct T_Main
|
|||
uint32_t stopResize = 0;
|
||||
ImVec2 prevSize;
|
||||
|
||||
UI ui;
|
||||
T_Optional< T_Demo > demo;
|
||||
T_Optional< T_SyncView > sequencer;
|
||||
|
||||
|
@ -46,8 +47,8 @@ struct T_Main
|
|||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
T_Main::T_Main( T_FSPath const& path )
|
||||
: ui{ path }
|
||||
{
|
||||
UI::Init( path );
|
||||
prevSize = ImVec2( -1 , -1 );
|
||||
}
|
||||
|
||||
|
@ -103,7 +104,6 @@ void T_Main::mainLoop( )
|
|||
T_Main::~T_Main( )
|
||||
{
|
||||
demo.clear( );
|
||||
UI::Shutdown( );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
|
19
ui.cc
19
ui.cc
|
@ -23,6 +23,7 @@ const char CopyShader_[] = {
|
|||
|
||||
struct UIData_
|
||||
{
|
||||
Common common;
|
||||
T_UIApp window;
|
||||
T_Profiler profiler;
|
||||
T_TextureManager textures;
|
||||
|
@ -35,24 +36,32 @@ struct UIData_
|
|||
};
|
||||
T_OutputDebugger odbg;
|
||||
T_UISync sync;
|
||||
|
||||
UIData_( T_FSPath const& path ) noexcept
|
||||
: common{ path }
|
||||
{}
|
||||
};
|
||||
|
||||
uint32_t Initialised_{ 0 };
|
||||
std::aligned_storage_t< sizeof( UIData_ ) , alignof( UIData_ ) > Instance_;
|
||||
|
||||
} // namespace <anon>
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
void UI::Init( T_FSPath const& path ) noexcept
|
||||
UI::UI( T_FSPath const& path ) noexcept
|
||||
{
|
||||
Common::Init( path );
|
||||
new ((char*)&Instance_) UIData_( );
|
||||
if ( !Initialised_ ++ ) {
|
||||
new ((char*)&Instance_) UIData_( path );
|
||||
}
|
||||
}
|
||||
|
||||
void UI::Shutdown( ) noexcept
|
||||
UI::~UI( ) noexcept
|
||||
{
|
||||
assert( Initialised_ );
|
||||
if ( !-- Initialised_ ) {
|
||||
((UIData_*)(char*)&Instance_)->~UIData_( );
|
||||
Common::Shutdown( );
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
|
4
ui.hh
4
ui.hh
|
@ -15,8 +15,8 @@ struct T_UISync;
|
|||
struct UI
|
||||
{
|
||||
public:
|
||||
static void Init( T_FSPath const& path = {} ) noexcept;
|
||||
static void Shutdown( ) noexcept;
|
||||
explicit UI( T_FSPath const& path = {} ) noexcept;
|
||||
~UI( ) noexcept;
|
||||
|
||||
static T_UIApp& Main( ) noexcept;
|
||||
static T_Profiler& Profiler( ) noexcept;
|
||||
|
|
Loading…
Reference in a new issue