demotool/c-opcomp.hh
Emmanuel BENOîT 3344f96af0 "Interactive mode" for common code
This prevents the script manager and sync manager from watching/loading
their files unless they're explicitely started using
Common::SetInteractiveMode()

This will avoid having the whole thing loaded twice when running the
builder.
2017-12-28 17:16:39 +01:00

118 lines
2.7 KiB
C++

#pragma once
#include "c-buildcfg.hh"
#include "c-filewatcher.hh"
#include "c-opast.hh"
#include "c-project.hh"
#include <ebcl/SRDData.hh>
/*= 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;
};