171 lines
3.7 KiB
C++
171 lines
3.7 KiB
C++
|
#pragma once
|
||
|
//#ifndef REAL_BUILD
|
||
|
# include "externals.hh"
|
||
|
//#endif
|
||
|
|
||
|
#include <ebcl/SRDData.hh>
|
||
|
|
||
|
|
||
|
namespace opast {
|
||
|
|
||
|
using namespace ebcl;
|
||
|
|
||
|
class T_RootNode;
|
||
|
|
||
|
class A_Node
|
||
|
{
|
||
|
public:
|
||
|
enum E_Type {
|
||
|
ROOT ,
|
||
|
//
|
||
|
DECL_INIT ,
|
||
|
DECL_FRAME ,
|
||
|
DECL_FN ,
|
||
|
//
|
||
|
OP_SET ,
|
||
|
//
|
||
|
EXPR_ADD ,
|
||
|
EXPR_MUL ,
|
||
|
EXPR_SUB ,
|
||
|
EXPR_DIV ,
|
||
|
EXPR_VAR ,
|
||
|
EXPR_CONST ,
|
||
|
};
|
||
|
|
||
|
private:
|
||
|
const E_Type type_;
|
||
|
A_Node* const parent_;
|
||
|
T_SRDLocation location_;
|
||
|
|
||
|
protected:
|
||
|
explicit A_Node( const E_Type type ,
|
||
|
A_Node* const parent ) noexcept;
|
||
|
|
||
|
public:
|
||
|
virtual ~A_Node( ) = 0;
|
||
|
|
||
|
E_Type type( ) const noexcept
|
||
|
{ return type_; }
|
||
|
|
||
|
T_SRDLocation& location( ) noexcept
|
||
|
{ return location_; }
|
||
|
T_SRDLocation const& location( ) const noexcept
|
||
|
{ return location_; }
|
||
|
|
||
|
A_Node& parent( ) const noexcept
|
||
|
{ assert( parent_ ); return *parent_; }
|
||
|
|
||
|
T_RootNode& root( ) const noexcept;
|
||
|
};
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
// Function-like nodes
|
||
|
class A_FuncNode : public A_Node
|
||
|
{
|
||
|
private:
|
||
|
T_String name_;
|
||
|
|
||
|
protected:
|
||
|
// For init or frame entry points.
|
||
|
// isInit = true => init entry point
|
||
|
// isInit = false => frame entry point
|
||
|
explicit A_FuncNode( bool isInit ,
|
||
|
T_RootNode* const parent ) noexcept;
|
||
|
|
||
|
// For normal functions
|
||
|
explicit A_FuncNode( T_String const& name ,
|
||
|
T_RootNode* const parent ) noexcept;
|
||
|
|
||
|
public:
|
||
|
T_String const& name( ) const noexcept
|
||
|
{ return name_; }
|
||
|
};
|
||
|
|
||
|
// Root node, keeps track of the whole tree and related data (function table,
|
||
|
// assets...)
|
||
|
class T_RootNode : public A_Node
|
||
|
{
|
||
|
private:
|
||
|
T_ObjectTable< T_String , T_OwnPtr< A_FuncNode > > functions_;
|
||
|
|
||
|
public:
|
||
|
T_RootNode( ) noexcept;
|
||
|
|
||
|
// Return type for addFunction. We'll always return a reference to a
|
||
|
// function node (which may or may not be the same as the initial one,
|
||
|
// if there were duplicates), and we'll return the location of the
|
||
|
// initial function in the case of a duplicate.
|
||
|
struct T_AddFunctionResult
|
||
|
{
|
||
|
A_FuncNode& function;
|
||
|
T_Optional< T_SRDLocation > dupLocation;
|
||
|
|
||
|
T_AddFunctionResult( A_FuncNode& function ) noexcept
|
||
|
: function{ function } , dupLocation{}
|
||
|
{}
|
||
|
|
||
|
T_AddFunctionResult( A_FuncNode& function ,
|
||
|
T_SRDLocation const& dupLocation ) noexcept
|
||
|
: function{ function } , dupLocation{ dupLocation }
|
||
|
{}
|
||
|
};
|
||
|
|
||
|
// Attempts to add a function. If the function is already present in
|
||
|
// the table, the result will be set up with the previous declaration's
|
||
|
// location, and the specified function will not be modified (a duplicate
|
||
|
// entry will be added to the table instead).
|
||
|
T_AddFunctionResult addFunction(
|
||
|
T_OwnPtr< A_FuncNode >& function ) noexcept;
|
||
|
};
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
// Init & frame functions
|
||
|
class T_SpecialFuncNode : public A_FuncNode
|
||
|
{
|
||
|
public:
|
||
|
T_SpecialFuncNode(
|
||
|
bool isInit ,
|
||
|
T_RootNode& parent ) noexcept;
|
||
|
};
|
||
|
|
||
|
// Normal functions
|
||
|
class T_FuncNode : public A_FuncNode
|
||
|
{
|
||
|
private:
|
||
|
T_AutoArray< T_String , 8 > argNames_;
|
||
|
T_AutoArray< T_SRDLocation , 8 > argLocations_;
|
||
|
|
||
|
public:
|
||
|
T_FuncNode( T_String const& name ,
|
||
|
T_RootNode& parent ) noexcept;
|
||
|
|
||
|
// Add an argument. If the argument is a duplicate, return the location
|
||
|
// of the initial argument.
|
||
|
T_Optional< T_SRDLocation > addArgument(
|
||
|
T_SRDToken const& token ) noexcept;
|
||
|
};
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
class T_Parser : public A_PrivateImplementation
|
||
|
{
|
||
|
private:
|
||
|
T_Array< T_SRDError > errors_;
|
||
|
T_OwnPtr< T_RootNode > rootNode_;
|
||
|
|
||
|
public:
|
||
|
T_Parser( ) noexcept;
|
||
|
|
||
|
bool parse( T_SRDList const& input ) noexcept;
|
||
|
|
||
|
T_Array< T_SRDError > const& errors( ) const noexcept
|
||
|
{ return errors_; }
|
||
|
T_OwnPtr< T_RootNode > result( ) noexcept
|
||
|
{ return std::move( rootNode_ ); }
|
||
|
};
|
||
|
|
||
|
|
||
|
} // namespace opast
|