WIP: more progress on new macro handling

This commit is contained in:
Edward R. Gonzalez 2024-12-14 18:49:41 -05:00
parent 76257123da
commit c8cf55403b
16 changed files with 400 additions and 189 deletions

View File

@ -36,7 +36,6 @@ Str code_debug_str(Code self)
case CT_Execution: case CT_Execution:
case CT_Comment: case CT_Comment:
case CT_PlatformAttributes: case CT_PlatformAttributes:
case CT_Preprocess_Define:
case CT_Preprocess_Include: case CT_Preprocess_Include:
case CT_Preprocess_Pragma: case CT_Preprocess_Pragma:
case CT_Preprocess_If: case CT_Preprocess_If:
@ -52,6 +51,11 @@ Str code_debug_str(Code self)
strbuilder_append_fmt( result, "\n\tContent: %S", self->Content ); strbuilder_append_fmt( result, "\n\tContent: %S", self->Content );
break; break;
case CT_Preprocess_Define:
// TODO(ED): Needs implementaton
log_failure("code_debug_str: NOT IMPLEMENTED for CT_Preprocess_Define");
break;
case CT_Class: case CT_Class:
case CT_Struct: case CT_Struct:
if ( self->Prev ) if ( self->Prev )
@ -259,6 +263,11 @@ Str code_debug_str(Code self)
strbuilder_append_fmt( result, "\n\tValue : %S", self->Value ? strbuilder_to_str( code_to_strbuilder(self->Value)) : txt("Null") ); strbuilder_append_fmt( result, "\n\tValue : %S", self->Value ? strbuilder_to_str( code_to_strbuilder(self->Value)) : txt("Null") );
break; break;
case CT_Parameters_Define:
// TODO(ED): Needs implementaton
log_failure("code_debug_str: NOT IMPLEMENTED for CT_Parameters_Define");
break;
case CT_Specifiers: case CT_Specifiers:
{ {
strbuilder_append_fmt( result, "\n\tNumEntries: %d", self->NumEntries ); strbuilder_append_fmt( result, "\n\tNumEntries: %d", self->NumEntries );
@ -497,6 +506,10 @@ void code_to_strbuilder_ptr( Code self, StrBuilder* result )
params_to_strbuilder_ref(cast(CodeParams, self), result ); params_to_strbuilder_ref(cast(CodeParams, self), result );
break; break;
case CT_Parameters_Define:
define_params_to_strbuilder_ref(cast(CodeDefineParams, self), result);
break;
case CT_Preprocess_Define: case CT_Preprocess_Define:
define_to_strbuilder_ref(cast(CodeDefine, self), result ); define_to_strbuilder_ref(cast(CodeDefine, self), result );
break; break;
@ -987,11 +1000,17 @@ bool code_is_equal( Code self, Code other )
return true; return true;
} }
case CT_Parameters_Define:
{
// TODO(ED): Needs implementaton
log_failure("code_is_equal: NOT IMPLEMENTED for CT_Parameters_Define");
return false;
}
case CT_Preprocess_Define: case CT_Preprocess_Define:
{ {
check_member_str( Name ); check_member_str( Name );
check_member_content( Content ); check_member_content( Body->Content );
return true; return true;
} }

View File

@ -176,7 +176,7 @@ void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
{ {
GEN_ASSERT(self); GEN_ASSERT(self);
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
strbuilder_append_str( result, txt("class ") ); strbuilder_append_str( result, txt("class ") );
@ -221,7 +221,7 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result )
{ {
GEN_ASSERT(self); GEN_ASSERT(self);
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
if ( self->Attributes ) if ( self->Attributes )
@ -241,12 +241,48 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result )
StrBuilder define_to_strbuilder(CodeDefine define) StrBuilder define_to_strbuilder(CodeDefine define)
{ {
return strbuilder_fmt_buf( _ctx->Allocator_Temp, "#define %S %S", define->Name, define->Content ); StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
define_to_strbuilder_ref(define, & result);
return result;
} }
void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result ) void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result )
{ {
strbuilder_append_fmt( result, "#define %S %S", define->Name, define->Content ); GEN_ASSERT(define);
GEN_ASSERT(define->Body);
GEN_ASSERT(define->Body->Content);
if (define->Params) {
StrBuilder params_builder = define_params_to_strbuilder(define->Params)
strbuilder_append_fmt( result, "#define %S(%S) %S", define->Name, strbuilder_to_str(params_builder), define->Body->Content );
}
else {
strbuilder_append_fmt( result, "#define %S %S", define->Name, define->Body->Content );
}
}
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;
}
void define_params_to_strbuilder_ref(CodeDefineParams params, StrBuilder* result)
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->Name.Ptr && self->Name.Len )
{
strbuilder_append_fmt( result, " %S", self->Name );
}
if ( self->NumEntries - 1 > 0 )
{
for ( CodeParams param = begin_CodeDefineParams(self->Next); param != end_CodeDefineParams(self->Next); param = next_CodeDefineParams(self->Next, param) )
{
strbuilder_append_fmt( result, ", %SB", params_to_strbuilder(param) );
}
}
} }
StrBuilder destructor_to_strbuilder(CodeDestructor self) StrBuilder destructor_to_strbuilder(CodeDestructor self)
@ -329,7 +365,7 @@ StrBuilder enum_to_strbuilder(CodeEnum self)
void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result ) void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result )
{ {
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
if ( self->Attributes || self->UnderlyingType || self->UnderlyingTypeMacro ) if ( self->Attributes || self->UnderlyingType || self->UnderlyingTypeMacro )
@ -362,7 +398,7 @@ void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result )
void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result ) void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result )
{ {
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
if ( self->Attributes ) if ( self->Attributes )
@ -389,7 +425,7 @@ void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result )
void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result ) void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result )
{ {
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
if ( self->Attributes || self->UnderlyingType ) if ( self->Attributes || self->UnderlyingType )
@ -421,7 +457,7 @@ void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result )
void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result ) void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result )
{ {
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
strbuilder_append_str( result, txt("enum class ") ); strbuilder_append_str( result, txt("enum class ") );
@ -505,7 +541,7 @@ StrBuilder fn_to_strbuilder(CodeFn self)
void fn_to_strbuilder_def(CodeFn self, StrBuilder* result ) void fn_to_strbuilder_def(CodeFn self, StrBuilder* result )
{ {
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export") ); strbuilder_append_str( result, txt("export") );
if ( self->Attributes ) if ( self->Attributes )
@ -558,7 +594,7 @@ void fn_to_strbuilder_def(CodeFn self, StrBuilder* result )
void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result ) void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result )
{ {
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
if ( self->Attributes ) if ( self->Attributes )
@ -646,7 +682,7 @@ StrBuilder namespace_to_strbuilder(CodeNS self)
void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result ) void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result )
{ {
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("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) ); strbuilder_append_fmt( result, "namespace %S\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
@ -671,7 +707,7 @@ StrBuilder code_op_to_strbuilder(CodeOperator self)
void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result ) void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result )
{ {
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
if ( self->Attributes ) if ( self->Attributes )
@ -725,7 +761,7 @@ void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result )
void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result ) void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result )
{ {
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
if ( self->Attributes ) if ( self->Attributes )
@ -865,7 +901,6 @@ void opcast_to_strbuilder_fwd(CodeOpCast self, StrBuilder* result )
StrBuilder params_to_strbuilder(CodeParams self) StrBuilder params_to_strbuilder(CodeParams self)
{ {
GEN_ASSERT(self);
GEN_ASSERT(self); GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 ); StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
params_to_strbuilder_ref( self, & result ); params_to_strbuilder_ref( self, & result );
@ -1030,7 +1065,7 @@ void struct_to_strbuilder_def( CodeStruct self, StrBuilder* result )
{ {
GEN_ASSERT(self); GEN_ASSERT(self);
GEN_ASSERT(result); GEN_ASSERT(result);
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
strbuilder_append_str( result, txt("struct ") ); strbuilder_append_str( result, txt("struct ") );
@ -1076,7 +1111,7 @@ void struct_to_strbuilder_fwd( CodeStruct self, StrBuilder* result )
{ {
GEN_ASSERT(self); GEN_ASSERT(self);
GEN_ASSERT(result); GEN_ASSERT(result);
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
if ( self->Attributes ) if ( self->Attributes )
@ -1105,7 +1140,7 @@ void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result )
{ {
GEN_ASSERT(self); GEN_ASSERT(self);
GEN_ASSERT(result); GEN_ASSERT(result);
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
if ( self->Params ) if ( self->Params )
@ -1123,7 +1158,7 @@ StrBuilder typedef_to_strbuilder(CodeTypedef self)
void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result ) void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result )
{ {
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
strbuilder_append_str( result, txt("typedef ")); strbuilder_append_str( result, txt("typedef "));
@ -1236,7 +1271,7 @@ StrBuilder union_to_strbuilder(CodeUnion self)
void union_to_strbuilder_def(CodeUnion self, StrBuilder* result ) void union_to_strbuilder_def(CodeUnion self, StrBuilder* result )
{ {
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
strbuilder_append_str( result, txt("union ") ); strbuilder_append_str( result, txt("union ") );
@ -1267,7 +1302,7 @@ void union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result )
{ {
GEN_ASSERT(self); GEN_ASSERT(self);
GEN_ASSERT(result); GEN_ASSERT(result);
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
strbuilder_append_str( result, txt("union ") ); strbuilder_append_str( result, txt("union ") );
@ -1304,7 +1339,7 @@ void using_to_strbuilder_ref(CodeUsing self, StrBuilder* result )
{ {
GEN_ASSERT(self); GEN_ASSERT(self);
GEN_ASSERT(result); GEN_ASSERT(result);
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
if ( self->Attributes ) if ( self->Attributes )
@ -1401,7 +1436,7 @@ void var_to_strbuilder_ref(CodeVar self, StrBuilder* result )
return; return;
} }
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") ); strbuilder_append_str( result, txt("export ") );
if ( self->Attributes || self->Specs ) if ( self->Attributes || self->Specs )

View File

@ -46,6 +46,7 @@ enum CodeType : u32
CT_Operator_Cast, CT_Operator_Cast,
CT_Operator_Cast_Fwd, CT_Operator_Cast_Fwd,
CT_Parameters, CT_Parameters,
CT_Parameters_Define,
CT_Preprocess_Define, CT_Preprocess_Define,
CT_Preprocess_Include, CT_Preprocess_Include,
CT_Preprocess_If, CT_Preprocess_If,
@ -114,6 +115,7 @@ inline Str codetype_to_str( CodeType type )
{ "Operator_Cast", sizeof( "Operator_Cast" ) - 1 }, { "Operator_Cast", sizeof( "Operator_Cast" ) - 1 },
{ "Operator_Cast_Fwd", sizeof( "Operator_Cast_Fwd" ) - 1 }, { "Operator_Cast_Fwd", sizeof( "Operator_Cast_Fwd" ) - 1 },
{ "Parameters", sizeof( "Parameters" ) - 1 }, { "Parameters", sizeof( "Parameters" ) - 1 },
{ "Parameters_Define", sizeof( "Parameters_Define" ) - 1 },
{ "Preprocess_Define", sizeof( "Preprocess_Define" ) - 1 }, { "Preprocess_Define", sizeof( "Preprocess_Define" ) - 1 },
{ "Preprocess_Include", sizeof( "Preprocess_Include" ) - 1 }, { "Preprocess_Include", sizeof( "Preprocess_Include" ) - 1 },
{ "Preprocess_If", sizeof( "Preprocess_If" ) - 1 }, { "Preprocess_If", sizeof( "Preprocess_If" ) - 1 },
@ -182,6 +184,7 @@ inline Str codetype_to_keyword_str( CodeType type )
{ "operator", sizeof( "operator" ) - 1 }, { "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 }, { "operator", sizeof( "operator" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "define", sizeof( "define" ) - 1 }, { "define", sizeof( "define" ) - 1 },
{ "include", sizeof( "include" ) - 1 }, { "include", sizeof( "include" ) - 1 },
{ "if", sizeof( "if" ) - 1 }, { "if", sizeof( "if" ) - 1 },

View File

@ -53,6 +53,7 @@ enum TokType : u32
Tok_Operator, Tok_Operator,
Tok_Preprocess_Hash, Tok_Preprocess_Hash,
Tok_Preprocess_Define, Tok_Preprocess_Define,
Tok_Preprocess_Define_Param,
Tok_Preprocess_If, Tok_Preprocess_If,
Tok_Preprocess_IfDef, Tok_Preprocess_IfDef,
Tok_Preprocess_IfNotDef, Tok_Preprocess_IfNotDef,
@ -62,7 +63,9 @@ enum TokType : u32
Tok_Preprocess_Include, Tok_Preprocess_Include,
Tok_Preprocess_Pragma, Tok_Preprocess_Pragma,
Tok_Preprocess_Content, Tok_Preprocess_Content,
Tok_Preprocess_Macro, Tok_Preprocess_Macro_Expr,
Tok_Preprocess_Macro_Stmt,
Tok_Preprocess_Macro_Typename,
Tok_Preprocess_Unsupported, Tok_Preprocess_Unsupported,
Tok_Spec_Alignas, Tok_Spec_Alignas,
Tok_Spec_Const, Tok_Spec_Const,
@ -155,6 +158,7 @@ inline Str toktype_to_str( TokType type )
{ "__operator__", sizeof( "__operator__" ) - 1 }, { "__operator__", sizeof( "__operator__" ) - 1 },
{ "#", sizeof( "#" ) - 1 }, { "#", sizeof( "#" ) - 1 },
{ "define", sizeof( "define" ) - 1 }, { "define", sizeof( "define" ) - 1 },
{ "__define_param__", sizeof( "__define__param__" ) - 1 },
{ "if", sizeof( "if" ) - 1 }, { "if", sizeof( "if" ) - 1 },
{ "ifdef", sizeof( "ifdef" ) - 1 }, { "ifdef", sizeof( "ifdef" ) - 1 },
{ "ifndef", sizeof( "ifndef" ) - 1 }, { "ifndef", sizeof( "ifndef" ) - 1 },
@ -164,7 +168,9 @@ inline Str toktype_to_str( TokType type )
{ "include", sizeof( "include" ) - 1 }, { "include", sizeof( "include" ) - 1 },
{ "pragma", sizeof( "pragma" ) - 1 }, { "pragma", sizeof( "pragma" ) - 1 },
{ "__macro_content__", sizeof( "__macro_content__" ) - 1 }, { "__macro_content__", sizeof( "__macro_content__" ) - 1 },
{ "__macro__", sizeof( "__macro__" ) - 1 }, { "__macro_expression__", sizeof( "__macro_expression__" ) - 1 },
{ "__macro_statment__", sizeof( "__macro_statment__" ) - 1 },
{ "__macro_typename__", sizeof( "__macro_typename__" ) - 1 },
{ "__unsupported__", sizeof( "__unsupported__" ) - 1 }, { "__unsupported__", sizeof( "__unsupported__" ) - 1 },
{ "alignas", sizeof( "alignas" ) - 1 }, { "alignas", sizeof( "alignas" ) - 1 },
{ "const", sizeof( "const" ) - 1 }, { "const", sizeof( "const" ) - 1 },

View File

@ -6,7 +6,7 @@
#pragma region Constants #pragma region Constants
extern Str enum_underlying_sig; extern PreprocessorMacro enum_underlying_macro;
extern Code access_public; extern Code access_public;
extern Code access_protected; extern Code access_protected;

View File

@ -206,10 +206,12 @@ void define_constants()
spec_local_persist = def_specifiers( 1, Spec_Local_Persist ); spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
code_set_global(cast(Code, spec_local_persist)); code_set_global(cast(Code, spec_local_persist));
if (enum_underlying_sig.Len == 0) { if (enum_underlying_macro.Name.Len == 0) {
enum_underlying_sig = txt("enum_underlying("); enum_underlying_macro.Name = txt("enum_underlying(");
enum_underlying_macro.Type = MT_Expression;
enum_underlying_macro.Flags = MF_Functional;
} }
array_append( _ctx->PreprocessorDefines, enum_underlying_sig); register_preprocess_macro(enum_underlying_macro);
} }
void init(Context* ctx) void init(Context* ctx)
@ -301,9 +303,6 @@ void init(Context* ctx)
GEN_FATAL( "gen::init: Failed to initialize the code pool" ); GEN_FATAL( "gen::init: Failed to initialize the code pool" );
array_append( ctx->CodePools, code_pool ); array_append( ctx->CodePools, code_pool );
// TODO(Ed): This is going to be phased out most likely.
ctx->LexArena = arena_init_from_allocator( ctx->Allocator_DyanmicContainers, ctx->InitSize_LexArena );
// TODO(Ed): Eventually the string arenas needs to be phased out for a dedicated string slab allocator // TODO(Ed): Eventually the string arenas needs to be phased out for a dedicated string slab allocator
Arena strbuilder_arena = arena_init_from_allocator( ctx->Allocator_StrCache, ctx->SizePer_StringArena ); Arena strbuilder_arena = arena_init_from_allocator( ctx->Allocator_StrCache, ctx->SizePer_StringArena );
if ( strbuilder_arena.PhysicalStart == nullptr ) if ( strbuilder_arena.PhysicalStart == nullptr )
@ -315,9 +314,12 @@ void init(Context* ctx)
ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers); ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers);
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->PreprocessorMacros = hashtable_init(PreprocessorMacros, ctx->Allocator_DyanmicContainers);
if (ctx->PreprocessorMacros.Hashes == nullptr || ctx->PreprocessorMacros.Entries == nullptr) {
GEN_FATAL( "gen::init: Failed to initialize the PreprocessMacros table" );
}
} }
// Preprocessor Defines
ctx->PreprocessorDefines = array_init_reserve(StrCached, ctx->Allocator_DyanmicContainers, kilobytes(1) );
define_constants(); define_constants();
parser_init(); parser_init();
@ -354,9 +356,7 @@ void deinit(Context* ctx)
array_free( ctx->CodePools); array_free( ctx->CodePools);
array_free( ctx->StringArenas); array_free( ctx->StringArenas);
// arena_free(& ctx->LexArena); hashtable_destroy(ctx->PreprocessorMacros);
array_free(ctx->PreprocessorDefines);
left = array_num( ctx->Fallback_AllocatorBuckets); left = array_num( ctx->Fallback_AllocatorBuckets);
if (left) if (left)
@ -401,6 +401,7 @@ void reset(Context* ctx)
while ( left--, left ); while ( left--, left );
hashtable_clear(ctx->StrCache); hashtable_clear(ctx->StrCache);
hashtable_clear(ctx->PreprocessorMacros);
define_constants(); define_constants();
} }

View File

@ -156,6 +156,7 @@ GEN_API CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEF
struct Opts_def_define { struct Opts_def_define {
MacroFlags flags; MacroFlags flags;
CodeDefineParams params; CodeDefineParams params;
Str content;
b32 dont_register_to_preprocess_macros; b32 dont_register_to_preprocess_macros;
}; };
GEN_API CodeDefine def_define( Str name, MacroType type, Opts_def_define opts GEN_PARAM_DEFAULT ); GEN_API CodeDefine def_define( Str name, MacroType type, Opts_def_define opts GEN_PARAM_DEFAULT );
@ -269,28 +270,30 @@ GEN_API CodeBody def_body( CodeType type );
// There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num, // There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num,
/// or provide as an array of Code objects. /// or provide as an array of Code objects.
GEN_API CodeBody def_class_body ( s32 num, ... ); GEN_API CodeBody def_class_body ( s32 num, ... );
GEN_API CodeBody def_class_body ( s32 num, Code* codes ); GEN_API CodeBody def_class_body ( s32 num, Code* codes );
GEN_API CodeBody def_enum_body ( s32 num, ... ); GEN_API CodeDefineParams def_define_params ( s32 num, ... );
GEN_API CodeBody def_enum_body ( s32 num, Code* codes ); GEN_API CodeDefineParams def_define_params ( s32 num, CodeDefineParams* codes )
GEN_API CodeBody def_export_body ( s32 num, ... ); GEN_API CodeBody def_enum_body ( s32 num, ... );
GEN_API CodeBody def_export_body ( s32 num, Code* codes); GEN_API CodeBody def_enum_body ( s32 num, Code* codes );
GEN_API CodeBody def_extern_link_body( s32 num, ... ); GEN_API CodeBody def_export_body ( s32 num, ... );
GEN_API CodeBody def_extern_link_body( s32 num, Code* codes ); GEN_API CodeBody def_export_body ( s32 num, Code* codes);
GEN_API CodeBody def_function_body ( s32 num, ... ); GEN_API CodeBody def_extern_link_body( s32 num, ... );
GEN_API CodeBody def_function_body ( s32 num, Code* codes ); GEN_API CodeBody def_extern_link_body( s32 num, Code* codes );
GEN_API CodeBody def_global_body ( s32 num, ... ); GEN_API CodeBody def_function_body ( s32 num, ... );
GEN_API CodeBody def_global_body ( s32 num, Code* codes ); GEN_API CodeBody def_function_body ( s32 num, Code* codes );
GEN_API CodeBody def_namespace_body ( s32 num, ... ); GEN_API CodeBody def_global_body ( s32 num, ... );
GEN_API CodeBody def_namespace_body ( s32 num, Code* codes ); GEN_API CodeBody def_global_body ( s32 num, Code* codes );
GEN_API CodeParams def_params ( s32 num, ... ); GEN_API CodeBody def_namespace_body ( s32 num, ... );
GEN_API CodeParams def_params ( s32 num, CodeParams* params ); GEN_API CodeBody def_namespace_body ( s32 num, Code* codes );
GEN_API CodeSpecifiers def_specifiers ( s32 num, ... ); GEN_API CodeParams def_params ( s32 num, ... );
GEN_API CodeSpecifiers def_specifiers ( s32 num, Specifier* specs ); GEN_API CodeParams def_params ( s32 num, CodeParams* params );
GEN_API CodeBody def_struct_body ( s32 num, ... ); GEN_API CodeSpecifiers def_specifiers ( s32 num, ... );
GEN_API CodeBody def_struct_body ( s32 num, Code* codes ); GEN_API CodeSpecifiers def_specifiers ( s32 num, Specifier* specs );
GEN_API CodeBody def_union_body ( s32 num, ... ); GEN_API CodeBody def_struct_body ( s32 num, ... );
GEN_API CodeBody def_union_body ( s32 num, Code* codes ); GEN_API CodeBody def_struct_body ( s32 num, Code* codes );
GEN_API CodeBody def_union_body ( s32 num, ... );
GEN_API CodeBody def_union_body ( s32 num, Code* codes );
#pragma endregion Upfront #pragma endregion Upfront

View File

@ -516,7 +516,6 @@ CodeClass def_class( Str name, Opts_def_struct p )
GEN_DEBUG_TRAP(); GEN_DEBUG_TRAP();
return InvalidCode; return InvalidCode;
} }
if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) { if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) {
log_failure( "gen::def_class: attributes was not a 'PlatformAttributes' type: %s", code_debug_str(p.attributes) ); log_failure( "gen::def_class: attributes was not a 'PlatformAttributes' type: %s", code_debug_str(p.attributes) );
GEN_DEBUG_TRAP(); GEN_DEBUG_TRAP();
@ -529,9 +528,12 @@ CodeClass def_class( Str name, Opts_def_struct p )
} }
CodeClass CodeClass
result = (CodeClass) make_code(); result = (CodeClass) make_code();
result->Name = cache_str( name ); result->Name = cache_str( name );
result->ModuleFlags = p.mflags; result->ModuleFlags = p.mflags;
result->Attributes = p.attributes;
result->ParentAccess = p.parent_access;
result->ParentType = p.parent;
if ( p.body ) if ( p.body )
{ {
switch ( p.body->Type ) switch ( p.body->Type )
@ -552,44 +554,32 @@ CodeClass def_class( Str name, Opts_def_struct p )
else { else {
result->Type = CT_Class_Fwd; result->Type = CT_Class_Fwd;
} }
result->Attributes = p.attributes;
result->ParentAccess = p.parent_access;
result->ParentType = p.parent;
for (s32 idx = 0; idx < p.num_interfaces; idx++ ) { for (s32 idx = 0; idx < p.num_interfaces; idx++ ) {
class_add_interface(result, p.interfaces[idx] ); class_add_interface(result, p.interfaces[idx] );
} }
return result; return result;
} }
CodeDefine def_define( Str name, Str content, Opts_def_define p ) CodeDefine def_define( Str name, MacroType type, Opts_def_define p )
{ {
if ( ! name_check( def_define, name ) ) { if ( ! name_check( def_define, name ) ) {
GEN_DEBUG_TRAP(); GEN_DEBUG_TRAP();
return InvalidCode; return InvalidCode;
} }
CodeDefine CodeDefine
result = (CodeDefine) make_code(); result = (CodeDefine) make_code();
result->Type = CT_Preprocess_Define; result->Type = CT_Preprocess_Define;
result->Name = cache_str( name ); result->Name = cache_str( name );
result->Params = p.params;
if ( content.Len <= 0 || content.Ptr == nullptr ) if ( p.content.Len <= 0 || p.content.Ptr == nullptr )
result->Content = cache_str( txt("") ); result->Content = cache_str( txt("\n") );
else else
result->Content = cache_str( strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S\n", content)) ); result->Content = cache_str( strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S\n", content)) );
b32 append_preprocess_defines = ! p.dont_append_preprocess_defines; b32 register_define = ! p.dont_register_to_preprocess_macros;
if ( append_preprocess_defines ) { if ( register_define ) {
// Add the define to PreprocessorDefines for usage in parsing macro_entry = { result->Name, type, p.flags };
s32 lex_id_len = 0; register_preprocess_macro(macro_entry);
for (; lex_id_len < result->Name.Len; ++ lex_id_len ) {
if ( result->Name.Ptr[lex_id_len] == '(' )
break;
}
Str lex_id = { result->Name.Ptr, lex_id_len };
array_append(_ctx->PreprocessorDefines, cache_str(lex_id) );
} }
return result; return result;
} }
@ -1410,6 +1400,67 @@ CodeBody def_class_body( s32 num, Code* codes )
return result; return result;
} }
CodeDefineParams def_define_params( s32 num, ... )
{
def_body_start( def_define_params );
va_list va;
va_start(va, num);
Code_POD pod = va_arg(va, Code_POD);
CodeDefineParams param = pcast( CodeDefineParams, pod );
null_check( def_define_params, param );
if ( param->Type != CT_Parameters_Define ) {
log_failure( "gen::def_define_params: param %d is not a parameter for a preprocessor define", num - num + 1 );
return InvalidCode;
}
CodeDefineParams result = (CodeDefineParams) code_duplicate(param);
while ( -- num )
{
pod = va_arg(va, Code_POD);
param = pcast( CodeDefineParams, pod );
if ( param->Type != CT_Parameters_Define ) {
log_failure( "gen::def_define_params: param %d is not a parameter for a preprocessor define", num - num + 1 );
return InvalidCode;
}
define_params_append(result, param );
}
va_end(va);
return result;
}
CodeDefineParams def_define_params( s32 num, CodeDefineParams* codes )
{
def_body_code_array_start( def_define_params );
# define check_current(current) \
if ( current == nullptr ) { \
log_failure("gen::def_define_params: Provide a null code in codes array"); \
return InvalidCode; \
} \
if (current->Type != CT_Parameters_Define ) { \
log_failure("gen::def_define_params: Code in coes array is not of paramter for preprocessor define type - %s", code_debug_str(current) ); \
return InvalidCode; \
}
CodeDefineParams current = (CodeDefineParams)code_duplicate(* codes);
check_current(current);
CodeDefineParams
result = (CodeDefineParams) make_code();
result->Name = current->Name;
result->Type = current->Type;
while( codes++, current = * codes, num--, num > 0 ) {
check_current(current);
define_params_append(result, current );
}
# undef check_current
return result;
}
CodeBody def_enum_body( s32 num, ... ) CodeBody def_enum_body( s32 num, ... )
{ {
def_body_start( def_enum_body ); def_body_start( def_enum_body );

View File

@ -112,6 +112,102 @@ void lexer_end_line( LexContext* ctx )
} }
#define end_line() lexer_end_line(ctx) #define end_line() lexer_end_line(ctx)
// TODO(Ed): We need to to attempt to recover from a lex failure?
s32 lex_preprocessor_define( LexContext* ctx )
{
Token name = { { ctx->scanner, 1 }, Tok_Identifier, ctx->line, ctx->column, TF_Preprocess };
move_forward();
PreprocessorMacro macro = { name.Text, MT_Statement, 0 };
PreprocessorMacro* registered_macro = lookup_preprocess_macro(name.Text);
if ( registered_macro == nullptr ) {
log_fmt("Warning: %S is was not registered before the lexer processed its #define directive, it will be registered as a statement macro"
, name.Text
);
}
while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) ) {
move_forward();
name.Text.Len++;
}
array_append( _ctx->Lexer_Tokens, name );
if ( ctx->left && (* ctx->scanner) == '(' )
{
if (registered_macro && ! macro_is_functional(* registered_macro)) {
log_fmt("Warning: %S registered macro is not flagged as functional yet the definition detects opening parenthesis '(' for arguments"
, name.Text
);
}
else {
macro.Flags |= MF_Functional;
}
Token opening_paren = { { ctx->scanner, 1 }, Tok_Capture_Start, ctx->line, ctx->column, TF_Preprocess };
array_append( _ctx->Lexer_Tokens, opening_paren );
move_forward();
// We need to tokenize the define's arguments now:
while( ctx->left && * ctx->scanner != ')')
{
skip_whitespace();
if ( char_is_alpha( (* ctx->scanner) ) || (* ctx->scanner) == '_' )
{
Token parameter = { { ctx->scanner, 1 }, Tok_Preprocess_Define_Param, ctx->line, ctx->column, TF_Preprocess };
move_forward();
while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) )
{
move_forward();
parameter.Text.Len++;
}
array_append(_ctx->Lexer_Tokens, parameter);
skip_whitespace();
}
else {
log_failure("lex_preprocessor_define(%d, %d): Expected a '_' or alpha character for a parameter name for %S\n"
, ctx->line
, ctx->column
, name.Text
);
return Lex_ReturnNull;
}
// There should be a comma
if ( * ctx->scanner != ',' ) {
log_failure("lex_preprocessor_define(%d, %d): Expected a comma after parameter %S for %S\n"
, ctx->line
, ctx->column
, parameter.Text
, name.Text
);
return Lex_ReturnNull;
}
Token comma = { { ctx->scanner, 1 }, Tok_Comma, ctx->line, ctx->column, TF_Preprocess };
array_append(_ctx->Lexer_Tokens, comma);
move_forward();
}
if ( * ctx->scanner != ')' ) {
log_failure("lex_preprocessor_define(%d, %d): Expected a ')' after last_parameter %S for %S (ran out of characters...)\n"
, ctx->line
, ctx->column
, parameter.Text
, name.Text
);
return Lex_ReturnNull;
}
Token closing_paren = { { ctx->scanner, 1 }, Tok_Capture_End, ctx->line, ctx->column, TF_Preprocess };
array_append(_ctx->Lexer_Tokens, closing_paren);
move_forward();
}
if ( registered_macro == nullptr ) {
register_preprocess_macro(macro);
}
// Define's content handled by lex_preprocessor_directive (the original caller of this)
return Lex_Continue;
}
// TODO(Ed): We need to to attempt to recover from a lex failure?
forceinline forceinline
s32 lex_preprocessor_directive( LexContext* ctx ) s32 lex_preprocessor_directive( LexContext* ctx )
{ {
@ -215,31 +311,9 @@ s32 lex_preprocessor_directive( LexContext* ctx )
if ( ctx->token.Type == Tok_Preprocess_Define ) if ( ctx->token.Type == Tok_Preprocess_Define )
{ {
Token name = { { ctx->scanner, 0 }, Tok_Identifier, ctx->line, ctx->column, TF_Preprocess }; u32 result = lex_preprocessor_define(ctx); // handles: #define <name>( <params> ) - define's content handled later on within this scope.
if (result != Lex_Continue)
name.Text.Ptr = ctx->scanner; return Lex_ReturnNull;
name.Text.Len = 1;
move_forward();
PreprocessorMacro* registered_macro = lookup_preprocess_macro(name.Text);
while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) )
{
move_forward();
name.Text.Len++;
}
if ( ctx->left && (* ctx->scanner) == '(' )
{
move_forward();
name.Text.Len++;
}
array_append( _ctx->Lexer_Tokens, name );
u64 key = crc32( name.Text.Ptr, name.Text.Len );
hashtable_set(ctx->defines, key, tok_to_str(name) );
} }
Token preprocess_content = { { ctx->scanner, 0 }, Tok_Preprocess_Content, ctx->line, ctx->column, TF_Preprocess }; Token preprocess_content = { { ctx->scanner, 0 }, Tok_Preprocess_Content, ctx->line, ctx->column, TF_Preprocess };
@ -289,7 +363,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
s32 within_string = false; s32 within_string = false;
s32 within_char = false; s32 within_char = false;
// SkipWhitespace(); // Consume preprocess content
while ( ctx->left ) while ( ctx->left )
{ {
if ( (* ctx->scanner) == '"' && ! within_char ) if ( (* ctx->scanner) == '"' && ! within_char )
@ -325,6 +399,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
, (* ctx->scanner), ctx->line, ctx->column , (* ctx->scanner), ctx->line, ctx->column
, directive_str, preprocess_content.Line, preprocess_content.Column , directive_str, preprocess_content.Line, preprocess_content.Column
, content_str ); , content_str );
return Lex_ReturnNull;
break; break;
} }
} }
@ -404,14 +479,15 @@ void lex_found_token( LexContext* ctx )
} }
u64 key = 0; u64 key = 0;
if ( (* ctx->scanner) == '(') // if ( (* ctx->scanner) == '(')
key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len + 1 ); // key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len + 1 );
else // else
key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len ); key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len );
Str* define = hashtable_get(ctx->defines, key ); Str* define = hashtable_get(_ctx->PreprocessMacros, key );
if ( define ) if ( define )
{ {
// TODO(Ed): Needs updating (Macros)
ctx->token.Type = Tok_Preprocess_Macro; ctx->token.Type = Tok_Preprocess_Macro;
// Want to ignore any arguments the define may have as they can be execution expressions. // Want to ignore any arguments the define may have as they can be execution expressions.
@ -456,6 +532,7 @@ void lex_found_token( LexContext* ctx )
array_append( _ctx->Lexer_Tokens, ctx->token ); array_append( _ctx->Lexer_Tokens, ctx->token );
} }
// TODO(Ed): We need to to attempt to recover from a lex failure?
neverinline neverinline
// TokArray lex( Array<Token> tokens, Str content ) // TokArray lex( Array<Token> tokens, Str content )
TokArray lex( Str content ) TokArray lex( Str content )
@ -480,27 +557,10 @@ TokArray lex( Str content )
return null_array; return null_array;
} }
// TODO(ED): Remove this when preprocess defines has been converted
// for ( StrCached* entry = array_begin(_ctx->PreprocessorDefines); entry != array_end(_ctx->PreprocessorDefines); entry = array_next(_ctx->PreprocessorDefines, entry))
// {
// s32 length = 0;
// char const* entry_scanner = (*entry).Ptr;
// while ( entry->Len > length && (char_is_alphanumeric( *entry_scanner ) || *entry_scanner == '_') )
// {
// entry_scanner++;
// length ++;
// }
// if ( entry_scanner[0] == '(' )
// {
// length++;
// }
// u64 key = crc32( entry->Ptr, length );
// hashtable_set(c.defines, key, * entry );
// }
array_clear(_ctx->Lexer_Tokens); array_clear(_ctx->Lexer_Tokens);
b32 preprocess_args = true;
while (c.left ) while (c.left )
{ {
#if 0 #if 0
@ -1182,6 +1242,7 @@ TokArray lex( Str content )
{ {
lex_found_token( ctx ); lex_found_token( ctx );
TokType last_type = array_back(_ctx->Lexer_Tokens)->Type; TokType last_type = array_back(_ctx->Lexer_Tokens)->Type;
// TODO(Ed): Change this to just detect if its a MACRO THAT SHOULD ACCEPT NEWLINES
if ( last_type == Tok_Preprocess_Macro ) if ( last_type == Tok_Preprocess_Macro )
{ {
Token thanks_c = { { c.scanner, 0 }, Tok_Invalid, c.line, c.column, TF_Null }; Token thanks_c = { { c.scanner, 0 }, Tok_Invalid, c.line, c.column, TF_Null };
@ -1217,6 +1278,7 @@ TokArray lex( Str content )
TokArray result = { _ctx->Lexer_Tokens, 0 }; TokArray result = { _ctx->Lexer_Tokens, 0 };
return result; return result;
} }
#undef move_forward #undef move_forward
#undef skip_whitespace #undef skip_whitespace
#undef end_line #undef end_line

View File

@ -825,22 +825,21 @@ CodeBody parse_class_struct_body( TokType which, Token name )
switch ( currtok_noskip.Type ) switch ( currtok_noskip.Type )
{ {
case Tok_Statement_End: case Tok_Statement_End: {
{
// TODO(Ed): Convert this to a general warning procedure // TODO(Ed): Convert this to a general warning procedure
log_fmt("Dangling end statement found %SB\n", tok_to_strbuilder(currtok_noskip)); log_fmt("Dangling end statement found %SB\n", tok_to_strbuilder(currtok_noskip));
eat( Tok_Statement_End ); eat( Tok_Statement_End );
continue; continue;
} }
case Tok_NewLine: case Tok_NewLine: {
member = fmt_newline; member = fmt_newline;
eat( Tok_NewLine ); eat( Tok_NewLine );
break; break;
}
case Tok_Comment: case Tok_Comment: {
member = cast(Code, parse_comment()); member = cast(Code, parse_comment());
break; break;
}
case Tok_Access_Public: case Tok_Access_Public:
member = access_public; member = access_public;
eat( Tok_Access_Public ); eat( Tok_Access_Public );
@ -1727,8 +1726,8 @@ CodeBody parse_global_nspace( CodeType which )
// <Macro> // <Macro>
macro_found = true; macro_found = true;
goto Preprocess_Macro_Bare_In_Body; goto Preprocess_Macro_Bare_In_Body;
// TODO(Ed): MACRO UPDATE
} }
break;
case Tok_Preprocess_Pragma: { case Tok_Preprocess_Pragma: {
member = cast(Code, parse_pragma()); member = cast(Code, parse_pragma());
@ -2727,7 +2726,7 @@ CodeParams parse_params( bool use_template_capture )
// In template captures you can have a typename have direct assignment without a name // In template captures you can have a typename have direct assignment without a name
// typename = typename ... // typename = typename ...
// Which would result in a static value type from a struct expansion (traditionally) // Which would result in a static value type from a struct expansion (traditionally)
if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
{ {
eat( Tok_Operator ); eat( Tok_Operator );
// ( <Macro> <ValueType> <Name> = // ( <Macro> <ValueType> <Name> =
@ -2839,7 +2838,7 @@ CodeParams parse_params( bool use_template_capture )
// In template captures you can have a typename have direct assignment without a name // In template captures you can have a typename have direct assignment without a name
// typename = typename ... // typename = typename ...
// Which would result in a static value type from a struct expansion (traditionally) // Which would result in a static value type from a struct expansion (traditionally)
if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
{ {
eat( Tok_Operator ); eat( Tok_Operator );
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = // ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> =
@ -3166,7 +3165,7 @@ CodeVar parse_variable_after_name(
b32 using_constructor_initializer = false; b32 using_constructor_initializer = false;
if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
{ {
// <Attributes> <Specifiers> <ValueType> <Name> = <Expression> // <Attributes> <Specifiers> <ValueType> <Name> = <Expression>
expr = parse_assignment_expression(); expr = parse_assignment_expression();
@ -4645,6 +4644,7 @@ else if ( currtok.Type == Tok_DeclType )
} }
} }
} }
// TODO(Ed): This needs updating
else if ( currtok.Type == Tok_Preprocess_Macro ) { else if ( currtok.Type == Tok_Preprocess_Macro ) {
// Typename is a macro // Typename is a macro
name = currtok; name = currtok;
@ -4988,6 +4988,7 @@ CodeTypedef parser_parse_typedef()
const bool from_typedef = true; const bool from_typedef = true;
// TODO(Ed): UPDATE MACRO USAGE HERE
#if GEN_PARSER_DISABLE_MACRO_TYPEDEF #if GEN_PARSER_DISABLE_MACRO_TYPEDEF
if ( false ) if ( false )
#else #else
@ -5365,7 +5366,7 @@ CodeUsing parser_parse_using()
if ( ! is_namespace ) if ( ! is_namespace )
{ {
if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
{ {
attributes = parse_attributes(); attributes = parse_attributes();
// <ModuleFlags> using <Name> <Attributes> // <ModuleFlags> using <Name> <Attributes>

View File

@ -6,34 +6,6 @@
#include "gen/especifier.hpp" #include "gen/especifier.hpp"
#endif #endif
enum MacroTypes : u16
{
MT_Block_Start, // Not Supported yet
MT_Block_End, // Not Supported yet
MT_Case_Statement, // Not Supported yet
MT_Expression,
MT_Statement,
MT_Typename,
MF_UnderlyingType = GEN_U16_Max,
};
enum MacroFlags : u16
{
MF_Functional = bit(0), // Macro has parameters (args expected to be passed)
MF_Expects_Body = bit(1), // Expects to assign a braced scope to its body.
MF_Null = 0,
MF_UnderlyingType = GEN_U16_Max,
};
struct PreprocessorMacro
{
StrCached Name;
MacroTypes Type;
MacroFlags Flags;
};
enum TokFlags : u32 enum TokFlags : u32
{ {
TF_Operator = bit(0), TF_Operator = bit(0),
@ -82,42 +54,42 @@ bool tok_is_valid( Token tok ) {
forceinline forceinline
bool tok_is_access_operator(Token tok) { bool tok_is_access_operator(Token tok) {
return bitfield_is_equal( u32, tok.Flags, TF_AccessOperator ); return bitfield_is_set( u32, tok.Flags, TF_AccessOperator );
} }
forceinline forceinline
bool tok_is_access_specifier(Token tok) { bool tok_is_access_specifier(Token tok) {
return bitfield_is_equal( u32, tok.Flags, TF_AccessSpecifier ); return bitfield_is_set( u32, tok.Flags, TF_AccessSpecifier );
} }
forceinline forceinline
bool tok_is_attribute(Token tok) { bool tok_is_attribute(Token tok) {
return bitfield_is_equal( u32, tok.Flags, TF_Attribute ); return bitfield_is_set( u32, tok.Flags, TF_Attribute );
} }
forceinline forceinline
bool tok_is_operator(Token tok) { bool tok_is_operator(Token tok) {
return bitfield_is_equal( u32, tok.Flags, TF_Operator ); return bitfield_is_set( u32, tok.Flags, TF_Operator );
} }
forceinline forceinline
bool tok_is_preprocessor(Token tok) { bool tok_is_preprocessor(Token tok) {
return bitfield_is_equal( u32, tok.Flags, TF_Preprocess ); return bitfield_is_set( u32, tok.Flags, TF_Preprocess );
} }
forceinline forceinline
bool tok_is_preprocess_cond(Token tok) { bool tok_is_preprocess_cond(Token tok) {
return bitfield_is_equal( u32, tok.Flags, TF_Preprocess_Cond ); return bitfield_is_set( u32, tok.Flags, TF_Preprocess_Cond );
} }
forceinline forceinline
bool tok_is_specifier(Token tok) { bool tok_is_specifier(Token tok) {
return bitfield_is_equal( u32, tok.Flags, TF_Specifier ); return bitfield_is_set( u32, tok.Flags, TF_Specifier );
} }
forceinline forceinline
bool tok_is_end_definition(Token tok) { bool tok_is_end_definition(Token tok) {
return bitfield_is_equal( u32, tok.Flags, TF_EndDefinition ); return bitfield_is_set( u32, tok.Flags, TF_EndDefinition );
} }
StrBuilder tok_to_strbuilder(Token tok); StrBuilder tok_to_strbuilder(Token tok);
@ -153,3 +125,60 @@ struct ParseContext
TokArray Tokens; TokArray Tokens;
StackNode* Scope; StackNode* Scope;
}; };
enum MacroType : u16
{
MT_Statement, // A macro is assumed to be a statement if not resolved.
MT_Expression,
MT_Typename,
MT_Block_Start, // Not Supported yet
MT_Block_End, // Not Supported yet
MT_Case_Statement, // Not Supported yet
MF_UnderlyingType = GEN_U16_Max,
};
Str macro_type_to_str( MacroType type )
{
local_persist
Str lookup[ (u32)Num_ModuleFlags ] = {
{ "Statement", sizeof("Statement") - 1 },
{ "Expression", sizeof("Expression") - 1 },
{ "Typename", sizeof("Typename") - 1 },
{ "Block_Start", sizeof("Block_Start") - 1 },
{ "Block_End", sizeof("Block_End") - 1 },
{ "Case_Statement", sizeof("Case_Statement") - 1 },
};
local_persist
Str invalid_flag = { "Invalid", sizeof("Invalid") };
if ( flag > ModuleFlag_Import )
return invalid_flag;
return lookup[ (u32)flag ];
}
enum MacroFlags : u16
{
MF_Functional = bit(0), // Macro has parameters (args expected to be passed)
MF_Expects_Body = bit(1), // Expects to assign a braced scope to its body.
MF_Null = 0,
MF_UnderlyingType = GEN_U16_Max,
};
struct PreprocessorMacro
{
StrCached Name;
MacroType Type;
MacroFlags Flags;
};
forceinine
b32 macro_is_functional( PreprocessorMacro macro ) {
return bitfield_is_set( macro->Flags, MF_Functional );
}
forceinline
b32 macro_expects_body( PreprocessorMacro macro ) {
return bitfield_is_set( macro->Flags, MF_Expects_Body );
}

View File

@ -9,7 +9,7 @@ global Context* _ctx;
#pragma region Constants #pragma region Constants
global u32 context_counter; global u32 context_counter;
global Str enum_underlying_sig; global PreprocessorMacro enum_underlying_macro;
global Code Code_Global; global Code Code_Global;
global Code Code_Invalid; global Code Code_Invalid;

View File

@ -34,8 +34,8 @@
#endif #endif
#ifndef bit #ifndef bit
#define bit( Value ) ( 1 << Value ) #define bit( Value ) ( 1 << Value )
#define bitfield_is_equal( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) ) #define bitfield_is_set( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) )
#endif #endif
// Mainly intended for forcing the base library to utilize only C-valid constructs or type coercion // Mainly intended for forcing the base library to utilize only C-valid constructs or type coercion

View File

@ -42,6 +42,7 @@ Number, "__number__"
Operator, "__operator__" Operator, "__operator__"
Preprocess_Hash, "#" Preprocess_Hash, "#"
Preprocess_Define, "define" Preprocess_Define, "define"
Preprocess_Define_Param, "__define_param__"
Preprocess_If, "if" Preprocess_If, "if"
Preprocess_IfDef, "ifdef" Preprocess_IfDef, "ifdef"
Preprocess_IfNotDef, "ifndef" Preprocess_IfNotDef, "ifndef"

1 Invalid __invalid__
42 Operator __operator__
43 Preprocess_Hash #
44 Preprocess_Define define
45 Preprocess_Define_Param __define_param__
46 Preprocess_If if
47 Preprocess_IfDef ifdef
48 Preprocess_IfNotDef ifndef

View File

@ -41,7 +41,7 @@
#undef local_persist #undef local_persist
#undef bit #undef bit
#undef bitfield_is_equal #undef bitfield_is_set
#undef cast #undef cast

View File

@ -21,7 +21,7 @@ word global, gen_global
word internal, gen_internal word internal, gen_internal
word local_persist, gen_local_persist word local_persist, gen_local_persist
word bit, gen_bit word bit, gen_bit
word bitfield_is_equal, gen_bitfield_is_equal word bitfield_is_set, gen_bitfield_is_set
word cast, gen_cast word cast, gen_cast
word ccast, gen_ccast word ccast, gen_ccast
word pcast, gen_pcast word pcast, gen_pcast