mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 07:44:45 -08:00
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:
parent
d4c2cdf30e
commit
39390535ce
@ -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)
|
||||
* RAII : This needs support for constructors/destructor parsing
|
||||
* 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++":
|
||||
|
||||
|
@ -3,16 +3,20 @@
|
||||
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>` )
|
||||
|
||||
Dependencies are within `gen.dep.<hpp/cpp>`
|
||||
|
||||
|
||||
## gen.hpp
|
||||
|
||||
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_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_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.
|
||||
If constructing ASTs properly. There should be no modification of ASTs, and thus this would never become an issue.
|
||||
|
@ -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 region Platform Detection
|
@ -4,12 +4,12 @@
|
||||
#error Gen.hpp : GEN_TIME not defined
|
||||
#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.
|
||||
//! Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||
# include "gen.dep.cpp"
|
||||
# include "dependencies/gen.dep.cpp"
|
||||
#endif
|
||||
|
||||
#include "gen.hpp"
|
||||
@ -478,6 +478,17 @@ String AST::to_string()
|
||||
, ParentType->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
|
||||
{
|
||||
@ -902,6 +913,17 @@ String AST::to_string()
|
||||
, ParentType->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
|
||||
{
|
||||
@ -1182,7 +1204,8 @@ bool AST::validate_body()
|
||||
#pragma endregion AST
|
||||
|
||||
#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();
|
||||
|
||||
@ -1244,7 +1267,8 @@ internal void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw s
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
internal void define_constants()
|
||||
internal
|
||||
void define_constants()
|
||||
{
|
||||
Code::Global = make_code();
|
||||
Code::Global->Name = get_cached_string( txt_StrC("Global Code") );
|
||||
@ -2032,7 +2056,8 @@ CodeClass def_class( StrC name
|
||||
, Code body
|
||||
, CodeType parent, AccessSpec parent_access
|
||||
, CodeAttributes attributes
|
||||
, ModuleFlag mflags )
|
||||
, ModuleFlag mflags
|
||||
, CodeType* interfaces, s32 num_interfaces )
|
||||
{
|
||||
using namespace ECode;
|
||||
|
||||
@ -2085,6 +2110,14 @@ CodeClass def_class( StrC name
|
||||
result->ParentType = parent;
|
||||
}
|
||||
|
||||
if ( interfaces )
|
||||
{
|
||||
for (s32 idx = 0; idx < num_interfaces; idx++ )
|
||||
{
|
||||
result.add_interface( interfaces[idx] );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2523,7 +2556,8 @@ CodeStruct def_struct( StrC name
|
||||
, Code body
|
||||
, CodeType parent, AccessSpec parent_access
|
||||
, CodeAttributes attributes
|
||||
, ModuleFlag mflags )
|
||||
, ModuleFlag mflags
|
||||
, CodeType* interfaces, s32 num_interfaces )
|
||||
{
|
||||
using namespace ECode;
|
||||
|
||||
@ -2571,6 +2605,14 @@ CodeStruct def_struct( StrC name
|
||||
result->ParentType = parent;
|
||||
}
|
||||
|
||||
if ( interfaces )
|
||||
{
|
||||
for (s32 idx = 0; idx < num_interfaces; idx++ )
|
||||
{
|
||||
result.add_interface( interfaces[idx] );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -5162,6 +5204,7 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
|
||||
|
||||
Token name { nullptr, 0, TokType::Invalid };
|
||||
|
||||
AccessSpec access = AccessSpec::Default;
|
||||
CodeType parent = { nullptr };
|
||||
CodeBody body = { nullptr };
|
||||
CodeAttributes attributes = { nullptr };
|
||||
@ -5182,8 +5225,9 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
|
||||
if ( check( TokType::Identifier ) )
|
||||
name = parse_identifier( toks, context );
|
||||
|
||||
AccessSpec access = AccessSpec::Default;
|
||||
Token parent_tok = { nullptr, 0, TokType::Invalid };
|
||||
local_persist
|
||||
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 ) )
|
||||
{
|
||||
@ -5194,7 +5238,22 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
|
||||
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 ) )
|
||||
@ -5204,9 +5263,6 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
|
||||
|
||||
eat( TokType::Statement_End );
|
||||
|
||||
if ( parent_tok )
|
||||
parent = def_type( parent_tok );
|
||||
|
||||
if ( which == TokType::Decl_Class )
|
||||
result = def_class( name, body, parent, access
|
||||
, attributes
|
||||
@ -5219,6 +5275,7 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
|
||||
, mflags
|
||||
);
|
||||
|
||||
interfaces.free();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -6812,4 +6869,4 @@ void Builder::write()
|
||||
|
||||
GEN_NS_END
|
||||
|
||||
#include "gen.pop_ignores.inline.hpp"
|
||||
#include "helpers/gen.pop_ignores.inline.hpp"
|
||||
|
103
project/gen.hpp
103
project/gen.hpp
@ -12,12 +12,12 @@
|
||||
#error Gen.hpp : GEN_TIME not defined
|
||||
#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.
|
||||
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||
# include "gen.dep.hpp"
|
||||
# include "dependencies/gen.dep.hpp"
|
||||
#endif
|
||||
|
||||
#if defined(GEN_DONT_USE_NAMESPACE) && ! defined(GEN_NS_BEGIN)
|
||||
@ -778,7 +778,6 @@ struct CodeBody
|
||||
|
||||
Define_CodeType( Attributes );
|
||||
Define_CodeType( Comment );
|
||||
Define_CodeType( Class );
|
||||
Define_CodeType( Enum );
|
||||
Define_CodeType( Exec );
|
||||
Define_CodeType( Extern );
|
||||
@ -789,14 +788,39 @@ Define_CodeType( Module );
|
||||
Define_CodeType( Namespace );
|
||||
Define_CodeType( Operator );
|
||||
Define_CodeType( OpCast );
|
||||
Define_CodeType( Struct );
|
||||
Define_CodeType( Template );
|
||||
Define_CodeType( Type );
|
||||
Define_CodeType(Typedef);
|
||||
Define_CodeType( Typedef );
|
||||
Define_CodeType( Union );
|
||||
Define_CodeType( Using );
|
||||
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
|
||||
{
|
||||
Using_Code( CodeParam );
|
||||
@ -904,6 +928,32 @@ struct CodeSpecifiers
|
||||
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 Using_Code
|
||||
#pragma endregion Code Types
|
||||
@ -971,8 +1021,8 @@ struct AST_Class
|
||||
CodeBody Body;
|
||||
};
|
||||
};
|
||||
Code Prev;
|
||||
Code Next;
|
||||
CodeType Last;
|
||||
CodeType Next;
|
||||
Code Parent;
|
||||
StringCached Name;
|
||||
CodeT Type;
|
||||
@ -1223,8 +1273,8 @@ struct AST_Struct
|
||||
CodeBody Body;
|
||||
};
|
||||
};
|
||||
Code Prev;
|
||||
Code Next;
|
||||
CodeType Last;
|
||||
CodeType Next;
|
||||
Code Parent;
|
||||
StringCached Name;
|
||||
CodeT Type;
|
||||
@ -1407,7 +1457,8 @@ CodeClass def_class( StrC name
|
||||
, Code body = NoCode
|
||||
, CodeType parent = NoCode, AccessSpec access = AccessSpec::Default
|
||||
, CodeAttributes attributes = NoCode
|
||||
, ModuleFlag mflags = ModuleFlag::None );
|
||||
, ModuleFlag mflags = ModuleFlag::None
|
||||
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
|
||||
|
||||
CodeEnum def_enum( StrC name
|
||||
, Code body = NoCode, CodeType type = NoCode
|
||||
@ -1441,7 +1492,8 @@ CodeStruct def_struct( StrC name
|
||||
, Code body = NoCode
|
||||
, CodeType parent = NoCode, AccessSpec access = AccessSpec::Default
|
||||
, 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 );
|
||||
|
||||
@ -1737,8 +1789,8 @@ Define_AST_Cast( Namespace );
|
||||
Define_AST_Cast( Operator );
|
||||
Define_AST_Cast( OpCast );
|
||||
Define_AST_Cast( Param );
|
||||
Define_AST_Cast( Specifiers );
|
||||
Define_AST_Cast( Struct );
|
||||
Define_AST_Cast( Specifiers );
|
||||
Define_AST_Cast( Template );
|
||||
Define_AST_Cast( Type );
|
||||
Define_AST_Cast( Typedef );
|
||||
@ -1779,6 +1831,19 @@ Define_CodeCast( Body);
|
||||
#undef Define_CodeCast
|
||||
#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 )
|
||||
{
|
||||
AST* self = (AST*) ast;
|
||||
@ -1828,6 +1893,18 @@ CodeParam& CodeParam::operator ++()
|
||||
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 )
|
||||
{
|
||||
switch ( type )
|
||||
@ -2030,4 +2107,4 @@ StrC token_fmt_impl( sw num, ... )
|
||||
|
||||
GEN_NS_END
|
||||
|
||||
#include "gen.pop_ignores.inline.hpp"
|
||||
#include "helpers/gen.pop_ignores.inline.hpp"
|
||||
|
Loading…
Reference in New Issue
Block a user