mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 15:54:45 -08:00
Design: Added additional keywords to specifiers, added def_friend. Fleshed out scanner.
This commit is contained in:
parent
fcf037d50f
commit
f5fe30e7cb
336
project/gen.cpp
336
project/gen.cpp
@ -72,10 +72,11 @@ namespace gen
|
|||||||
static TypeTable TypeMap;
|
static TypeTable TypeMap;
|
||||||
|
|
||||||
static sw InitSize_CodePool = megabytes(64);
|
static sw InitSize_CodePool = megabytes(64);
|
||||||
static sw InitSize_StringArena = megabytes(32);
|
|
||||||
static sw InitSize_StringTable = megabytes(4);
|
static sw InitSize_StringTable = megabytes(4);
|
||||||
static sw InitSize_TypeTable = megabytes(4);
|
static sw InitSize_TypeTable = megabytes(4);
|
||||||
|
|
||||||
|
static sw SizePer_StringArena = megabytes(32);
|
||||||
|
|
||||||
static allocator Allocator_CodePool = heap();
|
static allocator Allocator_CodePool = heap();
|
||||||
static allocator Allocator_StringArena = heap();
|
static allocator Allocator_StringArena = heap();
|
||||||
static allocator Allocator_StringTable = heap();
|
static allocator Allocator_StringTable = heap();
|
||||||
@ -111,33 +112,6 @@ namespace gen
|
|||||||
Code spec_inline;
|
Code spec_inline;
|
||||||
#pragma endregion CONSTANTS
|
#pragma endregion CONSTANTS
|
||||||
|
|
||||||
/*
|
|
||||||
Used internally to retireve a Code object form the CodePool.
|
|
||||||
*/
|
|
||||||
static Code make_code()
|
|
||||||
{
|
|
||||||
using namespace StaticData;
|
|
||||||
|
|
||||||
# ifndef GEN_CODE_USE_SOA
|
|
||||||
ct CodePOD Invalid = { ECode::Invalid, false, nullptr, nullptr, nullptr, { nullptr } };
|
|
||||||
|
|
||||||
array_append( CodePool, Invalid );
|
|
||||||
|
|
||||||
return pcast( Code, array_back( CodePool ));
|
|
||||||
# else
|
|
||||||
|
|
||||||
array_append( CodePool::Type, ECode::Invalid );
|
|
||||||
array_append( CodePool::Readonly, false );
|
|
||||||
array_append( CodePool::Name, nullptr );
|
|
||||||
array_append( CodePool::Comment, nullptr );
|
|
||||||
array_append( CodePool::Data, { nullptr } );
|
|
||||||
|
|
||||||
Code code { array_count( CodePool::Type) - 1 };
|
|
||||||
|
|
||||||
return code;
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
# pragma region AST
|
# pragma region AST
|
||||||
bool AST::add( AST* other )
|
bool AST::add( AST* other )
|
||||||
{
|
{
|
||||||
@ -356,7 +330,7 @@ namespace gen
|
|||||||
array_init( StaticData::StringArenas, heap() );
|
array_init( StaticData::StringArenas, heap() );
|
||||||
|
|
||||||
arena string_arena;
|
arena string_arena;
|
||||||
arena_init_from_allocator( & string_arena, StaticData::Allocator_StringArena, StaticData::InitSize_StringArena );
|
arena_init_from_allocator( & string_arena, StaticData::Allocator_StringArena, StaticData::SizePer_StringArena );
|
||||||
|
|
||||||
str_tbl_init( & StaticData::StringMap, StaticData::Allocator_StringTable );
|
str_tbl_init( & StaticData::StringMap, StaticData::Allocator_StringTable );
|
||||||
type_tbl_init( & StaticData::TypeMap, StaticData::Allocator_TypeTable );
|
type_tbl_init( & StaticData::TypeMap, StaticData::Allocator_TypeTable );
|
||||||
@ -427,7 +401,7 @@ namespace gen
|
|||||||
if ( StringArenas->total_allocated + str_length > StringArenas->total_size )
|
if ( StringArenas->total_allocated + str_length > StringArenas->total_size )
|
||||||
{
|
{
|
||||||
arena new_arena;
|
arena new_arena;
|
||||||
arena_init_from_allocator( & new_arena, Allocator_StringArena, InitSize_StringArena );
|
arena_init_from_allocator( & new_arena, Allocator_StringArena, SizePer_StringArena );
|
||||||
|
|
||||||
array_append( StringArenas, new_arena );
|
array_append( StringArenas, new_arena );
|
||||||
|
|
||||||
@ -438,7 +412,7 @@ namespace gen
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Will either make or retrive a code string.
|
// Will either make or retrive a code string.
|
||||||
string code_string( char const* cstr, s32 length )
|
ro_string cached_string( char const* cstr, s32 length )
|
||||||
{
|
{
|
||||||
s32 hash_length = length > kilobytes(1) ? kilobytes(1) : length;
|
s32 hash_length = length > kilobytes(1) ? kilobytes(1) : length;
|
||||||
|
|
||||||
@ -451,11 +425,40 @@ namespace gen
|
|||||||
return * result;
|
return * result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* result = string_make( get_string_allocator( length ), cstr );
|
||||||
|
|
||||||
str_tbl_set( & StaticData::StringMap, key, * result );
|
str_tbl_set( & StaticData::StringMap, key, * result );
|
||||||
|
|
||||||
return * result;
|
return * result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Used internally to retireve a Code object form the CodePool.
|
||||||
|
*/
|
||||||
|
Code make_code()
|
||||||
|
{
|
||||||
|
using namespace StaticData;
|
||||||
|
|
||||||
|
# ifndef GEN_CODE_USE_SOA
|
||||||
|
ct CodePOD Invalid = { nullptr, nullptr, nullptr, nullptr, ECode::Invalid, EOperator::Invalid, false, {0} };
|
||||||
|
|
||||||
|
array_append( CodePool, Invalid );
|
||||||
|
|
||||||
|
return pcast( Code, array_back( CodePool ));
|
||||||
|
# else
|
||||||
|
|
||||||
|
array_append( CodePool::Type, ECode::Invalid );
|
||||||
|
array_append( CodePool::Readonly, false );
|
||||||
|
array_append( CodePool::Name, nullptr );
|
||||||
|
array_append( CodePool::Comment, nullptr );
|
||||||
|
array_append( CodePool::Data, { nullptr } );
|
||||||
|
|
||||||
|
Code code { array_count( CodePool::Type) - 1 };
|
||||||
|
|
||||||
|
return code;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
void set_init_reserve_code_pool( sw size )
|
void set_init_reserve_code_pool( sw size )
|
||||||
{
|
{
|
||||||
StaticData::InitSize_CodePool = size;
|
StaticData::InitSize_CodePool = size;
|
||||||
@ -501,6 +504,12 @@ namespace gen
|
|||||||
{
|
{
|
||||||
using namespace ECode;
|
using namespace ECode;
|
||||||
|
|
||||||
|
if ( length <= 0 )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_class: Invalid name length provided - %d", length );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
if ( name == nullptr )
|
if ( name == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_class: name is null");
|
log_failure( "gen::def_class: name is null");
|
||||||
@ -509,16 +518,24 @@ namespace gen
|
|||||||
|
|
||||||
if ( parent && parent->Type != Class || parent->Type != Struct )
|
if ( parent && parent->Type != Class || parent->Type != Struct )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_class: parent provided is not type 'Class' or 'Struct' - Type: %s", parent->type_str() );
|
log_failure( "gen::def_class: parent provided is not type 'Class' or 'Struct' - Type: %s", parent->debug_str() );
|
||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( specifiers && specifiers->Type != Specifiers )
|
if ( specifiers && specifiers->Type != Specifiers )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_class: specifiers was not a 'Specifiers' type - Type: %s", specifiers->type_str() );
|
log_failure( "gen::def_class: specifiers was not a 'Specifiers' type - Type: %s", specifiers->debug_str() );
|
||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Code
|
||||||
|
result = make_code();
|
||||||
|
result->Name = cached_string( name, length );
|
||||||
|
|
||||||
|
array_init( result->Entries, StaticData::Allocator_CodePool );
|
||||||
|
|
||||||
|
if ( body )
|
||||||
|
{
|
||||||
switch ( body->Type )
|
switch ( body->Type )
|
||||||
{
|
{
|
||||||
case Class_Body:
|
case Class_Body:
|
||||||
@ -526,18 +543,10 @@ namespace gen
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log_failure("gen_def_class: body must be either of Function_Body or Untyped type.");
|
log_failure("gen::def_class: body must be either of Class_Body or Untyped type - %s", body->debug_str());
|
||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Name = code_string( name, length );
|
|
||||||
|
|
||||||
array_init( result->Entries, StaticData::Allocator_CodePool );
|
|
||||||
|
|
||||||
if ( body )
|
|
||||||
{
|
|
||||||
result->Type = Class;
|
result->Type = Class;
|
||||||
result->add_entry( body );
|
result->add_entry( body );
|
||||||
}
|
}
|
||||||
@ -558,9 +567,12 @@ namespace gen
|
|||||||
|
|
||||||
Code def_enum( s32 length, char const* name, Code type, Code body )
|
Code def_enum( s32 length, char const* name, Code type, Code body )
|
||||||
{
|
{
|
||||||
|
using namespace ECode;
|
||||||
|
|
||||||
if ( length <= 0 )
|
if ( length <= 0 )
|
||||||
{
|
{
|
||||||
log_failure( "gen_def_enum: Invalid name length provided - %d", length );
|
log_failure( "gen::def_enum: Invalid name length provided - %d", length );
|
||||||
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( name == nullptr )
|
if ( name == nullptr )
|
||||||
@ -569,10 +581,47 @@ namespace gen
|
|||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( type && type->Type != Typename )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_enum: enum underlying type provided was not of type Typename: %s", type->debug_str() );
|
||||||
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code def_function( char const* name
|
Code
|
||||||
|
result = make_code();
|
||||||
|
result->Name = cached_string( name, length );
|
||||||
|
|
||||||
|
if ( body )
|
||||||
|
{
|
||||||
|
switch ( body->Type )
|
||||||
|
{
|
||||||
|
case Enum_Body:
|
||||||
|
case Untyped:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log_failure( "gen::def_enum: body must be of Enum_Body or Untyped type %s", body->debug_str());
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
result->Type = Enum;
|
||||||
|
result->add_entry( body );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result->Type = Enum_FwdDecl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( type )
|
||||||
|
{
|
||||||
|
result->add_entry( type );
|
||||||
|
}
|
||||||
|
|
||||||
|
result.lock();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Code def_function( s32 length, char const* name
|
||||||
, Code specifiers
|
, Code specifiers
|
||||||
, Code params
|
, Code params
|
||||||
, Code ret_type
|
, Code ret_type
|
||||||
@ -581,24 +630,44 @@ namespace gen
|
|||||||
{
|
{
|
||||||
using namespace ECode;
|
using namespace ECode;
|
||||||
|
|
||||||
|
if ( length <= 0 )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_function: Invalid name length provided - %d", length );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( name == nullptr )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_function: name is null" );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
if ( specifiers && specifiers->Type != Specifiers )
|
if ( specifiers && specifiers->Type != Specifiers )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_function: specifiers was not a `Specifiers` type" );
|
log_failure( "gen::def_function: specifiers was not a `Specifiers` type %s", specifiers->debug_str() );
|
||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( params && params->Type != Parameters )
|
if ( params && params->Type != Parameters )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_function: params was not a `Parameters` type" );
|
log_failure( "gen::def_function: params was not a `Parameters` type %s", params->debug_str() );
|
||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ret_type == nullptr || ret_type->Type != Typename )
|
if ( ret_type == nullptr || ret_type->Type != Typename )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_function: ret_type was not a Typename" );
|
log_failure( "gen::def_function: ret_type was not a Typename %s", ret_type->debug_str() );
|
||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Code
|
||||||
|
result = make_code();
|
||||||
|
result->Name = cached_string( name, length );
|
||||||
|
|
||||||
|
array_init( result->Entries, StaticData::Allocator_CodePool );
|
||||||
|
|
||||||
|
if ( body )
|
||||||
|
{
|
||||||
switch ( body->Type )
|
switch ( body->Type )
|
||||||
{
|
{
|
||||||
case Function_Body:
|
case Function_Body:
|
||||||
@ -607,26 +676,30 @@ namespace gen
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
log_failure("gen::def_function: body must be either of Function_Body or Untyped type.");
|
log_failure("gen::def_function: body must be either of Function_Body or Untyped type. %s", body->debug_str());
|
||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 name_length = zpl_strnlen( name, MaxNameLength );
|
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Name = code_string( name, name_length );
|
|
||||||
result->Type = Function;
|
result->Type = Function;
|
||||||
|
|
||||||
array_init( result->Entries, StaticData::Allocator_CodePool );
|
|
||||||
|
|
||||||
result->add_entry( body );
|
result->add_entry( body );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result->Type = Function_FwdDecl;
|
||||||
|
}
|
||||||
|
|
||||||
if ( specifiers )
|
if ( specifiers )
|
||||||
result->add_entry( specifiers );
|
result->add_entry( specifiers );
|
||||||
|
|
||||||
|
if ( ret_type )
|
||||||
|
{
|
||||||
result->add_entry( ret_type );
|
result->add_entry( ret_type );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result->add_entry( type_ns(void) );
|
||||||
|
}
|
||||||
|
|
||||||
if ( params )
|
if ( params )
|
||||||
result->add_entry( params );
|
result->add_entry( params );
|
||||||
@ -635,6 +708,45 @@ namespace gen
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Code def_namespace( s32 length, char const* name, Code body )
|
||||||
|
{
|
||||||
|
using namespace ECode;
|
||||||
|
|
||||||
|
if ( length <= 0 )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_namespace: Invalid name length provided - %d", length );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( name == nullptr )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_namespace: name is null" );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Code
|
||||||
|
result = make_code();
|
||||||
|
result->Type = Namespace;
|
||||||
|
result->Name = cached_string( name, length );
|
||||||
|
|
||||||
|
array_init( result->Entries, g_allocator );
|
||||||
|
|
||||||
|
if ( body->Type != Namespace_Body || body->Type != Untyped )
|
||||||
|
{
|
||||||
|
log_failure("gen::def_namespace: body is not of namespace or untyped type %s", body->debug_str());
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
result->add_entry( body );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Code def_operator( OperatorT Op, Code params, Code ret_type, Code specifiers, Code body )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Code def_function_body( s32 num, ... )
|
Code def_function_body( s32 num, ... )
|
||||||
{
|
{
|
||||||
using namespace ECode;
|
using namespace ECode;
|
||||||
@ -763,7 +875,7 @@ namespace gen
|
|||||||
char const* name = va_arg(va, char const*);
|
char const* name = va_arg(va, char const*);
|
||||||
s32 name_length = zpl_strnlen(name, MaxNameLength);
|
s32 name_length = zpl_strnlen(name, MaxNameLength);
|
||||||
|
|
||||||
result->Name = code_string( name, name_length );
|
result->Name = cached_string( name, name_length );
|
||||||
|
|
||||||
array_init( result->Entries, g_allocator );
|
array_init( result->Entries, g_allocator );
|
||||||
|
|
||||||
@ -785,7 +897,7 @@ namespace gen
|
|||||||
Code
|
Code
|
||||||
param = make_code();
|
param = make_code();
|
||||||
param->Type = Parameters;
|
param->Type = Parameters;
|
||||||
param->Name = code_string(name, name_length);
|
param->Name = cached_string(name, name_length);
|
||||||
|
|
||||||
array_init( param->Entries, StaticData::Allocator_CodePool );
|
array_init( param->Entries, StaticData::Allocator_CodePool );
|
||||||
|
|
||||||
@ -806,27 +918,6 @@ namespace gen
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code def_namespace( char const* name, Code body )
|
|
||||||
{
|
|
||||||
using namespace ECode;
|
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Type = Namespace;
|
|
||||||
|
|
||||||
array_init( result->Entries, g_allocator );
|
|
||||||
|
|
||||||
if ( body->Type != Namespace_Body || body->Type != Untyped )
|
|
||||||
{
|
|
||||||
log_failure("gen::def_namespace: body is not of namespace or untyped type");
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
result->add_entry( body );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code def_namespace_body( s32 num, ... )
|
Code def_namespace_body( s32 num, ... )
|
||||||
{
|
{
|
||||||
using namespace ECode;
|
using namespace ECode;
|
||||||
@ -874,10 +965,19 @@ namespace gen
|
|||||||
if ( num <= 0 )
|
if ( num <= 0 )
|
||||||
fatal("gen::make_specifier: num cannot be zero or less");
|
fatal("gen::make_specifier: num cannot be zero or less");
|
||||||
|
|
||||||
|
// This should be more than enough...
|
||||||
|
static u8 FixedSizedBuffer[kilobytes(1024)];
|
||||||
|
|
||||||
|
static arena str_arena;
|
||||||
|
do_once_start
|
||||||
|
arena_init_from_memory( & str_arena, FixedSizedBuffer, kilobytes(1024) );
|
||||||
|
do_once_end
|
||||||
|
|
||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
result->Type = ECode::Specifiers;
|
result->Type = ECode::Specifiers;
|
||||||
result->Content = string_make( g_allocator, "" );
|
|
||||||
|
string crafted = string_make( arena_allocator( & str_arena ), "" );
|
||||||
|
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, num);
|
va_start(va, num);
|
||||||
@ -888,26 +988,42 @@ namespace gen
|
|||||||
switch ( type )
|
switch ( type )
|
||||||
{
|
{
|
||||||
case ESpecifier::Alignas:
|
case ESpecifier::Alignas:
|
||||||
result->Content = string_append_fmt( result->Content, "%s(%d)", ESpecifier::to_str(type), va_arg(va, u32) );
|
crafted = string_append_fmt( result->Content, "%s(%d)", ESpecifier::to_str(type), va_arg(va, u32) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
const char* str = ESpecifier::to_str(type);
|
const char* str = ESpecifier::to_str(type);
|
||||||
|
|
||||||
result->Content = string_append_fmt( result->Content, "%s", str );
|
crafted = string_append_fmt( result->Content, "%s", str );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while ( --num, num );
|
while ( --num, num );
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
|
result->Content = cached_string( crafted, string_length( crafted ) );
|
||||||
|
|
||||||
|
arena_free( & str_arena );
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code def_struct( char const* name, Code body, Code parent, Code specifiers )
|
Code def_struct( u32 length, char const* name, Code body, Code parent, Code specifiers )
|
||||||
{
|
{
|
||||||
using namespace ECode;
|
using namespace ECode;
|
||||||
|
|
||||||
|
if ( length <= 0 )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_function: Invalid name length provided - %d", length );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( name == nullptr )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_function: name is null" );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
if ( specifiers && specifiers->Type != Specifiers )
|
if ( specifiers && specifiers->Type != Specifiers )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_struct: specifiers was not a `Specifiers` type" );
|
log_failure( "gen::def_struct: specifiers was not a `Specifiers` type" );
|
||||||
@ -929,7 +1045,7 @@ namespace gen
|
|||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
result->Type = Struct;
|
result->Type = Struct;
|
||||||
result->Name = string_make( g_allocator, name );
|
result->Name = cached_string( name, length );
|
||||||
|
|
||||||
array_init( result->Entries, g_allocator );
|
array_init( result->Entries, g_allocator );
|
||||||
|
|
||||||
@ -987,8 +1103,20 @@ namespace gen
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code def_variable( Code type, char const* name, Code value, Code specifiers )
|
Code def_variable( Code type, u32 length, char const* name, Code value, Code specifiers )
|
||||||
{
|
{
|
||||||
|
if ( length <= 0 )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_function: Invalid name length provided - %d", length );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( name == nullptr )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_function: name is null" );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
if ( specifiers && specifiers->Type != ECode::Specifiers )
|
if ( specifiers && specifiers->Type != ECode::Specifiers )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_variable: specifiers was not a `Specifiers` type" );
|
log_failure( "gen::def_variable: specifiers was not a `Specifiers` type" );
|
||||||
@ -1009,7 +1137,7 @@ namespace gen
|
|||||||
|
|
||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
result->Name = string_make( g_allocator, name );
|
result->Name = cached_string( name, length );
|
||||||
result->Type = ECode::Variable;
|
result->Type = ECode::Variable;
|
||||||
|
|
||||||
array_init( result->Entries, g_allocator );
|
array_init( result->Entries, g_allocator );
|
||||||
@ -1025,21 +1153,45 @@ namespace gen
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code def_type( char const* name, Code specifiers )
|
Code def_type( u32 length, char const* name, Code specifiers )
|
||||||
{
|
{
|
||||||
|
if ( length <= 0 )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_function: Invalid name length provided - %d", length );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( name == nullptr )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_function: name is null" );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
result->Name = string_make( g_allocator, name );
|
result->Name = cached_string( name, length );
|
||||||
result->Type = ECode::Typename;
|
result->Type = ECode::Typename;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code def_using( char const* name, Code type )
|
Code def_using( u32 length, char const* name, Code type )
|
||||||
{
|
{
|
||||||
|
if ( length <= 0 )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_function: Invalid name length provided - %d", length );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( name == nullptr )
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_function: name is null" );
|
||||||
|
return Code::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
result->Name = string_make( g_allocator, name );
|
result->Name = cached_string( name, length );
|
||||||
result->Type = ECode::Using;
|
result->Type = ECode::Using;
|
||||||
|
|
||||||
array_init( result->Entries, g_allocator );
|
array_init( result->Entries, g_allocator );
|
||||||
@ -1295,7 +1447,7 @@ namespace gen
|
|||||||
|
|
||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
result->Name = string_make( g_allocator, name );
|
result->Name = cached_string( name, name_length );
|
||||||
result->Type = ECode::Function;
|
result->Type = ECode::Function;
|
||||||
|
|
||||||
array_init( result->Entries, g_allocator );
|
array_init( result->Entries, g_allocator );
|
||||||
|
434
project/gen.hpp
434
project/gen.hpp
@ -18,6 +18,22 @@
|
|||||||
* Modern C++ (STL library) features
|
* Modern C++ (STL library) features
|
||||||
* Modern C++ RTTI : This is kinda covered with the last point, but just wanted to emphasize.
|
* Modern C++ RTTI : This is kinda covered with the last point, but just wanted to emphasize.
|
||||||
|
|
||||||
|
Exceptions brought in from "Modern C++":
|
||||||
|
Specifiers:
|
||||||
|
* consteval
|
||||||
|
* constinit
|
||||||
|
* explicit
|
||||||
|
* export
|
||||||
|
* noexcept
|
||||||
|
* import
|
||||||
|
* final
|
||||||
|
* module
|
||||||
|
* override
|
||||||
|
* &&
|
||||||
|
* virtual
|
||||||
|
|
||||||
|
These features are in as they are just specifiers and aren't hard to implement seralization or validation.
|
||||||
|
|
||||||
The AST is managed by the library and provided the user via its interface prodedures.
|
The AST is managed by the library and provided the user via its interface prodedures.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
@ -60,6 +76,7 @@
|
|||||||
* def_class
|
* def_class
|
||||||
* def_enum
|
* def_enum
|
||||||
* def_enum_class
|
* def_enum_class
|
||||||
|
* def_friend
|
||||||
* def_function
|
* def_function
|
||||||
* def_namespace
|
* def_namespace
|
||||||
* def_operator
|
* def_operator
|
||||||
@ -113,6 +130,7 @@
|
|||||||
|
|
||||||
* parse_class
|
* parse_class
|
||||||
* parse_enum
|
* parse_enum
|
||||||
|
* parse_friend
|
||||||
* parse_function
|
* parse_function
|
||||||
* parse_global_body
|
* parse_global_body
|
||||||
* parse_namespace
|
* parse_namespace
|
||||||
@ -173,6 +191,8 @@
|
|||||||
#define GEN_DEFINE_DSL
|
#define GEN_DEFINE_DSL
|
||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
#define GEN_USE_FATAL
|
#define GEN_USE_FATAL
|
||||||
|
#define GEN_FEATURE_EDITOR
|
||||||
|
#define GEN_FEATURE_SCANNER
|
||||||
|
|
||||||
|
|
||||||
#ifdef gen_time
|
#ifdef gen_time
|
||||||
@ -192,37 +212,42 @@ namespace gen
|
|||||||
|
|
||||||
namespace ECode
|
namespace ECode
|
||||||
{
|
{
|
||||||
enum Type : u8
|
# define Define_Types \
|
||||||
{
|
Entry( Untyped ) \
|
||||||
Invalid,
|
Entry( Access_Public ) \
|
||||||
Untyped,
|
Entry( Access_Private ) \
|
||||||
Access_Public,
|
Entry( Access_Protected ) \
|
||||||
Access_Private,
|
Entry( Class ) \
|
||||||
Access_Protected,
|
Entry( Class_FwdDecl ) \
|
||||||
Class,
|
Entry( Class_Body ) \
|
||||||
Class_FwdDecl,
|
Entry( Enum ) \
|
||||||
Class_Body,
|
Entry( Enum_FwdDecl ) \
|
||||||
Enum,
|
Entry( Enum_Body ) \
|
||||||
Enum_FwdDecl,
|
Entry( Friend ) \
|
||||||
Enum_Body,
|
Entry( Global_Body ) \
|
||||||
Friend,
|
Entry( Namespace ) \
|
||||||
Global_Body,
|
Entry( Namespace_Body ) \
|
||||||
Namespace,
|
Entry( Parameters ) \
|
||||||
Namespace_Body,
|
Entry( Function ) \
|
||||||
Parameters,
|
Entry( Function_FwdDecl ) \
|
||||||
Function,
|
Entry( Function_Body ) \
|
||||||
Function_FwdDecl,
|
Entry( Specifiers ) \
|
||||||
Function_Body,
|
Entry( Struct ) \
|
||||||
Specifiers,
|
Entry( Struct_FwdDecl ) \
|
||||||
Struct,
|
Entry( Struct_Body ) \
|
||||||
Struct_FwdDecl,
|
Entry( Variable ) \
|
||||||
Struct_Body,
|
Entry( Typedef ) \
|
||||||
Variable,
|
Entry( Typename ) \
|
||||||
Typedef,
|
Entry( Using )
|
||||||
Typename,
|
|
||||||
Using,
|
|
||||||
|
|
||||||
Num_Types
|
enum Type : u32
|
||||||
|
{
|
||||||
|
# define Entry( Type ) Type,
|
||||||
|
Define_Types
|
||||||
|
# undef Entry
|
||||||
|
|
||||||
|
Num_Types,
|
||||||
|
Invalid
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -230,49 +255,72 @@ namespace gen
|
|||||||
{
|
{
|
||||||
static
|
static
|
||||||
char const* lookup[Num_Types] = {
|
char const* lookup[Num_Types] = {
|
||||||
"Invalid",
|
# define Entry( Type ) txt( Type ),
|
||||||
"Untyped",
|
Define_Types
|
||||||
"Access_Public",
|
# undef Entry
|
||||||
"Access_Private",
|
|
||||||
"Access_Protected",
|
|
||||||
"Class",
|
|
||||||
"Class_FwdDecl",
|
|
||||||
"Class_Body",
|
|
||||||
"Enum",
|
|
||||||
"Enum_FwdDecl",
|
|
||||||
"Enum_Body",
|
|
||||||
"Function",
|
|
||||||
"Function_FwdDecl",
|
|
||||||
"Function_Body",
|
|
||||||
"Global_Body",
|
|
||||||
"Namespace",
|
|
||||||
"Namespace_Body",
|
|
||||||
"Parameters",
|
|
||||||
"Specifiers",
|
|
||||||
"Struct",
|
|
||||||
"Struct_Body",
|
|
||||||
"Variable",
|
|
||||||
"Typedef",
|
|
||||||
"Typename",
|
|
||||||
"Using",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return lookup[ type ];
|
return lookup[ type ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# undef Define_Types
|
||||||
}
|
}
|
||||||
using CodeT = ECode::Type;
|
using CodeT = ECode::Type;
|
||||||
|
|
||||||
namespace EOperator
|
namespace EOperator
|
||||||
{
|
{
|
||||||
enum Type : u8
|
# define Define_Operators \
|
||||||
{
|
Entry( Assign, = ) \
|
||||||
Add,
|
Entry( Assign_Add, += ) \
|
||||||
Subtract,
|
Entry( Assign_Subtract, -= ) \
|
||||||
Multiply,
|
Entry( Assgin_Multiply, *= ) \
|
||||||
Divide,
|
Entry( Assgin_Divide, /= ) \
|
||||||
Modulo,
|
Entry( Assgin_Modulo, %= ) \
|
||||||
|
Entry( Assgin_BAnd, &= ) \
|
||||||
|
Entry( Assgin_BOr, &= ) \
|
||||||
|
Entry( Assign_BXOr, ^= ) \
|
||||||
|
Entry( Assign_LShift, <<= ) \
|
||||||
|
Entry( Assign_RShift, >>= ) \
|
||||||
|
Entry( Increment, ++ ) \
|
||||||
|
Entry( Decrement, -- ) \
|
||||||
|
Entry( Unary_Plus, + ) \
|
||||||
|
Entry( Unary_Minus, - ) \
|
||||||
|
Entry( Add, + ) \
|
||||||
|
Entry( Subtract, - ) \
|
||||||
|
Entry( Multiply, * ) \
|
||||||
|
Entry( Divide, / ) \
|
||||||
|
Entry( Modulo, % ) \
|
||||||
|
Entry( BNot, ~ ) \
|
||||||
|
Entry( BAnd, & ) \
|
||||||
|
Entry( BOr, | ) \
|
||||||
|
Entry( BXOr, ^ ) \
|
||||||
|
Entry( LShift, << ) \
|
||||||
|
Entry( RShift, >> ) \
|
||||||
|
Entry( LNot, ! ) \
|
||||||
|
Entry( LAnd, && ) \
|
||||||
|
Entry( LOr, || ) \
|
||||||
|
Entry( Equals, == ) \
|
||||||
|
Entry( NotEquals, != ) \
|
||||||
|
Entry( Lesser, < ) \
|
||||||
|
Entry( Greater, > ) \
|
||||||
|
Entry( LesserEqual, <= ) \
|
||||||
|
Entry( GreaterEqual, >= ) \
|
||||||
|
Entry( Subscript, [] ) \
|
||||||
|
Entry( Indirection, * ) \
|
||||||
|
Entry( AddressOf, & ) \
|
||||||
|
Entry( MemberOfPointer, -> ) \
|
||||||
|
Entry( PtrToMemOfPtr, ->* ) \
|
||||||
|
Entry( FunctionCall, () )
|
||||||
|
|
||||||
Num_Ops
|
enum Type : u32
|
||||||
|
{
|
||||||
|
# define Entry( Type, Token ) Type,
|
||||||
|
Define_Operators
|
||||||
|
# undef Entry
|
||||||
|
Comma,
|
||||||
|
|
||||||
|
Num_Ops,
|
||||||
|
Invalid
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -280,41 +328,74 @@ namespace gen
|
|||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
char const* lookup[ Num_Ops ] = {
|
char const* lookup[ Num_Ops ] = {
|
||||||
"+",
|
# define Entry( Type, Token ) txt(Token),
|
||||||
"-",
|
Define_Operators
|
||||||
"*",
|
# undef Entry
|
||||||
"/",
|
","
|
||||||
};
|
};
|
||||||
|
|
||||||
return lookup[ op ];
|
return lookup[ op ];
|
||||||
}
|
}
|
||||||
|
# undef Define_Operators
|
||||||
}
|
}
|
||||||
using OperatorT = EOperator::Type;
|
using OperatorT = EOperator::Type;
|
||||||
|
|
||||||
namespace ESpecifier
|
namespace ESpecifier
|
||||||
{
|
{
|
||||||
enum Type : u8
|
# if defined(ZPL_SYSTEM_WINDOWS)
|
||||||
|
# define API_Export_Code __declspec(dllexport)
|
||||||
|
# define API_Import_Code __declspec(dllimport)
|
||||||
|
# elif defined(ZPL_SYSTEM_MACOS)
|
||||||
|
# define API_Export_Code __attribute__ ((visibility ("default")))
|
||||||
|
# define API_Import_Code __attribute__ ((visibility ("default")))
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(ZPL_MODULE_THREADING)
|
||||||
|
# define Thread_Local_Code thread_local
|
||||||
|
# else
|
||||||
|
# define Thread_Local_Code "NOT DEFINED"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Entry( Explicit, explicit ) \
|
||||||
|
|
||||||
|
#define Define_Specifiers \
|
||||||
|
Entry( API_Import, API_Export_Code ) \
|
||||||
|
Entry( API_Export, API_Import_Code ) \
|
||||||
|
Entry( Attribute, "You cannot stringize an attribute this way" ) \
|
||||||
|
Entry( Alignas, alignas ) \
|
||||||
|
Entry( Const, const ) \
|
||||||
|
Entry( C_Linkage, extern "C" ) \
|
||||||
|
Entry( Consteval, consteval ) \
|
||||||
|
Entry( Constexpr, constexpr ) \
|
||||||
|
Entry( Constinit, constinit ) \
|
||||||
|
Entry( Export, export ) \
|
||||||
|
Entry( External_Linkage, extern ) \
|
||||||
|
Entry( Import, import ) \
|
||||||
|
Entry( Inline, inline ) \
|
||||||
|
Entry( Internal_Linkage, static ) \
|
||||||
|
Entry( Final, final ) \
|
||||||
|
Entry( Local_Persist, static ) \
|
||||||
|
Entry( Module, module ) \
|
||||||
|
Entry( Mutable, mutable ) \
|
||||||
|
Entry( NoExcept, noexcept ) \
|
||||||
|
Entry( Override, override ) \
|
||||||
|
Entry( Pointer, * ) \
|
||||||
|
Entry( Reference, & ) \
|
||||||
|
Entry( Register, register ) \
|
||||||
|
Entry( RValue, && ) \
|
||||||
|
Entry( Static_Member, static ) \
|
||||||
|
Entry( Thread_Local, Thread_Local_Code ) \
|
||||||
|
Entry( Virtual, virtual ) \
|
||||||
|
Entry( Volatile, volatile )
|
||||||
|
|
||||||
|
enum Type : u32
|
||||||
{
|
{
|
||||||
Attribute,
|
# define Entry( Specifier, Code ) Specifier,
|
||||||
Alignas,
|
Define_Specifiers
|
||||||
Constexpr,
|
# undef Entry
|
||||||
Const,
|
|
||||||
Inline,
|
|
||||||
Pointer,
|
|
||||||
Reference,
|
|
||||||
RValue,
|
|
||||||
|
|
||||||
C_Linkage,
|
|
||||||
API_Import,
|
|
||||||
API_Export,
|
|
||||||
External_Linkage,
|
|
||||||
Internal_Linkage,
|
|
||||||
Static_Member,
|
|
||||||
Local_Persist,
|
|
||||||
Thread_Local,
|
|
||||||
|
|
||||||
Invalid,
|
|
||||||
Num_Specifiers,
|
Num_Specifiers,
|
||||||
|
Invalid,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Specifier to string
|
// Specifier to string
|
||||||
@ -323,29 +404,9 @@ namespace gen
|
|||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
char const* lookup[ Num_Specifiers ] = {
|
char const* lookup[ Num_Specifiers ] = {
|
||||||
"alignas",
|
# define Entry( Spec_, Code_ ) txt(Code_),
|
||||||
"constexpr",
|
Define_Specifiers
|
||||||
"const",
|
# undef Entry
|
||||||
"inline",
|
|
||||||
"*",
|
|
||||||
"&",
|
|
||||||
"&&",
|
|
||||||
|
|
||||||
"extern \"C\"",
|
|
||||||
|
|
||||||
# if defined(ZPL_SYSTEM_WINDOWS)
|
|
||||||
"__declspec(dllexport)",
|
|
||||||
"__declspec(dllimport)",
|
|
||||||
# elif defined(ZPL_SYSTEM_MACOS)
|
|
||||||
"__attribute__ ((visibility (\"default\")))",
|
|
||||||
"__attribute__ ((visibility (\"default\")))",
|
|
||||||
# endif
|
|
||||||
|
|
||||||
"extern",
|
|
||||||
"static",
|
|
||||||
"static",
|
|
||||||
"static",
|
|
||||||
"thread_local"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return lookup[ specifier ];
|
return lookup[ specifier ];
|
||||||
@ -394,11 +455,13 @@ namespace gen
|
|||||||
forceinline
|
forceinline
|
||||||
void add_entry( AST* other )
|
void add_entry( AST* other )
|
||||||
{
|
{
|
||||||
array_append( Entries, other );
|
Code to_add = other->Parent ?
|
||||||
|
other->duplicate() : other;
|
||||||
|
|
||||||
other->Parent = this;
|
array_append( Entries, to_add );
|
||||||
|
|
||||||
|
to_add->Parent = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
AST* body()
|
AST* body()
|
||||||
{
|
{
|
||||||
@ -408,6 +471,8 @@ namespace gen
|
|||||||
forceinline
|
forceinline
|
||||||
bool check();
|
bool check();
|
||||||
|
|
||||||
|
Code duplicate();
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
bool has_entries() const
|
bool has_entries() const
|
||||||
{
|
{
|
||||||
@ -440,6 +505,27 @@ namespace gen
|
|||||||
return Type != ECode::Invalid;
|
return Type != ECode::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
char const* debug_str() const
|
||||||
|
{
|
||||||
|
char const* fmt = txt(
|
||||||
|
\nCode Debug:
|
||||||
|
\nType : %s
|
||||||
|
\nReadonly: %s
|
||||||
|
\nParent : %s
|
||||||
|
\nName : %s
|
||||||
|
\nComment : %s
|
||||||
|
);
|
||||||
|
|
||||||
|
bprintf( fmt
|
||||||
|
, type_str()
|
||||||
|
, Readonly ? "true" : "false"
|
||||||
|
, Parent ? Parent->Name : ""
|
||||||
|
, Name ? Name : ""
|
||||||
|
, Comment ? Comment : ""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
char const* type_str() const
|
char const* type_str() const
|
||||||
{
|
{
|
||||||
@ -450,15 +536,17 @@ namespace gen
|
|||||||
#pragma endregion Member Procedures
|
#pragma endregion Member Procedures
|
||||||
|
|
||||||
#define Using_Code_POD \
|
#define Using_Code_POD \
|
||||||
CodeT Type; \
|
|
||||||
bool Readonly; \
|
|
||||||
AST* Parent; \
|
AST* Parent; \
|
||||||
string Name; \
|
ro_string Name; \
|
||||||
string Comment; \
|
ro_string Comment; \
|
||||||
union { \
|
union { \
|
||||||
array(AST*) Entries; \
|
array(AST*) Entries; \
|
||||||
string Content; \
|
ro_string Content; \
|
||||||
};
|
}; \
|
||||||
|
CodeT Type; \
|
||||||
|
OperatorT Op; \
|
||||||
|
bool Readonly; \
|
||||||
|
u8 _64_Align[23];
|
||||||
|
|
||||||
Using_Code_POD;
|
Using_Code_POD;
|
||||||
};
|
};
|
||||||
@ -468,6 +556,9 @@ namespace gen
|
|||||||
Using_Code_POD;
|
Using_Code_POD;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ct u32 sizeof_AST = sizeof(AST);
|
||||||
|
ct u32 sizeof_CODE = sizeof(CodePOD);
|
||||||
|
|
||||||
// Its intended for the AST to have equivalent size to its POD.
|
// Its intended for the AST to have equivalent size to its POD.
|
||||||
// All extra functionality within the AST namespace should just be syntatic sugar.
|
// All extra functionality within the AST namespace should just be syntatic sugar.
|
||||||
static_assert( sizeof(AST) == sizeof(CodePOD), "ERROR: AST IS NOT POD" );
|
static_assert( sizeof(AST) == sizeof(CodePOD), "ERROR: AST IS NOT POD" );
|
||||||
@ -594,6 +685,8 @@ namespace gen
|
|||||||
*/
|
*/
|
||||||
ZPL_TABLE_DECLARE( ZPL_EXTERN, StringTable, str_tbl_, string );
|
ZPL_TABLE_DECLARE( ZPL_EXTERN, StringTable, str_tbl_, string );
|
||||||
|
|
||||||
|
using ro_string = char const*;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Type registy: Used to store Typename ASTs. Types are registered by their string literal value.
|
Type registy: Used to store Typename ASTs. Types are registered by their string literal value.
|
||||||
|
|
||||||
@ -615,6 +708,19 @@ namespace gen
|
|||||||
// And rather get rid of current code asts instead of growing the pool memory.
|
// And rather get rid of current code asts instead of growing the pool memory.
|
||||||
void clear_code_pool();
|
void clear_code_pool();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Used internally to retrive or make string allocations.
|
||||||
|
Strings are stored in a series of string arenas of fixed size (SizePer_StringArena)
|
||||||
|
*/
|
||||||
|
ro_string cached_string( char const* cstr, s32 length );
|
||||||
|
|
||||||
|
/*
|
||||||
|
This provides a fresh Code AST struct.
|
||||||
|
The gen interface use this as their method from getting a new AST object from the CodePool.
|
||||||
|
Use this if you want to make your own API for formatting the supported Code Types.
|
||||||
|
*/
|
||||||
|
Code make_code();
|
||||||
|
|
||||||
// Set these before calling gen's init() procedure.
|
// Set these before calling gen's init() procedure.
|
||||||
|
|
||||||
void set_init_reserve_code_pool ( sw size );
|
void set_init_reserve_code_pool ( sw size );
|
||||||
@ -632,6 +738,7 @@ namespace gen
|
|||||||
Code def_class ( s32 length, char const* name, Code parent = NoCode, Code specifiers = NoCode, Code body = NoCode );
|
Code def_class ( s32 length, char const* name, Code parent = NoCode, Code specifiers = NoCode, Code body = NoCode );
|
||||||
Code def_enum ( char const* name, Code type = NoCode, Code body = NoCode);
|
Code def_enum ( char const* name, Code type = NoCode, Code body = NoCode);
|
||||||
Code def_enum ( s32 length, char const* name, Code type = NoCode, Code body = NoCode );
|
Code def_enum ( s32 length, char const* name, Code type = NoCode, Code body = NoCode );
|
||||||
|
Code def_friend ( Code symbol );
|
||||||
Code def_function ( char const* name, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode, Code body = NoCode );
|
Code def_function ( char const* name, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode, Code body = NoCode );
|
||||||
Code def_function ( s32 length, char const* name, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode, Code body = NoCode );
|
Code def_function ( s32 length, char const* name, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode, Code body = NoCode );
|
||||||
Code def_namespace ( char const* name, Code body );
|
Code def_namespace ( char const* name, Code body );
|
||||||
@ -695,6 +802,7 @@ namespace gen
|
|||||||
# pragma region Parsing
|
# pragma region Parsing
|
||||||
Code parse_class ( s32 length, char const* class_def );
|
Code parse_class ( s32 length, char const* class_def );
|
||||||
Code parse_enum ( s32 length, char const* enum_def );
|
Code parse_enum ( s32 length, char const* enum_def );
|
||||||
|
Code parse_friend ( s32 length, char const* friend_def );
|
||||||
Code parse_function ( s32 length, char const* fn_def );
|
Code parse_function ( s32 length, char const* fn_def );
|
||||||
Code parse_global_body( s32 length, char const* body_def );
|
Code parse_global_body( s32 length, char const* body_def );
|
||||||
Code parse_namespace ( s32 length, char const* namespace_def );
|
Code parse_namespace ( s32 length, char const* namespace_def );
|
||||||
@ -705,8 +813,9 @@ namespace gen
|
|||||||
Code parse_typedef ( s32 length, char const* typedef_def );
|
Code parse_typedef ( s32 length, char const* typedef_def );
|
||||||
Code parse_using ( s32 length, char const* using_def );
|
Code parse_using ( s32 length, char const* using_def );
|
||||||
|
|
||||||
s32 parse_classes ( s32 length, char const* class_defs, Code* out_classes );
|
s32 parse_classes ( s32 length, char const* class_defs, Code* out_class_codes );
|
||||||
s32 parse_enums ( s32 length, char const* enum_defs, Code* out_enums );
|
s32 parse_enums ( s32 length, char const* enum_defs, Code* out_enum_codes );
|
||||||
|
s32 parse_friends ( s32 length, char const* friend_defs, Code* out_friend_codes );
|
||||||
s32 parse_functions ( s32 length, char const* fn_defs, Code* out_fn_codes );
|
s32 parse_functions ( s32 length, char const* fn_defs, Code* out_fn_codes );
|
||||||
s32 parse_namespaces( s32 length, char const* namespace_defs, Code* out_namespaces_codes );
|
s32 parse_namespaces( s32 length, char const* namespace_defs, Code* out_namespaces_codes );
|
||||||
s32 parse_operators ( s32 length, char const* operator_defs, Code* out_operator_codes );
|
s32 parse_operators ( s32 length, char const* operator_defs, Code* out_operator_codes );
|
||||||
@ -740,24 +849,9 @@ namespace gen
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AddPolicy
|
|
||||||
{
|
|
||||||
// Not sure yet
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ReplacePolicy
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RemovePolicy
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SymbolInfo
|
struct SymbolInfo
|
||||||
{
|
{
|
||||||
char const* File;
|
ro_string File;
|
||||||
Code Signature;
|
Code Signature;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -770,27 +864,75 @@ namespace gen
|
|||||||
Remove
|
Remove
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RequestEntry
|
struct SymbolData
|
||||||
{
|
{
|
||||||
RequestType Type;
|
|
||||||
SymbolInfo Info;
|
|
||||||
Policy Policy;
|
Policy Policy;
|
||||||
|
SymbolInfo Info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RequestEntry
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
SymbolData Symbol;
|
||||||
|
string Specification;
|
||||||
|
};
|
||||||
|
RequestType Type;
|
||||||
|
};
|
||||||
|
|
||||||
zpl_file File;
|
struct Receipt
|
||||||
|
{
|
||||||
|
ro_string File;
|
||||||
|
Code Found;
|
||||||
|
Code Written;
|
||||||
|
bool Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
static allocator Allocator;
|
||||||
|
|
||||||
|
static void set_allocator( allocator mem_allocator );
|
||||||
|
|
||||||
|
array(zpl_file) Files;
|
||||||
string Buffer;
|
string Buffer;
|
||||||
array(RequestEntry) Requestss ;
|
array(RequestEntry) Requests;
|
||||||
|
|
||||||
void add( SymbolInfo definition, AddPolicy policy, Code to_inject );
|
void add ( SymbolInfo definition, Policy policy, Code to_inject );
|
||||||
|
void replace( SymbolInfo definition, Policy policy, Code to_replace);
|
||||||
void replace( SymbolInfo definiton, ReplacePolicy policy, Code to_replace);
|
void remove ( SymbolInfo definition, Policy policy, Code to_remove );
|
||||||
|
|
||||||
void remove( SymbolInfo definition, RemovePolicy policy, Code to_remove );
|
|
||||||
|
|
||||||
# ifdef GEN_USE_REFACTOR_LIBRARY
|
# ifdef GEN_USE_REFACTOR_LIBRARY
|
||||||
void refactor( char const* specification );
|
void refactor( char const* specification );
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
bool process_requests( array(Receipt) out_receipts );
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GEN_FEATURE_SCANNER
|
||||||
|
struct Scanner
|
||||||
|
{
|
||||||
|
struct RequestEntry
|
||||||
|
{
|
||||||
|
SymbolInfo Info;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Receipt
|
||||||
|
{
|
||||||
|
ro_string File;
|
||||||
|
Code Defintion;
|
||||||
|
bool Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
allocator Allocator;
|
||||||
|
|
||||||
|
static void set_allocator( allocator mem_allocator );
|
||||||
|
|
||||||
|
array(zpl_file) Files;
|
||||||
|
string Buffer;
|
||||||
|
array(RequestEntry) Requests;
|
||||||
|
|
||||||
|
void add( SymbolInfo signature, Policy policy );
|
||||||
|
|
||||||
|
bool process_requests( array(Receipt) out_receipts );
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#pragma endregion Gen Interface
|
#pragma endregion Gen Interface
|
||||||
|
Loading…
Reference in New Issue
Block a user