#pragma once #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; }; // The actual parser class T_OpsParser : public ebcl::A_PrivateImplementation { private: T_Array< ebcl::T_SRDError > errors_; T_OwnPtr< T_OpsParserOutput > output_; public: T_OpsParser( ) noexcept; bool parse( 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 { public: T_OpsCompiler( ) noexcept; 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( ); 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: T_String 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; };