mirror of
https://github.com/Ed94/gencpp.git
synced 2025-02-24 06:08:37 -08:00
723 lines
17 KiB
C++
723 lines
17 KiB
C++
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
|
#pragma once
|
|
#include "interface.hpp"
|
|
#endif
|
|
|
|
#pragma region Serialization
|
|
inline
|
|
StrBuilder attributes_to_strbuilder(CodeAttributes attributes) {
|
|
GEN_ASSERT(attributes);
|
|
char* raw = ccast(char*, str_duplicate( attributes->Content, get_context()->Allocator_Temp ).Ptr);
|
|
StrBuilder result = { raw };
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
void attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result) {
|
|
GEN_ASSERT(attributes);
|
|
GEN_ASSERT(result);
|
|
strbuilder_append_str(result, attributes->Content);
|
|
}
|
|
|
|
inline
|
|
StrBuilder comment_to_strbuilder(CodeComment comment) {
|
|
GEN_ASSERT(comment);
|
|
char* raw = ccast(char*, str_duplicate( comment->Content, get_context()->Allocator_Temp ).Ptr);
|
|
StrBuilder result = { raw };
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
void body_to_strbuilder_ref( CodeBody body, StrBuilder* result )
|
|
{
|
|
GEN_ASSERT(body != nullptr);
|
|
GEN_ASSERT(result != nullptr);
|
|
Code curr = body->Front;
|
|
s32 left = body->NumEntries;
|
|
while ( left -- )
|
|
{
|
|
code_to_strbuilder_ptr(curr, result);
|
|
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
|
|
++curr;
|
|
}
|
|
}
|
|
|
|
inline
|
|
void comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result) {
|
|
GEN_ASSERT(comment);
|
|
GEN_ASSERT(result);
|
|
strbuilder_append_str(result, comment->Content);
|
|
}
|
|
|
|
inline
|
|
StrBuilder define_to_strbuilder(CodeDefine define)
|
|
{
|
|
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
|
|
define_to_strbuilder_ref(define, & result);
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
StrBuilder define_params_to_strbuilder(CodeDefineParams params)
|
|
{
|
|
GEN_ASSERT(params);
|
|
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
|
|
define_params_to_strbuilder_ref( params, & result );
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
StrBuilder exec_to_strbuilder(CodeExec exec)
|
|
{
|
|
GEN_ASSERT(exec);
|
|
char* raw = ccast(char*, str_duplicate( exec->Content, _ctx->Allocator_Temp ).Ptr);
|
|
StrBuilder result = { raw };
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
void extern_to_strbuilder(CodeExtern self, StrBuilder* result )
|
|
{
|
|
if ( self->Body )
|
|
strbuilder_append_fmt( result, "extern \"%S\"\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
|
|
else
|
|
strbuilder_append_fmt( result, "extern \"%S\"\n{}\n", self->Name );
|
|
}
|
|
|
|
inline
|
|
StrBuilder include_to_strbuilder(CodeInclude include)
|
|
{
|
|
return strbuilder_fmt_buf( _ctx->Allocator_Temp, "#include %S\n", include->Content );
|
|
}
|
|
|
|
inline
|
|
void include_to_strbuilder_ref( CodeInclude include, StrBuilder* result )
|
|
{
|
|
strbuilder_append_fmt( result, "#include %S\n", include->Content );
|
|
}
|
|
|
|
inline
|
|
StrBuilder friend_to_strbuilder(CodeFriend self)
|
|
{
|
|
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
|
|
friend_to_strbuilder_ref( self, & result );
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
void friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result )
|
|
{
|
|
strbuilder_append_fmt( result, "friend %SB", code_to_strbuilder(self->Declaration) );
|
|
|
|
if ( self->Declaration->Type != CT_Function && self->Declaration->Type != CT_Operator && (* result)[ strbuilder_length(* result) - 1 ] != ';' )
|
|
{
|
|
strbuilder_append_str( result, txt(";") );
|
|
}
|
|
|
|
if ( self->InlineCmt )
|
|
strbuilder_append_fmt( result, " %S", self->InlineCmt->Content );
|
|
else
|
|
strbuilder_append_str( result, txt("\n"));
|
|
}
|
|
|
|
inline
|
|
StrBuilder module_to_strbuilder(CodeModule self)
|
|
{
|
|
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
|
|
module_to_strbuilder_ref( self, & result );
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
StrBuilder namespace_to_strbuilder(CodeNS self)
|
|
{
|
|
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
|
|
namespace_to_strbuilder_ref( self, & result );
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result )
|
|
{
|
|
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
|
strbuilder_append_str( result, txt("export ") );
|
|
|
|
strbuilder_append_fmt( result, "namespace %S\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
|
|
}
|
|
|
|
inline
|
|
StrBuilder params_to_strbuilder(CodeParams self)
|
|
{
|
|
GEN_ASSERT(self);
|
|
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
|
|
params_to_strbuilder_ref( self, & result );
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
void preprocess_to_strbuilder_if(CodePreprocessCond cond, StrBuilder* result )
|
|
{
|
|
GEN_ASSERT(cond);
|
|
strbuilder_append_fmt( result, "#if %S", cond->Content );
|
|
}
|
|
|
|
inline
|
|
void preprocess_to_strbuilder_ifdef(CodePreprocessCond cond, StrBuilder* result )
|
|
{
|
|
GEN_ASSERT(cond);
|
|
strbuilder_append_fmt( result, "#ifdef %S\n", cond->Content );
|
|
}
|
|
|
|
inline
|
|
void preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result )
|
|
{
|
|
GEN_ASSERT(cond);
|
|
strbuilder_append_fmt( result, "#ifndef %S", cond->Content );
|
|
}
|
|
|
|
inline
|
|
void preprocess_to_strbuilder_elif(CodePreprocessCond cond, StrBuilder* result )
|
|
{
|
|
GEN_ASSERT(cond);
|
|
strbuilder_append_fmt( result, "#elif %S\n", cond->Content );
|
|
}
|
|
|
|
inline
|
|
void preprocess_to_strbuilder_else(CodePreprocessCond cond, StrBuilder* result )
|
|
{
|
|
GEN_ASSERT(cond);
|
|
strbuilder_append_str( result, txt("#else\n") );
|
|
}
|
|
|
|
inline
|
|
void preprocess_to_strbuilder_endif(CodePreprocessCond cond, StrBuilder* result )
|
|
{
|
|
GEN_ASSERT(cond);
|
|
strbuilder_append_str( result, txt("#endif\n") );
|
|
}
|
|
|
|
inline
|
|
StrBuilder pragma_to_strbuilder(CodePragma self)
|
|
{
|
|
GEN_ASSERT(self);
|
|
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
|
|
pragma_to_strbuilder_ref( self, & result );
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
void pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result )
|
|
{
|
|
strbuilder_append_fmt( result, "#pragma %S\n", self->Content );
|
|
}
|
|
|
|
inline
|
|
StrBuilder specifiers_to_strbuilder(CodeSpecifiers self)
|
|
{
|
|
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
|
|
specifiers_to_strbuilder_ref( self, & result );
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
StrBuilder template_to_strbuilder(CodeTemplate self)
|
|
{
|
|
GEN_ASSERT(self);
|
|
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 1024 );
|
|
template_to_strbuilder_ref( self, & result );
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
StrBuilder typedef_to_strbuilder(CodeTypedef self)
|
|
{
|
|
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
|
|
typedef_to_strbuilder_ref( self, & result );
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
StrBuilder typename_to_strbuilder(CodeTypename self)
|
|
{
|
|
StrBuilder result = strbuilder_make_str( _ctx->Allocator_Temp, txt("") );
|
|
typename_to_strbuilder_ref( self, & result );
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
StrBuilder using_to_strbuilder(CodeUsing self)
|
|
{
|
|
GEN_ASSERT(self);
|
|
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
|
|
switch ( self->Type )
|
|
{
|
|
case CT_Using:
|
|
using_to_strbuilder_ref( self, & result );
|
|
break;
|
|
case CT_Using_Namespace:
|
|
using_to_strbuilder_ns( self, & result );
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
inline
|
|
void using_to_strbuilder_ns(CodeUsing self, StrBuilder* result )
|
|
{
|
|
GEN_ASSERT(self);
|
|
GEN_ASSERT(result);
|
|
if ( self->InlineCmt )
|
|
strbuilder_append_fmt( result, "using namespace $S; %S", self->Name, self->InlineCmt->Content );
|
|
else
|
|
strbuilder_append_fmt( result, "using namespace %S;\n", self->Name );
|
|
}
|
|
|
|
inline
|
|
StrBuilder var_to_strbuilder(CodeVar self)
|
|
{
|
|
GEN_ASSERT(self);
|
|
StrBuilder result = strbuilder_make_reserve( get_context()->Allocator_Temp, 256 );
|
|
var_to_strbuilder_ref( self, & result );
|
|
return result;
|
|
}
|
|
#pragma endregion Serialization
|
|
|
|
#pragma region Code
|
|
inline
|
|
void code_append( Code self, Code other )
|
|
{
|
|
GEN_ASSERT(self);
|
|
GEN_ASSERT(other);
|
|
GEN_ASSERT_MSG(self != other, "Attempted to recursively append Code AST to itself.");
|
|
|
|
if ( other->Parent != nullptr )
|
|
other = code_duplicate(other);
|
|
|
|
other->Parent = self;
|
|
|
|
if ( self->Front == nullptr )
|
|
{
|
|
self->Front = other;
|
|
self->Back = other;
|
|
|
|
self->NumEntries++;
|
|
return;
|
|
}
|
|
|
|
Code
|
|
Current = self->Back;
|
|
Current->Next = other;
|
|
other->Prev = Current;
|
|
self->Back = other;
|
|
self->NumEntries++;
|
|
}
|
|
inline
|
|
bool code_is_body(Code self)
|
|
{
|
|
GEN_ASSERT(self);
|
|
switch (self->Type)
|
|
{
|
|
case CT_Enum_Body:
|
|
case CT_Class_Body:
|
|
case CT_Union_Body:
|
|
case CT_Export_Body:
|
|
case CT_Global_Body:
|
|
case CT_Struct_Body:
|
|
case CT_Function_Body:
|
|
case CT_Namespace_Body:
|
|
case CT_Extern_Linkage_Body:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
inline
|
|
Code* code_entry( Code self, u32 idx )
|
|
{
|
|
GEN_ASSERT(self != nullptr);
|
|
Code* current = & self->Front;
|
|
while ( idx >= 0 && current != nullptr )
|
|
{
|
|
if ( idx == 0 )
|
|
return rcast( Code*, current);
|
|
|
|
current = & ( * current )->Next;
|
|
idx--;
|
|
}
|
|
|
|
return rcast( Code*, current);
|
|
}
|
|
forceinline
|
|
bool code_is_valid(Code self)
|
|
{
|
|
GEN_ASSERT(self);
|
|
return self != nullptr && self->Type != CT_Invalid;
|
|
}
|
|
forceinline
|
|
bool code_has_entries(Code self)
|
|
{
|
|
GEN_ASSERT(self);
|
|
return self->NumEntries > 0;
|
|
}
|
|
forceinline
|
|
void code_set_global(Code self)
|
|
{
|
|
if ( self == nullptr )
|
|
{
|
|
log_failure("Code::set_global: Cannot set code as global, AST is null!");
|
|
return;
|
|
}
|
|
|
|
self->Parent = Code_Global;
|
|
}
|
|
#if GEN_COMPILER_CPP
|
|
forceinline
|
|
Code& Code::operator ++()
|
|
{
|
|
if ( ast )
|
|
ast = ast->Next.ast;
|
|
|
|
return * this;
|
|
}
|
|
#endif
|
|
forceinline
|
|
Str code_type_str(Code self)
|
|
{
|
|
GEN_ASSERT(self != nullptr);
|
|
return codetype_to_str( self->Type );
|
|
}
|
|
#pragma endregion Code
|
|
|
|
#pragma region CodeBody
|
|
inline
|
|
void body_append( CodeBody self, Code other )
|
|
{
|
|
GEN_ASSERT(self);
|
|
GEN_ASSERT(other);
|
|
|
|
if (code_is_body(other)) {
|
|
body_append_body( self, cast(CodeBody, other) );
|
|
return;
|
|
}
|
|
|
|
code_append( cast(Code, self), other );
|
|
}
|
|
inline
|
|
void body_append_body( CodeBody self, CodeBody body )
|
|
{
|
|
GEN_ASSERT(self);
|
|
GEN_ASSERT(body);
|
|
GEN_ASSERT_MSG(self != body, "Attempted to append body to itself.");
|
|
|
|
for ( Code entry = begin_CodeBody(body); entry != end_CodeBody(body); entry = next_CodeBody(body, entry) ) {
|
|
body_append( self, entry );
|
|
}
|
|
}
|
|
inline
|
|
Code begin_CodeBody( CodeBody body) {
|
|
GEN_ASSERT(body);
|
|
if ( body != nullptr )
|
|
return body->Front;
|
|
|
|
return NullCode;
|
|
}
|
|
forceinline
|
|
Code end_CodeBody(CodeBody body ){
|
|
GEN_ASSERT(body);
|
|
return body->Back->Next;
|
|
}
|
|
inline
|
|
Code next_CodeBody(CodeBody body, Code entry) {
|
|
GEN_ASSERT(body);
|
|
GEN_ASSERT(entry);
|
|
return entry->Next;
|
|
}
|
|
#pragma endregion CodeBody
|
|
|
|
#pragma region CodeClass
|
|
inline
|
|
void class_add_interface( CodeClass self, CodeTypename type )
|
|
{
|
|
GEN_ASSERT(self);
|
|
GEN_ASSERT(type);
|
|
CodeTypename possible_slot = self->ParentType;
|
|
if ( possible_slot != nullptr )
|
|
{
|
|
// Were adding an interface to parent type, so we need to make sure the parent type is public.
|
|
self->ParentAccess = AccessSpec_Public;
|
|
// If your planning on adding a proper parent,
|
|
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
|
|
}
|
|
|
|
while ( possible_slot->Next != nullptr )
|
|
{
|
|
possible_slot = cast(CodeTypename, possible_slot->Next);
|
|
}
|
|
|
|
possible_slot->Next = type;
|
|
}
|
|
#pragma endregion CodeClass
|
|
|
|
#pragma region CodeParams
|
|
inline
|
|
void params_append( CodeParams appendee, CodeParams other )
|
|
{
|
|
GEN_ASSERT(appendee);
|
|
GEN_ASSERT(other);
|
|
GEN_ASSERT_MSG(appendee != other, "Attempted to append parameter to itself.");
|
|
Code self = cast(Code, appendee);
|
|
Code entry = cast(Code, other);
|
|
|
|
if ( entry->Parent != nullptr )
|
|
entry = code_duplicate( entry );
|
|
|
|
entry->Parent = self;
|
|
|
|
if ( self->Last == nullptr )
|
|
{
|
|
self->Last = entry;
|
|
self->Next = entry;
|
|
self->NumEntries++;
|
|
return;
|
|
}
|
|
|
|
self->Last->Next = entry;
|
|
self->Last = entry;
|
|
self->NumEntries++;
|
|
}
|
|
inline
|
|
CodeParams params_get(CodeParams self, s32 idx )
|
|
{
|
|
GEN_ASSERT(self);
|
|
CodeParams param = self;
|
|
do
|
|
{
|
|
if ( ++ param != nullptr )
|
|
return NullCode;
|
|
|
|
param = cast(CodeParams, cast(Code, param)->Next);
|
|
}
|
|
while ( --idx );
|
|
|
|
return param;
|
|
}
|
|
forceinline
|
|
bool params_has_entries(CodeParams self)
|
|
{
|
|
GEN_ASSERT(self);
|
|
return self->NumEntries > 0;
|
|
}
|
|
#if GEN_COMPILER_CPP
|
|
forceinline
|
|
CodeParams& CodeParams::operator ++()
|
|
{
|
|
* this = ast->Next;
|
|
return * this;
|
|
}
|
|
#endif
|
|
forceinline
|
|
CodeParams begin_CodeParams(CodeParams params)
|
|
{
|
|
if ( params != nullptr )
|
|
return params;
|
|
|
|
return NullCode;
|
|
}
|
|
forceinline
|
|
CodeParams end_CodeParams(CodeParams params)
|
|
{
|
|
// return { (AST_Params*) rcast( AST*, ast)->Last };
|
|
return NullCode;
|
|
}
|
|
forceinline
|
|
CodeParams next_CodeParams(CodeParams params, CodeParams param_iter)
|
|
{
|
|
GEN_ASSERT(param_iter);
|
|
return param_iter->Next;
|
|
}
|
|
#pragma endregion CodeParams
|
|
|
|
#pragma region CodeDefineParams
|
|
forceinline void define_params_append (CodeDefineParams appendee, CodeDefineParams other ) { params_append( cast(CodeParams, appendee), cast(CodeParams, other) ); }
|
|
forceinline CodeDefineParams define_params_get (CodeDefineParams self, s32 idx ) { return (CodeDefineParams) (Code) params_get( cast(CodeParams, self), idx); }
|
|
forceinline bool define_params_has_entries(CodeDefineParams self) { return params_has_entries( cast(CodeParams, self)); }
|
|
|
|
forceinline CodeDefineParams begin_CodeDefineParams(CodeDefineParams params) { return (CodeDefineParams) (Code) begin_CodeParams( cast(CodeParams, (Code)params)); }
|
|
forceinline CodeDefineParams end_CodeDefineParams (CodeDefineParams params) { return (CodeDefineParams) (Code) end_CodeParams ( cast(CodeParams, (Code)params)); }
|
|
forceinline CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter) { return (CodeDefineParams) (Code) next_CodeParams ( cast(CodeParams, (Code)params), cast(CodeParams, (Code)entry_iter)); }
|
|
|
|
#if GEN_COMPILER_CPP
|
|
forceinline
|
|
CodeDefineParams& CodeDefineParams::operator ++()
|
|
{
|
|
* this = ast->Next;
|
|
return * this;
|
|
}
|
|
#endif
|
|
#pragma endregion CodeDefineParams
|
|
|
|
#pragma region CodeSpecifiers
|
|
inline
|
|
bool specifiers_append(CodeSpecifiers self, Specifier spec )
|
|
{
|
|
if ( self == nullptr )
|
|
{
|
|
log_failure("CodeSpecifiers: Attempted to append to a null specifiers AST!");
|
|
return false;
|
|
}
|
|
if ( self->NumEntries == AST_ArrSpecs_Cap )
|
|
{
|
|
log_failure("CodeSpecifiers: Attempted to append over %d specifiers to a specifiers AST!", AST_ArrSpecs_Cap );
|
|
return false;
|
|
}
|
|
|
|
self->ArrSpecs[ self->NumEntries ] = spec;
|
|
self->NumEntries++;
|
|
return true;
|
|
}
|
|
inline
|
|
bool specifiers_has(CodeSpecifiers self, Specifier spec)
|
|
{
|
|
GEN_ASSERT(self != nullptr);
|
|
for ( s32 idx = 0; idx < self->NumEntries; idx++ ) {
|
|
if ( self->ArrSpecs[ idx ] == spec )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
inline
|
|
s32 specifiers_index_of(CodeSpecifiers self, Specifier spec)
|
|
{
|
|
GEN_ASSERT(self != nullptr);
|
|
for ( s32 idx = 0; idx < self->NumEntries; idx++ ) {
|
|
if ( self->ArrSpecs[ idx ] == spec )
|
|
return idx;
|
|
}
|
|
return -1;
|
|
}
|
|
inline
|
|
s32 specifiers_remove( CodeSpecifiers self, Specifier to_remove )
|
|
{
|
|
if ( self == nullptr )
|
|
{
|
|
log_failure("CodeSpecifiers: Attempted to append to a null specifiers AST!");
|
|
return -1;
|
|
}
|
|
if ( self->NumEntries == AST_ArrSpecs_Cap )
|
|
{
|
|
log_failure("CodeSpecifiers: Attempted to append over %d specifiers to a specifiers AST!", AST_ArrSpecs_Cap );
|
|
return -1;
|
|
}
|
|
|
|
s32 result = -1;
|
|
|
|
s32 curr = 0;
|
|
s32 next = 0;
|
|
for(; next < self->NumEntries; ++ curr, ++ next)
|
|
{
|
|
Specifier spec = self->ArrSpecs[next];
|
|
if (spec == to_remove)
|
|
{
|
|
result = next;
|
|
|
|
next ++;
|
|
if (next >= self->NumEntries)
|
|
break;
|
|
|
|
spec = self->ArrSpecs[next];
|
|
}
|
|
|
|
self->ArrSpecs[ curr ] = spec;
|
|
}
|
|
|
|
if (result > -1) {
|
|
self->NumEntries --;
|
|
}
|
|
return result;
|
|
}
|
|
forceinline
|
|
Specifier* begin_CodeSpecifiers(CodeSpecifiers self)
|
|
{
|
|
if ( self != nullptr )
|
|
return & self->ArrSpecs[0];
|
|
|
|
return nullptr;
|
|
}
|
|
forceinline
|
|
Specifier* end_CodeSpecifiers(CodeSpecifiers self)
|
|
{
|
|
return self->ArrSpecs + self->NumEntries;
|
|
}
|
|
forceinline
|
|
Specifier* next_CodeSpecifiers(CodeSpecifiers self, Specifier* spec_iter)
|
|
{
|
|
return spec_iter + 1;
|
|
}
|
|
#pragma endregion CodeSpecifiers
|
|
|
|
#pragma region CodeStruct
|
|
inline
|
|
void struct_add_interface(CodeStruct self, CodeTypename type )
|
|
{
|
|
CodeTypename possible_slot = self->ParentType;
|
|
if ( possible_slot != nullptr )
|
|
{
|
|
// Were adding an interface to parent type, so we need to make sure the parent type is public.
|
|
self->ParentAccess = AccessSpec_Public;
|
|
// If your planning on adding a proper parent,
|
|
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
|
|
}
|
|
|
|
while ( possible_slot->Next != nullptr )
|
|
{
|
|
possible_slot->Next = cast(CodeTypename, possible_slot->Next);
|
|
}
|
|
|
|
possible_slot->Next = type;
|
|
}
|
|
#pragma endregion Code
|
|
|
|
#pragma region Interface
|
|
inline
|
|
CodeBody def_body( CodeType type )
|
|
{
|
|
switch ( type )
|
|
{
|
|
case CT_Class_Body:
|
|
case CT_Enum_Body:
|
|
case CT_Export_Body:
|
|
case CT_Extern_Linkage:
|
|
case CT_Function_Body:
|
|
case CT_Global_Body:
|
|
case CT_Namespace_Body:
|
|
case CT_Struct_Body:
|
|
case CT_Union_Body:
|
|
break;
|
|
|
|
default:
|
|
log_failure( "def_body: Invalid type %s", codetype_to_str(type).Ptr );
|
|
return (CodeBody)Code_Invalid;
|
|
}
|
|
|
|
Code
|
|
result = make_code();
|
|
result->Type = type;
|
|
return (CodeBody)result;
|
|
}
|
|
|
|
inline
|
|
Str token_fmt_impl( ssize num, ... )
|
|
{
|
|
local_persist thread_local
|
|
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
|
mem_set( buf, 0, GEN_PRINTF_MAXLEN );
|
|
|
|
va_list va;
|
|
va_start(va, num );
|
|
ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
|
|
va_end(va);
|
|
|
|
Str str = { buf, result };
|
|
return str;
|
|
}
|
|
#pragma endregion Interface
|