2017-11-15 18:58:37 +01:00
|
|
|
#pragma once
|
2017-12-02 18:38:34 +01:00
|
|
|
#include "c-buildcfg.hh"
|
2017-11-23 23:05:14 +01:00
|
|
|
#include "c-filewatcher.hh"
|
2017-11-23 23:31:24 +01:00
|
|
|
#include "c-opast.hh"
|
2017-11-24 14:52:56 +01:00
|
|
|
#include "c-project.hh"
|
2017-11-15 18:58:37 +01:00
|
|
|
#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;
|
|
|
|
};
|
|
|
|
|
|
|
|
// The actual parser
|
|
|
|
class T_OpsParser : public ebcl::A_PrivateImplementation
|
|
|
|
{
|
|
|
|
private:
|
2017-12-02 12:18:31 +01:00
|
|
|
F_OPLogger logger_{ []( auto , auto ) { } };
|
2017-11-15 18:58:37 +01:00
|
|
|
T_Array< ebcl::T_SRDError > errors_;
|
|
|
|
T_OwnPtr< T_OpsParserOutput > output_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_OpsParser( ) noexcept;
|
|
|
|
|
2017-12-02 12:18:31 +01:00
|
|
|
void setLogger( F_OPLogger logger )
|
|
|
|
{
|
|
|
|
if ( logger ) {
|
|
|
|
logger_ = std::move( logger );
|
|
|
|
} else {
|
|
|
|
logger_ = []( auto , auto ) { };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-15 18:58:37 +01:00
|
|
|
bool parse( ebcl::T_SRDList const& input ) noexcept;
|
|
|
|
|
|
|
|
T_Array< ebcl::T_SRDError > const& errors( ) const noexcept
|
|
|
|
{ return errors_; }
|
2017-11-15 23:09:52 +01:00
|
|
|
|
2017-11-15 18:58:37 +01:00
|
|
|
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
|
|
|
|
{
|
2017-12-03 13:05:54 +01:00
|
|
|
private:
|
|
|
|
F_OPLogger logger_{ []( auto , auto ) { } };
|
|
|
|
|
2017-11-15 18:58:37 +01:00
|
|
|
public:
|
2017-12-03 14:59:39 +01:00
|
|
|
T_OpsCompiler( bool noUIInstructions = false ) noexcept;
|
2017-11-15 18:58:37 +01:00
|
|
|
|
2017-12-03 13:05:54 +01:00
|
|
|
void setLogger( F_OPLogger logger )
|
|
|
|
{
|
|
|
|
if ( logger ) {
|
|
|
|
logger_ = std::move( logger );
|
|
|
|
} else {
|
|
|
|
logger_ = []( auto , auto ) { };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-15 18:58:37 +01:00
|
|
|
ops::P_OpProgram compile( T_OpsParserOutput const& input ) noexcept;
|
|
|
|
};
|
2017-11-15 23:09:52 +01:00
|
|
|
|
|
|
|
|
|
|
|
/*= SCRIPT MANAGER =============================================================*/
|
|
|
|
|
|
|
|
// The script manager watches over the demo's script, attempting to reload it if
|
|
|
|
// it is changed.
|
2017-11-24 14:52:56 +01:00
|
|
|
class T_ScriptManager : public A_ProjectPathListener
|
2017-11-15 23:09:52 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
T_ScriptManager( ) noexcept;
|
2017-11-24 14:52:56 +01:00
|
|
|
~T_ScriptManager( );
|
2017-11-15 23:09:52 +01:00
|
|
|
|
|
|
|
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:
|
2017-11-24 14:52:56 +01:00
|
|
|
T_String path_;
|
|
|
|
T_WatchedFiles watcher_;
|
|
|
|
|
|
|
|
T_OpsParser parser_;
|
|
|
|
T_OpsCompiler compiler_;
|
|
|
|
|
|
|
|
ops::P_OpProgram output_;
|
|
|
|
T_Array< ebcl::T_SRDError > errors_;
|
|
|
|
|
2017-11-15 23:09:52 +01:00
|
|
|
void loadScript( ) noexcept;
|
2017-11-24 14:52:56 +01:00
|
|
|
|
|
|
|
protected:
|
|
|
|
void projectPathChanged( ) noexcept override;
|
2017-11-15 23:09:52 +01:00
|
|
|
};
|