Support for interfaces in class/struct.

Interfaces are assumed to have the public access specifier for their content (if its a class definition)

Started to prepare to segement library code into more files (Less scrolling, need for bootstrapping a tailored version + single header support anyway).
This commit is contained in:
Edward R. Gonzalez 2023-07-24 13:44:19 -04:00
parent d4c2cdf30e
commit 39390535ce
11 changed files with 166 additions and 28 deletions

View File

@ -172,7 +172,7 @@ This method is setup where all the metaprogram's code are the within the same fi
* Lambdas (This naturally means its unsupported) * Lambdas (This naturally means its unsupported)
* RAII : This needs support for constructors/destructor parsing * RAII : This needs support for constructors/destructor parsing
* I haven't gotten around to yet, only useful (to me) for third-party scanning * I haven't gotten around to yet, only useful (to me) for third-party scanning
* Multiple Inheritance * Multiple Inheritance : Working on it..
Keywords kept from "Modern C++": Keywords kept from "Modern C++":

View File

@ -3,16 +3,20 @@
The core library is contained within `gen.hpp` and `gen.cpp`. The core library is contained within `gen.hpp` and `gen.cpp`.
Things related to the editor and scanner are in their own respective files. (Ex: `gen.scanner.<hpp/cpp>` ) Things related to the editor and scanner are in their own respective files. (Ex: `gen.scanner.<hpp/cpp>` )
Dependencies are within `gen.dep.<hpp/cpp>`
## gen.hpp ## gen.hpp
Feature Macros: Feature Macros:
* `GEN_DONT_USE_NAMESPACE` : By default, the library is wrapped in a `gen` namespace, this will disable that expose it to the global scope.
* `GEN_DONT_ENFORCE_GEN_TIME_GUARD` : By default, the library ( gen.hpp/ gen.cpp ) expects the macro `GEN_TIME` to be defined, this disables that. * `GEN_DONT_ENFORCE_GEN_TIME_GUARD` : By default, the library ( gen.hpp/ gen.cpp ) expects the macro `GEN_TIME` to be defined, this disables that.
* `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves. * `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves.
* `GEN_DEFINE_LIBRARY_CORE_CONSTANTS` : Optional typename codes as they are non-standard to C/C++ and not necessary to library usage * `GEN_DEFINE_LIBRARY_CORE_CONSTANTS` : Optional typename codes as they are non-standard to C/C++ and not necessary to library usage
* `GEN_ENFORCE_STRONG_CODE_TYPES` : Enforces casts to filtered code types. * `GEN_ENFORCE_STRONG_CODE_TYPES` : Enforces casts to filtered code types.
* `GEN_EXPOSE_BACKEND` : Will expose symbols meant for internal use only.
* `GEN_Define_Attribute_Tokens` : Allows user to define their own attribute macros for use in parsing.
`GEN_USE_RECURSIVE_AST_DUPLICATION` is available but its not well tested and should not need to be used. `GEN_USE_RECURSIVE_AST_DUPLICATION` is available but its not well tested and should not need to be used.
If constructing ASTs properly. There should be no modification of ASTs, and thus this would never become an issue. If constructing ASTs properly. There should be no modification of ASTs, and thus this would never become an issue.

View File

@ -1,4 +1,4 @@
// This file is intended to be included within gen.hpp (There is pragma diagnostic ignores) // This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores)
#pragma once #pragma once
#pragma region Platform Detection #pragma region Platform Detection

View File

@ -4,12 +4,12 @@
#error Gen.hpp : GEN_TIME not defined #error Gen.hpp : GEN_TIME not defined
#endif #endif
#include "gen.push_ignores.inline.hpp" #include "helpers/gen.push_ignores.inline.hpp"
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
//! Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl //! Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
#ifndef GEN_ROLL_OWN_DEPENDENCIES #ifndef GEN_ROLL_OWN_DEPENDENCIES
# include "gen.dep.cpp" # include "dependencies/gen.dep.cpp"
#endif #endif
#include "gen.hpp" #include "gen.hpp"
@ -478,6 +478,17 @@ String AST::to_string()
, ParentType->to_string() , ParentType->to_string()
, Body->to_string() , Body->to_string()
); );
CodeType interface = Next->cast<CodeType>();
if ( interface )
result.append("\n");
while ( interface )
{
result.append_fmt( ", %s", interface.to_string() );
interface = interface->Next->cast<CodeType>();
}
} }
else else
{ {
@ -902,6 +913,17 @@ String AST::to_string()
, ParentType->to_string() , ParentType->to_string()
, Body->to_string() , Body->to_string()
); );
CodeType interface = Next->cast<CodeType>();
if ( interface )
result.append("\n");
while ( interface )
{
result.append_fmt( ", public %s", interface.to_string() );
interface = interface->Next->cast<CodeType>();
}
} }
else else
{ {
@ -1182,7 +1204,8 @@ bool AST::validate_body()
#pragma endregion AST #pragma endregion AST
#pragma region Gen Interface #pragma region Gen Interface
internal void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags ) internal
void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
{ {
Arena* last = & Global_AllocatorBuckets.back(); Arena* last = & Global_AllocatorBuckets.back();
@ -1244,7 +1267,8 @@ internal void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw s
return nullptr; return nullptr;
} }
internal void define_constants() internal
void define_constants()
{ {
Code::Global = make_code(); Code::Global = make_code();
Code::Global->Name = get_cached_string( txt_StrC("Global Code") ); Code::Global->Name = get_cached_string( txt_StrC("Global Code") );
@ -2032,7 +2056,8 @@ CodeClass def_class( StrC name
, Code body , Code body
, CodeType parent, AccessSpec parent_access , CodeType parent, AccessSpec parent_access
, CodeAttributes attributes , CodeAttributes attributes
, ModuleFlag mflags ) , ModuleFlag mflags
, CodeType* interfaces, s32 num_interfaces )
{ {
using namespace ECode; using namespace ECode;
@ -2085,6 +2110,14 @@ CodeClass def_class( StrC name
result->ParentType = parent; result->ParentType = parent;
} }
if ( interfaces )
{
for (s32 idx = 0; idx < num_interfaces; idx++ )
{
result.add_interface( interfaces[idx] );
}
}
return result; return result;
} }
@ -2523,7 +2556,8 @@ CodeStruct def_struct( StrC name
, Code body , Code body
, CodeType parent, AccessSpec parent_access , CodeType parent, AccessSpec parent_access
, CodeAttributes attributes , CodeAttributes attributes
, ModuleFlag mflags ) , ModuleFlag mflags
, CodeType* interfaces, s32 num_interfaces )
{ {
using namespace ECode; using namespace ECode;
@ -2571,6 +2605,14 @@ CodeStruct def_struct( StrC name
result->ParentType = parent; result->ParentType = parent;
} }
if ( interfaces )
{
for (s32 idx = 0; idx < num_interfaces; idx++ )
{
result.add_interface( interfaces[idx] );
}
}
return result; return result;
} }
@ -5162,6 +5204,7 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
Token name { nullptr, 0, TokType::Invalid }; Token name { nullptr, 0, TokType::Invalid };
AccessSpec access = AccessSpec::Default;
CodeType parent = { nullptr }; CodeType parent = { nullptr };
CodeBody body = { nullptr }; CodeBody body = { nullptr };
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
@ -5182,8 +5225,9 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
if ( check( TokType::Identifier ) ) if ( check( TokType::Identifier ) )
name = parse_identifier( toks, context ); name = parse_identifier( toks, context );
AccessSpec access = AccessSpec::Default; local_persist
Token parent_tok = { nullptr, 0, TokType::Invalid }; char interface_arr_mem[ kilobytes(4) ] {0};
Array<CodeType> interfaces = Array<CodeType>::init_reserve( Arena::init_from_memory(interface_arr_mem, kilobytes(4) ), 4 );
if ( check( TokType::Assign_Classifer ) ) if ( check( TokType::Assign_Classifer ) )
{ {
@ -5194,7 +5238,22 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
access = tok_to_access_specifier( currtok ); access = tok_to_access_specifier( currtok );
} }
parent_tok = parse_identifier( toks, context ); Token parent_tok = parse_identifier( toks, context );
parent = def_type( parent_tok );
while ( check(TokType::Comma) )
{
eat(TokType::Access_Public);
if ( tok_is_access_specifier( currtok ) )
{
eat(currtok.Type);
}
Token interface_tok = parse_identifier( toks, context );
interfaces.append( def_type( interface_tok ) );
}
} }
if ( check( TokType::BraceCurly_Open ) ) if ( check( TokType::BraceCurly_Open ) )
@ -5204,9 +5263,6 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
eat( TokType::Statement_End ); eat( TokType::Statement_End );
if ( parent_tok )
parent = def_type( parent_tok );
if ( which == TokType::Decl_Class ) if ( which == TokType::Decl_Class )
result = def_class( name, body, parent, access result = def_class( name, body, parent, access
, attributes , attributes
@ -5219,6 +5275,7 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
, mflags , mflags
); );
interfaces.free();
return result; return result;
} }
@ -6812,4 +6869,4 @@ void Builder::write()
GEN_NS_END GEN_NS_END
#include "gen.pop_ignores.inline.hpp" #include "helpers/gen.pop_ignores.inline.hpp"

View File

@ -12,12 +12,12 @@
#error Gen.hpp : GEN_TIME not defined #error Gen.hpp : GEN_TIME not defined
#endif #endif
#include "gen.push_ignores.inline.hpp" #include "helpers/gen.push_ignores.inline.hpp"
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl // Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
#ifndef GEN_ROLL_OWN_DEPENDENCIES #ifndef GEN_ROLL_OWN_DEPENDENCIES
# include "gen.dep.hpp" # include "dependencies/gen.dep.hpp"
#endif #endif
#if defined(GEN_DONT_USE_NAMESPACE) && ! defined(GEN_NS_BEGIN) #if defined(GEN_DONT_USE_NAMESPACE) && ! defined(GEN_NS_BEGIN)
@ -778,7 +778,6 @@ struct CodeBody
Define_CodeType( Attributes ); Define_CodeType( Attributes );
Define_CodeType( Comment ); Define_CodeType( Comment );
Define_CodeType( Class );
Define_CodeType( Enum ); Define_CodeType( Enum );
Define_CodeType( Exec ); Define_CodeType( Exec );
Define_CodeType( Extern ); Define_CodeType( Extern );
@ -789,14 +788,39 @@ Define_CodeType( Module );
Define_CodeType( Namespace ); Define_CodeType( Namespace );
Define_CodeType( Operator ); Define_CodeType( Operator );
Define_CodeType( OpCast ); Define_CodeType( OpCast );
Define_CodeType( Struct );
Define_CodeType( Template ); Define_CodeType( Template );
Define_CodeType( Type ); Define_CodeType( Type );
Define_CodeType(Typedef); Define_CodeType( Typedef );
Define_CodeType( Union ); Define_CodeType( Union );
Define_CodeType( Using ); Define_CodeType( Using );
Define_CodeType( Var ); Define_CodeType( Var );
struct CodeClass
{
Using_Code( CodeClass );
void add_interface( CodeType interface );
AST* raw()
{
return rcast( AST*, ast );
}
operator Code()
{
return * rcast( Code*, this );
}
AST_Class* operator->()
{
if ( ast == nullptr )
{
log_failure("Attempt to dereference a nullptr");
return nullptr;
}
return ast;
}
AST_Class* ast;
};
struct CodeParam struct CodeParam
{ {
Using_Code( CodeParam ); Using_Code( CodeParam );
@ -904,6 +928,32 @@ struct CodeSpecifiers
AST_Specifiers* ast; AST_Specifiers* ast;
}; };
struct CodeStruct
{
Using_Code( CodeStruct );
void add_interface( CodeType interface );
AST* raw()
{
return rcast( AST*, ast );
}
operator Code()
{
return * rcast( Code*, this );
}
AST_Struct* operator->()
{
if ( ast == nullptr )
{
log_failure("Attempt to dereference a nullptr");
return nullptr;
}
return ast;
}
AST_Struct* ast;
};
#undef Define_CodeType #undef Define_CodeType
#undef Using_Code #undef Using_Code
#pragma endregion Code Types #pragma endregion Code Types
@ -971,8 +1021,8 @@ struct AST_Class
CodeBody Body; CodeBody Body;
}; };
}; };
Code Prev; CodeType Last;
Code Next; CodeType Next;
Code Parent; Code Parent;
StringCached Name; StringCached Name;
CodeT Type; CodeT Type;
@ -1223,8 +1273,8 @@ struct AST_Struct
CodeBody Body; CodeBody Body;
}; };
}; };
Code Prev; CodeType Last;
Code Next; CodeType Next;
Code Parent; Code Parent;
StringCached Name; StringCached Name;
CodeT Type; CodeT Type;
@ -1407,7 +1457,8 @@ CodeClass def_class( StrC name
, Code body = NoCode , Code body = NoCode
, CodeType parent = NoCode, AccessSpec access = AccessSpec::Default , CodeType parent = NoCode, AccessSpec access = AccessSpec::Default
, CodeAttributes attributes = NoCode , CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
CodeEnum def_enum( StrC name CodeEnum def_enum( StrC name
, Code body = NoCode, CodeType type = NoCode , Code body = NoCode, CodeType type = NoCode
@ -1441,7 +1492,8 @@ CodeStruct def_struct( StrC name
, Code body = NoCode , Code body = NoCode
, CodeType parent = NoCode, AccessSpec access = AccessSpec::Default , CodeType parent = NoCode, AccessSpec access = AccessSpec::Default
, CodeAttributes attributes = NoCode , CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
CodeTemplate def_template( CodeParam params, Code definition, ModuleFlag mflags = ModuleFlag::None ); CodeTemplate def_template( CodeParam params, Code definition, ModuleFlag mflags = ModuleFlag::None );
@ -1737,8 +1789,8 @@ Define_AST_Cast( Namespace );
Define_AST_Cast( Operator ); Define_AST_Cast( Operator );
Define_AST_Cast( OpCast ); Define_AST_Cast( OpCast );
Define_AST_Cast( Param ); Define_AST_Cast( Param );
Define_AST_Cast( Specifiers );
Define_AST_Cast( Struct ); Define_AST_Cast( Struct );
Define_AST_Cast( Specifiers );
Define_AST_Cast( Template ); Define_AST_Cast( Template );
Define_AST_Cast( Type ); Define_AST_Cast( Type );
Define_AST_Cast( Typedef ); Define_AST_Cast( Typedef );
@ -1779,6 +1831,19 @@ Define_CodeCast( Body);
#undef Define_CodeCast #undef Define_CodeCast
#pragma endregion AST & Code Gen Common #pragma endregion AST & Code Gen Common
void CodeClass::add_interface( CodeType type )
{
if ( ! ast->Next )
{
ast->Next = type;
ast->Last = ast->Next;
return;
}
ast->Next->Next = type;
ast->Last = ast->Next->Next;
}
void CodeParam::append( CodeParam other ) void CodeParam::append( CodeParam other )
{ {
AST* self = (AST*) ast; AST* self = (AST*) ast;
@ -1828,6 +1893,18 @@ CodeParam& CodeParam::operator ++()
return * this; return * this;
} }
void CodeStruct::add_interface( CodeType type )
{
if ( ! ast->Next )
{
ast->Next = type;
ast->Last = ast->Next;
}
ast->Next->Next = type;
ast->Last = ast->Next->Next;
}
CodeBody def_body( CodeT type ) CodeBody def_body( CodeT type )
{ {
switch ( type ) switch ( type )
@ -2030,4 +2107,4 @@ StrC token_fmt_impl( sw num, ... )
GEN_NS_END GEN_NS_END
#include "gen.pop_ignores.inline.hpp" #include "helpers/gen.pop_ignores.inline.hpp"