#include "externals.hh" #include "common.hh" #include "c-opcomp.hh" #include "c-ops.hh" #include #include #include /*============================================================================*/ 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 /*= T_ScriptManager ============================================================*/ T_ScriptManager::T_ScriptManager( ) noexcept : watcher_( Common::Watcher( ) , [this](){ loadScript( ); } ) , parser_( ) , compiler_( ) { Common::Project( ).addListener( this ); projectPathChanged( ); } T_ScriptManager::~T_ScriptManager( ) { Common::Project( ).removeListener( this ); } void T_ScriptManager::projectPathChanged( ) noexcept { path_ = Common::Project( ).pathOf( "demo.srd" ); watcher_.clear( ); watcher_.watch( path_ ); loadScript( ); } /*----------------------------------------------------------------------------*/ void T_ScriptManager::loadScript( ) noexcept { output_.clear( ); errors_.clear( ); using namespace ebcl; T_File input( path_ , E_FileMode::READ_ONLY ); 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 ) , T_SRDLocation{ path_ , 1 , 1 } ); DumpSRDErrors( "Script not found" , errors_ ); return; } // Load SRD data T_SRDMemoryTarget srdOut; srdOut.clearComments( true ).clearFlushToken( true ); try { T_SRDTextReader srdReader{ srdOut }; T_FileInputStream fis{ input }; srdReader.read( path_ , fis ); } 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 ) , T_SRDLocation{ path_ , 1 , 1 } ); DumpSRDErrors( "Script not loaded" , errors_ ); 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 ] ); } DumpSRDErrors( "Script not loaded" , errors_ ); return; } // Parse the fuck if ( !parser_.parse( srdOut.list( ) ) ) { errors_.addAll( parser_.errors( ) ); DumpSRDErrors( "Parse errors" , errors_ ); return; } output_ = compiler_.compile( *parser_.result( ) ); // FIXME - errors from compiler }