#pragma once #include "c-buildcfg.hh" #include "c-filewatcher.hh" #include "c-opast.hh" #include "c-project.hh" #include /*= PARSER ===================================================================*/ // Parser output. Consists in a root node as well as other details (table of // constants, data types, etc...) struct T_OpsParserOutput { opast::T_RootNode root; T_KeyValueTable< T_String , opast::E_DataType > types; ebcl::T_Set< T_FSPath > files{ ebcl::UseTag< ebcl::ArrayBacked< 16 > >( ) }; }; // The actual parser class T_OpsParser : public ebcl::A_PrivateImplementation { private: F_OPLogger logger_{ []( auto , auto ) { } }; T_Array< ebcl::T_SRDError > errors_; T_OwnPtr< T_OpsParserOutput > output_; public: T_OpsParser( ) noexcept; void setLogger( F_OPLogger logger ) { if ( logger ) { logger_ = std::move( logger ); } else { logger_ = []( auto , auto ) { }; } } bool parse( T_FSPath const& filePath , ebcl::T_SRDList const& input ) noexcept; T_Array< ebcl::T_SRDError > const& errors( ) const noexcept { return errors_; } T_OwnPtr< T_OpsParserOutput > result( ) noexcept { return std::move( output_ ); } }; /*= COMPILER ===================================================================*/ namespace ops { struct T_OpProgram; using P_OpProgram = T_OwnPtr< T_OpProgram >; } // Generates bytecode based on the type-checked tree produced by the parser class T_OpsCompiler : public ebcl::A_PrivateImplementation { private: F_OPLogger logger_{ []( auto , auto ) { } }; public: T_OpsCompiler( bool noUIInstructions = false ) 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; }; /*= SCRIPT MANAGER =============================================================*/ // The script manager watches over the demo's script, attempting to reload it if // it is changed. class T_ScriptManager : public A_ProjectPathListener { public: T_ScriptManager( ) noexcept; ~T_ScriptManager( ); void enable( ) noexcept; void disable( ) noexcept { enabled_ = false; } bool enabled( ) const noexcept { return enabled_; } bool hasNewProgram( ) const noexcept { return bool( output_ ); } ops::P_OpProgram program( ) noexcept { return std::move( output_ ); } T_Array< ebcl::T_SRDError > const& errors( ) const noexcept { return errors_; } private: bool enabled_{ false }; T_FSPath path_; T_WatchedFiles watcher_; T_OpsParser parser_; T_OpsCompiler compiler_; ops::P_OpProgram output_; T_Array< ebcl::T_SRDError > errors_; void loadScript( ) noexcept; protected: void projectPathChanged( ) noexcept override; };