2017-11-15 23:09:52 +01:00
|
|
|
#include "externals.hh"
|
2017-11-23 23:05:14 +01:00
|
|
|
#include "common.hh"
|
2017-11-23 23:31:24 +01:00
|
|
|
#include "c-opcomp.hh"
|
|
|
|
#include "c-ops.hh"
|
2017-11-15 23:09:52 +01:00
|
|
|
|
|
|
|
#include <ebcl/Files.hh>
|
|
|
|
#include <ebcl/SRDIO.hh>
|
|
|
|
#include <ebcl/SRDText.hh>
|
|
|
|
|
|
|
|
|
2017-11-16 08:34:13 +01:00
|
|
|
/*============================================================================*/
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
void WriteSRDError(
|
|
|
|
T_StringBuilder& sb ,
|
|
|
|
ebcl::T_SRDError const& error )
|
|
|
|
{
|
|
|
|
sb << error.location( ) << " - " << error.error( ) << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void DumpSRDErrors(
|
|
|
|
T_String const& header ,
|
|
|
|
T_Array< ebcl::T_SRDError > const& errors )
|
|
|
|
{
|
|
|
|
T_StringBuilder sb;
|
|
|
|
sb << "=============================================================\n"
|
|
|
|
<< header << '\n'
|
|
|
|
<< "-------------------------------------------------------------\n";
|
|
|
|
for ( auto& error : errors ) {
|
|
|
|
WriteSRDError( sb , error );
|
|
|
|
}
|
|
|
|
sb << "=============================================================\n" << '\0';
|
|
|
|
printf( "%s" , sb.data( ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
2017-11-15 23:09:52 +01:00
|
|
|
/*= T_ScriptManager ============================================================*/
|
|
|
|
|
|
|
|
T_ScriptManager::T_ScriptManager( ) noexcept
|
2017-11-23 23:05:14 +01:00
|
|
|
: watcher_( Common::Watcher( ) , [this](){
|
2017-11-15 23:09:52 +01:00
|
|
|
loadScript( );
|
|
|
|
} ) ,
|
|
|
|
parser_( ) , compiler_( )
|
|
|
|
{
|
2017-11-24 14:52:56 +01:00
|
|
|
Common::Project( ).addListener( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
T_ScriptManager::~T_ScriptManager( )
|
|
|
|
{
|
|
|
|
Common::Project( ).removeListener( this );
|
|
|
|
}
|
|
|
|
|
2017-12-28 17:15:00 +01:00
|
|
|
void T_ScriptManager::enable( ) noexcept
|
|
|
|
{
|
|
|
|
if ( !enabled_ ) {
|
|
|
|
enabled_ = true;
|
|
|
|
projectPathChanged( );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-24 14:52:56 +01:00
|
|
|
void T_ScriptManager::projectPathChanged( ) noexcept
|
|
|
|
{
|
|
|
|
path_ = Common::Project( ).pathOf( "demo.srd" );
|
2017-12-28 17:15:00 +01:00
|
|
|
if ( enabled_ ) {
|
|
|
|
watcher_.clear( );
|
|
|
|
watcher_.watch( path_.toString( ) );
|
|
|
|
loadScript( );
|
|
|
|
}
|
2017-11-15 23:09:52 +01:00
|
|
|
}
|
|
|
|
|
2017-11-24 14:52:56 +01:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
2017-11-15 23:09:52 +01:00
|
|
|
void T_ScriptManager::loadScript( ) noexcept
|
|
|
|
{
|
|
|
|
output_.clear( );
|
|
|
|
errors_.clear( );
|
|
|
|
|
|
|
|
using namespace ebcl;
|
2017-12-27 14:53:19 +01:00
|
|
|
T_File input( path_.toString( ) , E_FileMode::READ_ONLY );
|
2017-11-15 23:09:52 +01:00
|
|
|
try {
|
|
|
|
input.open( );
|
|
|
|
} catch ( X_StreamError const& e ) {
|
|
|
|
T_StringBuilder sb;
|
|
|
|
sb << "could not open: " << e.what( );
|
|
|
|
if ( e.code( ) == ebcl::E_StreamError::SYSTEM_ERROR ) {
|
|
|
|
sb << " (error code " << e.systemError( ) << ")";
|
|
|
|
}
|
|
|
|
errors_.addNew( std::move( sb ) ,
|
2017-12-27 14:53:19 +01:00
|
|
|
T_SRDLocation{ path_.toString( ) , 1 , 1 } );
|
2017-11-16 08:34:13 +01:00
|
|
|
DumpSRDErrors( "Script not found" , errors_ );
|
2017-11-15 23:09:52 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load SRD data
|
|
|
|
T_SRDMemoryTarget srdOut;
|
|
|
|
srdOut.clearComments( true ).clearFlushToken( true );
|
2017-12-28 13:02:48 +01:00
|
|
|
const auto fn{ path_.makeRelative( Common::Project( ).basePath( ) ) };
|
2017-11-15 23:09:52 +01:00
|
|
|
try {
|
|
|
|
T_SRDTextReader srdReader{ srdOut };
|
|
|
|
T_FileInputStream fis{ input };
|
2017-12-28 13:02:48 +01:00
|
|
|
srdReader.read( fn.toString( ) , fis );
|
2017-11-15 23:09:52 +01:00
|
|
|
} catch ( X_StreamError const& e ) {
|
|
|
|
T_StringBuilder sb;
|
|
|
|
sb << "could not load: " << e.what( );
|
|
|
|
if ( e.code( ) == ebcl::E_StreamError::SYSTEM_ERROR ) {
|
|
|
|
sb << " (error code " << e.systemError( ) << ")";
|
|
|
|
}
|
|
|
|
errors_.addNew( std::move( sb ) ,
|
2017-12-27 14:53:19 +01:00
|
|
|
T_SRDLocation{ path_.toString( ) , 1 , 1 } );
|
2017-11-16 08:34:13 +01:00
|
|
|
DumpSRDErrors( "Script not loaded" , errors_ );
|
2017-11-15 23:09:52 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
} catch ( X_SRDErrors const& e ) {
|
|
|
|
T_StringBuilder sb;
|
|
|
|
const auto nErrors( e.errors.size( ) );
|
|
|
|
errors_.ensureCapacity( nErrors );
|
|
|
|
for ( auto i = 0u ; i < nErrors ; i ++ ) {
|
|
|
|
errors_.add( e.errors[ i ] );
|
|
|
|
}
|
2017-11-16 08:34:13 +01:00
|
|
|
DumpSRDErrors( "Script not loaded" , errors_ );
|
2017-11-15 23:09:52 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the fuck
|
2017-12-28 13:02:48 +01:00
|
|
|
const bool parsed{ parser_.parse( path_ , srdOut.list( ) ) };
|
|
|
|
auto pOut{ parser_.result( ) };
|
|
|
|
const auto nf{ pOut->files.size( ) };
|
|
|
|
if ( nf ) {
|
|
|
|
watcher_.clear( );
|
|
|
|
for ( auto i = 0u ; i < nf ; i ++ ) {
|
|
|
|
watcher_.watch( pOut->files[ i ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( !parsed ) {
|
2017-11-15 23:09:52 +01:00
|
|
|
errors_.addAll( parser_.errors( ) );
|
2017-11-16 08:34:13 +01:00
|
|
|
DumpSRDErrors( "Parse errors" , errors_ );
|
2017-11-15 23:09:52 +01:00
|
|
|
return;
|
|
|
|
}
|
2017-12-28 13:02:48 +01:00
|
|
|
|
|
|
|
output_ = compiler_.compile( *pOut );
|
|
|
|
|
2017-11-15 23:09:52 +01:00
|
|
|
// FIXME - errors from compiler
|
2017-12-28 13:02:48 +01:00
|
|
|
|
|
|
|
printf( "Script loaded & compiled\n" );
|
2017-11-15 23:09:52 +01:00
|
|
|
}
|