mirror of
https://github.com/Ed94/gencpp.git
synced 2025-02-24 06:08:37 -08:00
changes based off of metadesk genc_c11
This commit is contained in:
parent
878bc4c8ae
commit
75b1d42cca
@ -38,13 +38,13 @@ void body_to_strbuilder_export( CodeBody body, StrBuilder* result )
|
|||||||
GEN_ASSERT(result != nullptr);
|
GEN_ASSERT(result != nullptr);
|
||||||
strbuilder_append_fmt( result, "export\n{\n" );
|
strbuilder_append_fmt( result, "export\n{\n" );
|
||||||
|
|
||||||
Code curr = cast(Code, body);
|
Code curr = body->Front;
|
||||||
s32 left = body->NumEntries;
|
s32 left = body->NumEntries;
|
||||||
while ( left-- )
|
while ( left-- )
|
||||||
{
|
{
|
||||||
code_to_strbuilder_ref(curr, result);
|
code_to_strbuilder_ref(curr, result);
|
||||||
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
|
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
|
||||||
++curr;
|
curr = curr->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuilder_append_fmt( result, "};\n" );
|
strbuilder_append_fmt( result, "};\n" );
|
||||||
|
@ -38,7 +38,7 @@ void body_to_strbuilder_ref( CodeBody body, StrBuilder* result )
|
|||||||
{
|
{
|
||||||
code_to_strbuilder_ref(curr, result);
|
code_to_strbuilder_ref(curr, result);
|
||||||
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
|
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
|
||||||
++curr;
|
curr = curr->Next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,6 +283,15 @@ void init(Context* ctx)
|
|||||||
ctx->InitSize_Fallback_Allocator_Bucket_Size = megabytes(8);
|
ctx->InitSize_Fallback_Allocator_Bucket_Size = megabytes(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->InitSize_StrCacheTable == 0)
|
||||||
|
{
|
||||||
|
ctx->InitSize_StrCacheTable = kilobytes(8);
|
||||||
|
}
|
||||||
|
if (ctx->InitSize_MacrosTable == 0)
|
||||||
|
{
|
||||||
|
ctx->InitSize_MacrosTable = kilobytes(8);
|
||||||
|
}
|
||||||
|
|
||||||
// Override the current context (user has to put it back if unwanted).
|
// Override the current context (user has to put it back if unwanted).
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
|
|
||||||
@ -311,11 +320,11 @@ void init(Context* ctx)
|
|||||||
}
|
}
|
||||||
// Setup the hash tables
|
// Setup the hash tables
|
||||||
{
|
{
|
||||||
ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers);
|
ctx->StrCache = hashtable_init_reserve(StrCached, ctx->Allocator_DyanmicContainers, ctx->InitSize_StrCacheTable);
|
||||||
if ( ctx->StrCache.Entries == nullptr )
|
if ( ctx->StrCache.Entries == nullptr )
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
|
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
|
||||||
|
|
||||||
ctx->Macros = hashtable_init(Macro, ctx->Allocator_DyanmicContainers);
|
ctx->Macros = hashtable_init_reserve(Macro, ctx->Allocator_DyanmicContainers, ctx->InitSize_MacrosTable);
|
||||||
if (ctx->Macros.Hashes == nullptr || ctx->Macros.Entries == nullptr) {
|
if (ctx->Macros.Hashes == nullptr || ctx->Macros.Entries == nullptr) {
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the PreprocessMacros table" );
|
GEN_FATAL( "gen::init: Failed to initialize the PreprocessMacros table" );
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,9 @@ struct Context
|
|||||||
u32 InitSize_LexerTokens;
|
u32 InitSize_LexerTokens;
|
||||||
u32 SizePer_StringArena;
|
u32 SizePer_StringArena;
|
||||||
|
|
||||||
|
u32 InitSize_StrCacheTable;
|
||||||
|
u32 InitSize_MacrosTable;
|
||||||
|
|
||||||
// TODO(Ed): Symbol Table
|
// TODO(Ed): Symbol Table
|
||||||
// Keep track of all resolved symbols (naemspaced identifiers)
|
// Keep track of all resolved symbols (naemspaced identifiers)
|
||||||
|
|
||||||
|
@ -1443,6 +1443,22 @@ CodeFn parse_function_after_name(
|
|||||||
}
|
}
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>
|
||||||
|
|
||||||
|
// Check for trailing specifiers...
|
||||||
|
CodeAttributes post_rt_attributes = parse_attributes();
|
||||||
|
if (post_rt_attributes)
|
||||||
|
{
|
||||||
|
if (attributes)
|
||||||
|
{
|
||||||
|
StrBuilder merged = strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S %S", attributes->Content, post_rt_attributes->Content);
|
||||||
|
attributes->Content = cache_str(strbuilder_to_str(merged));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attributes = post_rt_attributes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> <Attributes>
|
||||||
|
|
||||||
CodeBody body = NullCode;
|
CodeBody body = NullCode;
|
||||||
CodeComment inline_cmt = NullCode;
|
CodeComment inline_cmt = NullCode;
|
||||||
if ( check( Tok_BraceCurly_Open ) )
|
if ( check( Tok_BraceCurly_Open ) )
|
||||||
@ -1481,17 +1497,19 @@ CodeFn parse_function_after_name(
|
|||||||
|
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment();
|
inline_cmt = parse_comment();
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>; <InlineCmt>
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> < = 0 or delete > ; <InlineCmt>
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
|
||||||
|
if (body == nullptr)
|
||||||
{
|
{
|
||||||
Token stmt_end = currtok;
|
Token stmt_end = currtok;
|
||||||
eat( Tok_Statement_End );
|
eat( Tok_Statement_End );
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>;
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> <Attributes> < = 0 or delete > ;
|
||||||
|
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment();
|
inline_cmt = parse_comment();
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>; <InlineCmt>
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> < = 0 or delete > ; <InlineCmt>
|
||||||
}
|
}
|
||||||
|
|
||||||
StrBuilder
|
StrBuilder
|
||||||
@ -1766,7 +1784,7 @@ CodeBody parse_global_nspace( CodeType which )
|
|||||||
|
|
||||||
case Tok_Preprocess_Macro_Expr:
|
case Tok_Preprocess_Macro_Expr:
|
||||||
{
|
{
|
||||||
if (tok_is_attribute(currtok))
|
if ( ! tok_is_attribute(currtok))
|
||||||
{
|
{
|
||||||
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
|
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -2049,11 +2067,20 @@ Token parse_identifier( bool* possible_member_function )
|
|||||||
|
|
||||||
Macro* macro = lookup_macro(currtok.Text);
|
Macro* macro = lookup_macro(currtok.Text);
|
||||||
b32 accept_as_identifier = macro && bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Identifier );
|
b32 accept_as_identifier = macro && bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Identifier );
|
||||||
|
b32 is_decarator = macro && bitfield_is_set(MacroFlags, macro->Flags, MF_Identifier_Decorator );
|
||||||
|
|
||||||
// Typename can be: '::' <name>
|
// Typename can be: '::' <name>
|
||||||
// If that is the case first option will be Tok_Access_StaticSymbol below
|
// If that is the case first option will be Tok_Access_StaticSymbol below
|
||||||
if (check(Tok_Identifier) || accept_as_identifier)
|
if (check(Tok_Identifier) || accept_as_identifier)
|
||||||
eat( Tok_Identifier );
|
{
|
||||||
|
if (is_decarator) {
|
||||||
|
Code name_macro = parse_simple_preprocess(currtok.Type);
|
||||||
|
name.Text.Len = ( ( sptr )prevtok.Text.Ptr + prevtok.Text.Len ) - ( sptr )name.Text.Ptr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eat(Tok_Identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
// <Name>
|
// <Name>
|
||||||
|
|
||||||
parse_template_args( & name );
|
parse_template_args( & name );
|
||||||
@ -4714,21 +4741,37 @@ CodeTypename parser_parse_type( bool from_template, bool* typedef_is_function )
|
|||||||
else if ( currtok.Type == Tok_Decl_Class || currtok.Type == Tok_Decl_Enum || currtok.Type == Tok_Decl_Struct
|
else if ( currtok.Type == Tok_Decl_Class || currtok.Type == Tok_Decl_Enum || currtok.Type == Tok_Decl_Struct
|
||||||
|| currtok.Type == Tok_Decl_Union )
|
|| currtok.Type == Tok_Decl_Union )
|
||||||
{
|
{
|
||||||
switch (currtok.Type) {
|
Token next = nexttok;
|
||||||
case Tok_Decl_Class : tag = Tag_Class; break;
|
|
||||||
case Tok_Decl_Enum : tag = Tag_Enum; break;
|
if (next.Type == Tok_Identifier)
|
||||||
case Tok_Decl_Struct : tag = Tag_Struct; break;
|
{
|
||||||
case Tok_Decl_Union : tag = Tag_Union; break;
|
switch (currtok.Type) {
|
||||||
default:
|
case Tok_Decl_Class : tag = Tag_Class; break;
|
||||||
break;
|
case Tok_Decl_Enum : tag = Tag_Enum; break;
|
||||||
|
case Tok_Decl_Struct : tag = Tag_Struct; break;
|
||||||
|
case Tok_Decl_Union : tag = Tag_Union; break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
eat( currtok.Type );
|
||||||
|
// <Attributes> <Specifiers> <class, enum, struct, union>
|
||||||
|
|
||||||
|
name = parse_identifier(nullptr);
|
||||||
|
// <Attributes> <Specifiers> <class, enum, struct, union> <Name>
|
||||||
}
|
}
|
||||||
eat( currtok.Type );
|
else if (next.Type == Tok_BraceCurly_Open)
|
||||||
// <Attributes> <Specifiers> <class, enum, struct, union>
|
{
|
||||||
|
name = currtok;
|
||||||
|
// We have an inplace definition, we need to consume that...
|
||||||
|
|
||||||
name = parse_identifier(nullptr);
|
// TODO(Ed): we need to add a way for AST_CodeTypename to track an implace definition..
|
||||||
|
b32 const inplace = true;
|
||||||
|
Code indplace_def = cast(Code, parser_parse_struct(inplace));
|
||||||
|
|
||||||
// name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text;
|
// For now we lose the structural information,
|
||||||
// eat( Tok_Identifier );
|
name.Text.Len = ( ( sptr )prevtok.Text.Ptr + prevtok.Text.Len ) - ( sptr )name.Text.Ptr;
|
||||||
|
// <Attributes> <Specifiers> <class, enum, struct, union> <inplace def>
|
||||||
|
}
|
||||||
_ctx->parser.Scope->Name = name.Text;
|
_ctx->parser.Scope->Name = name.Text;
|
||||||
// <Attributes> <Specifiers> <class, enum, struct, union> <Name>
|
// <Attributes> <Specifiers> <class, enum, struct, union> <Name>
|
||||||
}
|
}
|
||||||
|
@ -168,26 +168,36 @@ Str macrotype_to_str( MacroType type )
|
|||||||
|
|
||||||
enum EMacroFlags : u16
|
enum EMacroFlags : u16
|
||||||
{
|
{
|
||||||
MF_Functional = bit(0), // Macro has parameters (args expected to be passed)
|
// Macro has parameters (args expected to be passed)
|
||||||
MF_Expects_Body = bit(1), // Expects to assign a braced scope to its body.
|
MF_Functional = bit(0),
|
||||||
|
|
||||||
|
// Expects to assign a braced scope to its body.
|
||||||
|
MF_Expects_Body = bit(1),
|
||||||
|
|
||||||
// lex__eat wil treat this macro as an identifier if the parser attempts to consume it as one.
|
// lex__eat wil treat this macro as an identifier if the parser attempts to consume it as one.
|
||||||
// ^^^ This is a kludge because we don't support push/pop macro pragmas rn.
|
// This is a kludge because we don't support push/pop macro pragmas rn.
|
||||||
MF_Allow_As_Identifier = bit(2),
|
MF_Allow_As_Identifier = bit(2),
|
||||||
|
|
||||||
|
// When parsing identifiers, it will allow the consumption of the macro parameters (as its expected to be a part of constructing the identifier)
|
||||||
|
// Example of a decarator macro from stb_sprintf.h:
|
||||||
|
// STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(sprintf)(char* buf, char const *fmt, ...) STBSP__ATTRIBUTE_FORMAT(2,3);
|
||||||
|
// ^^ STB_SPRINTF_DECORATE is decorating sprintf
|
||||||
|
MF_Identifier_Decorator = bit(3),
|
||||||
|
|
||||||
// lex__eat wil treat this macro as an attribute if the parser attempts to consume it as one.
|
// lex__eat wil treat this macro as an attribute if the parser attempts to consume it as one.
|
||||||
// ^^^ This a kludge because unreal has a macro that behaves as both a 'statement' and an attribute (UE_DEPRECATED, PRAGMA_ENABLE_DEPRECATION_WARNINGS, etc)
|
// This a kludge because unreal has a macro that behaves as both a 'statement' and an attribute (UE_DEPRECATED, PRAGMA_ENABLE_DEPRECATION_WARNINGS, etc)
|
||||||
// TODO(Ed): We can keep the MF_Allow_As_Attribute flag for macros, however, we need to add the ability of AST_Attributes to chain themselves.
|
// TODO(Ed): We can keep the MF_Allow_As_Attribute flag for macros, however, we need to add the ability of AST_Attributes to chain themselves.
|
||||||
// Its thats already a thing in the standard language anyway
|
// Its thats already a thing in the standard language anyway
|
||||||
// & it would allow UE_DEPRECATED, (UE_PROPERTY / UE_FUNCTION) to chain themselves as attributes of a resolved member function/variable definition
|
// & it would allow UE_DEPRECATED, (UE_PROPERTY / UE_FUNCTION) to chain themselves as attributes of a resolved member function/variable definition
|
||||||
MF_Allow_As_Attribute = bit(3),
|
MF_Allow_As_Attribute = bit(4),
|
||||||
|
|
||||||
// When a macro is encountered after attributes and specifiers while parsing a function, or variable:
|
// When a macro is encountered after attributes and specifiers while parsing a function, or variable:
|
||||||
// It will consume the macro and treat it as resolving the definition. (Yes this is for Unreal Engine)
|
// It will consume the macro and treat it as resolving the definition.
|
||||||
// (MUST BE OF MT_Statement TYPE)
|
// (MUST BE OF MT_Statement TYPE)
|
||||||
MF_Allow_As_Definition = bit(4),
|
MF_Allow_As_Definition = bit(5),
|
||||||
|
|
||||||
MF_Allow_As_Specifier = bit(5), // Created for Unreal's PURE_VIRTUAL
|
// Created for Unreal's PURE_VIRTUAL
|
||||||
|
MF_Allow_As_Specifier = bit(6),
|
||||||
|
|
||||||
MF_Null = 0,
|
MF_Null = 0,
|
||||||
MF_UnderlyingType = GEN_U16_MAX,
|
MF_UnderlyingType = GEN_U16_MAX,
|
||||||
|
@ -198,21 +198,16 @@
|
|||||||
#ifndef forceinline
|
#ifndef forceinline
|
||||||
# if GEN_COMPILER_MSVC
|
# if GEN_COMPILER_MSVC
|
||||||
# define forceinline __forceinline
|
# define forceinline __forceinline
|
||||||
# define neverinline __declspec( noinline )
|
|
||||||
# elif GEN_COMPILER_GCC
|
# elif GEN_COMPILER_GCC
|
||||||
# define forceinline inline __attribute__((__always_inline__))
|
# define forceinline inline __attribute__((__always_inline__))
|
||||||
# define neverinline __attribute__( ( __noinline__ ) )
|
|
||||||
# elif GEN_COMPILER_CLANG
|
# elif GEN_COMPILER_CLANG
|
||||||
# if __has_attribute(__always_inline__)
|
# if __has_attribute(__always_inline__)
|
||||||
# define forceinline inline __attribute__((__always_inline__))
|
# define forceinline inline __attribute__((__always_inline__))
|
||||||
# define neverinline __attribute__( ( __noinline__ ) )
|
|
||||||
# else
|
# else
|
||||||
# define forceinline
|
# define forceinline
|
||||||
# define neverinline
|
|
||||||
# endif
|
# endif
|
||||||
# else
|
# else
|
||||||
# define forceinline
|
# define forceinline
|
||||||
# define neverinline
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocato
|
|||||||
#define malloc( sz ) alloc( heap(), sz )
|
#define malloc( sz ) alloc( heap(), sz )
|
||||||
|
|
||||||
//! Helper to free memory allocated by heap allocator.
|
//! Helper to free memory allocated by heap allocator.
|
||||||
#define mfree( ptr ) free( heap(), ptr )
|
#define mfree( ptr ) allocator_free( heap(), ptr )
|
||||||
|
|
||||||
struct VirtualMemory
|
struct VirtualMemory
|
||||||
{
|
{
|
||||||
|
@ -53,6 +53,7 @@ word enum_underlying, gen_enum_underlying
|
|||||||
word nullptr, gen_nullptr
|
word nullptr, gen_nullptr
|
||||||
word struct_init, gen_struct_init
|
word struct_init, gen_struct_init
|
||||||
word hash, gen_hash
|
word hash, gen_hash
|
||||||
|
word txt, gen_txt
|
||||||
|
|
||||||
// Basic Types
|
// Basic Types
|
||||||
|
|
||||||
@ -410,6 +411,8 @@ namespace var_, gen_var_
|
|||||||
|
|
||||||
word _ctx, gen__ctx
|
word _ctx, gen__ctx
|
||||||
|
|
||||||
|
word get_context, gen_get_context
|
||||||
|
|
||||||
word init, gen_init
|
word init, gen_init
|
||||||
word deinit, gen_deinit
|
word deinit, gen_deinit
|
||||||
word reset, gen_reset
|
word reset, gen_reset
|
||||||
|
@ -404,7 +404,7 @@ if ( $vendor -match "msvc" )
|
|||||||
$flag_optimize_intrinsics = '/Oi'
|
$flag_optimize_intrinsics = '/Oi'
|
||||||
$flag_optimized_debug_forceinline = '/d2Obforceinline'
|
$flag_optimized_debug_forceinline = '/d2Obforceinline'
|
||||||
$flag_optimized_debug = '/Zo'
|
$flag_optimized_debug = '/Zo'
|
||||||
$flag_
|
# $flag_
|
||||||
# $flag_out_name = '/OUT:'
|
# $flag_out_name = '/OUT:'
|
||||||
$flag_path_interm = '/Fo'
|
$flag_path_interm = '/Fo'
|
||||||
$flag_path_debug = '/Fd'
|
$flag_path_debug = '/Fd'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user