Compare commits

...

4 Commits

24 changed files with 1041 additions and 752 deletions

View File

@ -36,7 +36,6 @@ Str code_debug_str(Code self)
case CT_Execution:
case CT_Comment:
case CT_PlatformAttributes:
case CT_Preprocess_Define:
case CT_Preprocess_Include:
case CT_Preprocess_Pragma:
case CT_Preprocess_If:
@ -52,6 +51,11 @@ Str code_debug_str(Code self)
strbuilder_append_fmt( result, "\n\tContent: %S", self->Content );
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_Struct:
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") );
break;
case CT_Parameters_Define:
// TODO(ED): Needs implementaton
log_failure("code_debug_str: NOT IMPLEMENTED for CT_Parameters_Define");
break;
case CT_Specifiers:
{
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 );
break;
case CT_Parameters_Define:
define_params_to_strbuilder_ref(cast(CodeDefineParams, self), result);
break;
case CT_Preprocess_Define:
define_to_strbuilder_ref(cast(CodeDefine, self), result );
break;
@ -987,11 +1000,17 @@ bool code_is_equal( Code self, Code other )
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:
{
check_member_str( Name );
check_member_content( Content );
check_member_content( Body->Content );
return true;
}

View File

@ -151,7 +151,7 @@ struct AST_Define
char _PAD_PROPERTIES_ [ sizeof(AST*) * 4 ];
CodeDefineParams Params;
Code Body; // Should be completely serialized for now to a: StrCached Content.
char _PAD_PROPERTIES_ [ sizeof(AST*) * 1 ];
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 1 ];
};
};
StrCached Name;

View File

@ -176,7 +176,7 @@ void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
{
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("class ") );
@ -221,7 +221,7 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result )
{
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 ") );
if ( self->Attributes )
@ -241,12 +241,48 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result )
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 )
{
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 self, 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 ( CodeDefineParams param = begin_CodeDefineParams(self->Next); param != end_CodeDefineParams(self->Next); param = next_CodeDefineParams(self->Next, param) )
{
strbuilder_append_fmt( result, ", %SB", define_params_to_strbuilder(param) );
}
}
}
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 )
{
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
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 )
{
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
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 )
{
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
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 )
{
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("enum class ") );
@ -505,7 +541,7 @@ StrBuilder fn_to_strbuilder(CodeFn self)
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") );
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 )
{
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
if ( self->Attributes )
@ -646,7 +682,7 @@ StrBuilder namespace_to_strbuilder(CodeNS self)
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_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 )
{
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
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 )
{
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
if ( self->Attributes )
@ -865,7 +901,6 @@ void opcast_to_strbuilder_fwd(CodeOpCast self, StrBuilder* result )
StrBuilder params_to_strbuilder(CodeParams self)
{
GEN_ASSERT(self);
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
params_to_strbuilder_ref( self, & result );
@ -1030,7 +1065,7 @@ void struct_to_strbuilder_def( CodeStruct self, StrBuilder* result )
{
GEN_ASSERT(self);
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("struct ") );
@ -1076,7 +1111,7 @@ void struct_to_strbuilder_fwd( CodeStruct self, StrBuilder* result )
{
GEN_ASSERT(self);
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 ") );
if ( self->Attributes )
@ -1105,7 +1140,7 @@ void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result )
{
GEN_ASSERT(self);
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 ") );
if ( self->Params )
@ -1123,7 +1158,7 @@ StrBuilder typedef_to_strbuilder(CodeTypedef self)
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("typedef "));
@ -1236,7 +1271,7 @@ StrBuilder union_to_strbuilder(CodeUnion self)
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("union ") );
@ -1267,7 +1302,7 @@ void union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result )
{
GEN_ASSERT(self);
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("union ") );
@ -1304,7 +1339,7 @@ void using_to_strbuilder_ref(CodeUsing self, StrBuilder* result )
{
GEN_ASSERT(self);
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 ") );
if ( self->Attributes )
@ -1401,7 +1436,7 @@ void var_to_strbuilder_ref(CodeVar self, StrBuilder* result )
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 ") );
if ( self->Attributes || self->Specs )

View File

@ -202,7 +202,7 @@ struct CodeParams
{
#if ! GEN_C_LIKE_CPP
Using_Code( CodeParams );
forceinline void append( CodeParams other ) { return params_append(* this, other) }
forceinline void append( CodeParams other ) { return params_append(* this, other); }
forceinline CodeParams get( s32 idx ) { return params_get( * this, idx); }
forceinline bool has_entries() { return params_has_entries(* this); }
forceinline StrBuilder to_strbuilder() { return params_to_strbuilder(* this); }
@ -225,22 +225,22 @@ struct CodeDefineParams
{
#if ! GEN_C_LIKE_CPP
Using_Code( CodeDefineParams );
forceinline void append( CodeDefineParams other ) { return params_append( cast(CodeParams, * this), other) }
forceinline CodeDefineParams get( s32 idx ) { return params_get( cast(CodeParams, * this), idx); }
forceinline void append( CodeDefineParams other ) { return params_append( cast(CodeParams, * this), cast(CodeParams, other)); }
forceinline CodeDefineParams get( s32 idx ) { return (CodeDefineParams) (Code) params_get( cast(CodeParams, * this), idx); }
forceinline bool has_entries() { return params_has_entries( cast(CodeParams, * this)); }
forceinline StrBuilder to_strbuilder() { return define_params_to_strbuilder(* this); }
forceinline void to_strbuilder( StrBuilder& result ) { return define_params_to_strbuilder_ref(* this, & result); }
#endif
Using_CodeOps( CodeDefineParams );
forceinline CodeDefineParams begin() { return begin_CodeParams( cast(CodeParams, * this)); }
forceinline CodeDefineParams end() { return end_CodeParams( cast(CodeParams, * this)); }
forceinline CodeDefineParams begin() { return (CodeDefineParams) (Code) begin_CodeParams( cast(CodeParams, * this)); }
forceinline CodeDefineParams end() { return (CodeDefineParams) (Code) end_CodeParams( cast(CodeParams, * this)); }
forceinline operator Code() { return { (AST*)ast }; }
forceinline CodeDefineParams operator *() { return * this; } // Required to support for-range iteration.
forceinline AST_DefineParams* operator->() {
GEN_ASSERT(ast);
return ast;
}
forceinline CodeDefineParams& operator++() { return cast(CodeParams, * this).operator ++() };
forceinline CodeDefineParams& operator++();
AST_DefineParams* ast;
};
@ -1058,9 +1058,9 @@ forceinline StrBuilder to_strbuilder ( CodeClass self )
forceinline void to_strbuilder_def( CodeClass self, StrBuilder& result ) { return class_to_strbuilder_def(self, & result); }
forceinline void to_strbuilder_fwd( CodeClass self, StrBuilder& result ) { return class_to_strbuilder_fwd(self, & result); }
forceinline void append (CodeDefineParams appendee, CodeDefineParams other ) { return params_append(cast(CodeParam, appendee), other); }
forceinline CodeDefineParams get (CodeDefineParams params, s32 idx) { return params_get(cast(CodeParam, params), idx); }
forceinline bool has_entries (CodeDefineParams params ) { return params_has_entries(cast(CodeParam, params)); }
forceinline void append (CodeDefineParams appendee, CodeDefineParams other ) { params_append(cast(CodeParams, appendee), cast(CodeParams, other)); }
forceinline CodeDefineParams get (CodeDefineParams params, s32 idx) { return (CodeDefineParams) (Code) params_get(cast(CodeParams, params), idx); }
forceinline bool has_entries (CodeDefineParams params ) { return params_has_entries(cast(CodeParams, params)); }
forceinline StrBuilder to_strbuilder(CodeDefineParams params ) { return define_params_to_strbuilder(params); }
forceinline void to_strbuilder(CodeDefineParams params, StrBuilder& result ) { return define_params_to_strbuilder_ref(params, & result); }

View File

@ -179,6 +179,22 @@ inline AST_Define* CodeDefine::operator->()
return ast;
}
inline CodeDefineParams& CodeDefineParams::operator=( Code other )
{
if ( other.ast != nullptr && other->Parent != nullptr )
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
return *this;
}
inline CodeDefineParams::operator bool()
{
return ast != nullptr;
}
inline CodeDestructor& CodeDestructor::operator=( Code other )
{
if ( other.ast != nullptr && other->Parent != nullptr )
@ -851,6 +867,11 @@ forceinline Code::operator CodeDefine() const
return { (AST_Define*)ast };
}
forceinline Code::operator CodeDefineParams() const
{
return { (AST_DefineParams*)ast };
}
forceinline Code::operator CodeDestructor() const
{
return { (AST_Destructor*)ast };

View File

@ -46,6 +46,7 @@ enum CodeType : u32
CT_Operator_Cast,
CT_Operator_Cast_Fwd,
CT_Parameters,
CT_Parameters_Define,
CT_Preprocess_Define,
CT_Preprocess_Include,
CT_Preprocess_If,
@ -74,7 +75,7 @@ enum CodeType : u32
inline Str codetype_to_str( CodeType type )
{
local_persist Str lookup[61] = {
local_persist Str lookup[] = {
{ "Invalid", sizeof( "Invalid" ) - 1 },
{ "Untyped", sizeof( "Untyped" ) - 1 },
{ "NewLine", sizeof( "NewLine" ) - 1 },
@ -114,6 +115,7 @@ inline Str codetype_to_str( CodeType type )
{ "Operator_Cast", sizeof( "Operator_Cast" ) - 1 },
{ "Operator_Cast_Fwd", sizeof( "Operator_Cast_Fwd" ) - 1 },
{ "Parameters", sizeof( "Parameters" ) - 1 },
{ "Parameters_Define", sizeof( "Parameters_Define" ) - 1 },
{ "Preprocess_Define", sizeof( "Preprocess_Define" ) - 1 },
{ "Preprocess_Include", sizeof( "Preprocess_Include" ) - 1 },
{ "Preprocess_If", sizeof( "Preprocess_If" ) - 1 },
@ -142,7 +144,7 @@ inline Str codetype_to_str( CodeType type )
inline Str codetype_to_keyword_str( CodeType type )
{
local_persist Str lookup[61] = {
local_persist Str lookup[] = {
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
@ -182,6 +184,7 @@ inline Str codetype_to_keyword_str( CodeType type )
{ "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "define", sizeof( "define" ) - 1 },
{ "include", sizeof( "include" ) - 1 },
{ "if", sizeof( "if" ) - 1 },

View File

@ -60,7 +60,7 @@ enum Operator : u32
inline Str operator_to_str( Operator op )
{
local_persist Str lookup[47] = {
local_persist Str lookup[] = {
{ "INVALID", sizeof( "INVALID" ) - 1 },
{ "=", sizeof( "=" ) - 1 },
{ "+=", sizeof( "+=" ) - 1 },

View File

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

View File

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

View File

@ -259,12 +259,21 @@ CodeParams next_CodeParams(CodeParams params, CodeParams param_iter)
#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 params_get( cast(CodeParams, self), idx); }
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)); }
CodeDefineParams begin_CodeDefineParams(CodeDefineParams params) { return begin_CodeParams( cast(CodeParams, params)); }
CodeDefineParams end_CodeDefineParams (CodeDefineParams params) { return end_CodeParams ( cast(CodeParams, params)); }
CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter) { return next_CodeParams ( cast(CodeParams, params), cast(CoeParams, entry_iter)); }
CodeDefineParams begin_CodeDefineParams(CodeDefineParams params) { return (CodeDefineParams) (Code) begin_CodeParams( cast(CodeParams, (Code)params)); }
CodeDefineParams end_CodeDefineParams (CodeDefineParams params) { return (CodeDefineParams) (Code) end_CodeParams ( cast(CodeParams, (Code)params)); }
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

View File

@ -206,10 +206,12 @@ void define_constants()
spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
code_set_global(cast(Code, spec_local_persist));
if (enum_underlying_sig.Len == 0) {
enum_underlying_sig = txt("enum_underlying(");
if (enum_underlying_macro.Name.Len == 0) {
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)
@ -270,8 +272,8 @@ void init(Context* ctx)
ctx->CodePool_NumBlocks = kilobytes(16);
}
if (ctx->InitSize_LexArena == 0 ) {
ctx->InitSize_LexArena = megabytes(4);
if (ctx->InitSize_LexerTokens == 0 ) {
ctx->InitSize_LexerTokens = kilobytes(64);
}
if (ctx->SizePer_StringArena == 0) {
ctx->SizePer_StringArena = megabytes(1);
@ -301,9 +303,6 @@ void init(Context* ctx)
GEN_FATAL( "gen::init: Failed to initialize the 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
Arena strbuilder_arena = arena_init_from_allocator( ctx->Allocator_StrCache, ctx->SizePer_StringArena );
if ( strbuilder_arena.PhysicalStart == nullptr )
@ -315,9 +314,12 @@ void init(Context* ctx)
ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers);
if ( ctx->StrCache.Entries == nullptr )
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
ctx->PreprocessorMacros = hashtable_init(PreprocessorMacro, 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();
parser_init();
@ -354,9 +356,7 @@ void deinit(Context* ctx)
array_free( ctx->CodePools);
array_free( ctx->StringArenas);
// arena_free(& ctx->LexArena);
array_free(ctx->PreprocessorDefines);
hashtable_destroy(ctx->PreprocessorMacros);
left = array_num( ctx->Fallback_AllocatorBuckets);
if (left)
@ -401,6 +401,7 @@ void reset(Context* ctx)
while ( left--, left );
hashtable_clear(ctx->StrCache);
hashtable_clear(ctx->PreprocessorMacros);
define_constants();
}
@ -469,6 +470,42 @@ PreprocessorMacro* lookup_preprocess_macro( Str name ) {
}
void register_preprocess_macro( PreprocessorMacro macro ) {
GEN_ASSERT_NOT_NULL(macro.Name.Ptr);
GEN_ASSERT(macro.Name.Len > 0);
u32 key = crc32( macro.Name.Ptr, macro.Name.Len );
hashtable_set( _ctx->PreprocessorMacros, key, macro );
}
void register_preprocess_macros( s32 num, ... )
{
GEN_ASSERT(num > 0);
va_list va;
va_start(va, num);
do
{
PreprocessorMacro macro = va_arg(va, PreprocessorMacro);
GEN_ASSERT_NOT_NULL(macro.Name.Ptr);
GEN_ASSERT(macro.Name.Len > 0);
u32 key = crc32( macro.Name.Ptr, macro.Name.Len );
hashtable_set( _ctx->PreprocessorMacros, key, macro );
}
while (num--, num > 0);
va_end(va);
}
void register_preprocess_macros( s32 num, PreprocessorMacro* macros )
{
GEN_ASSERT(num > 0);
do
{
PreprocessorMacro macro = * macros;
GEN_ASSERT_NOT_NULL(macro.Name.Ptr);
GEN_ASSERT(macro.Name.Len > 0);
u32 key = crc32( macro.Name.Ptr, macro.Name.Len );
hashtable_set( _ctx->PreprocessorMacros, key, macro );
++ macros;
}
while (num--, num > 0);
}

View File

@ -60,7 +60,7 @@ struct Context
u32 CodePool_NumBlocks;
// TODO(Ed): Review these... (No longer needed if using the proper allocation strategy)
u32 InitSize_LexArena;
u32 InitSize_LexerTokens;
u32 SizePer_StringArena;
// TODO(Ed): Symbol Table
@ -87,9 +87,6 @@ struct Context
StringTable StrCache;
// TODO(Ed): This needs to be just handled by a parser context
// Arena LexArena;
// StringTable Lexer_defines;
Array(Token) Lexer_Tokens;
// TODO(Ed): Active parse context vs a parse result need to be separated conceptually
@ -109,14 +106,18 @@ GEN_API void reset(Context* ctx);
GEN_API void set_context(Context* ctx);
// Mostly used to verify a macro entry exists for the given name
GEN_API PreprocessMacro* lookup_preprocess_macro( Str Name );
// Mostly intended for the parser
GEN_API PreprocessorMacro* lookup_preprocess_macro( Str Name );
// Alternative way to add a preprocess define entry for the lexer & parser to utilize
// if the user doesn't want to use def_define
// Macros are tracked by name so if the name already exists the entry will be overwritten.
GEN_API void register_preprocess_macro( PreprocessorMacro macro );
// Ease of use batch registration
GEN_API void register_preprocess_macros( s32 num, ... );
GEN_API void register_preprocess_macros( s32 num, PreprocessorMacro* macros );
// Used internally to retrive or make string allocations.
// Strings are stored in a series of string arenas of fixed size (SizePer_StringArena)
GEN_API StrCached cache_str( Str str );
@ -154,8 +155,9 @@ struct Opts_def_constructor {
GEN_API CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT );
struct Opts_def_define {
MacroFlags flags;
CodeDefineParams params;
Str content;
MacroFlags flags;
b32 dont_register_to_preprocess_macros;
};
GEN_API CodeDefine def_define( Str name, MacroType type, Opts_def_define opts GEN_PARAM_DEFAULT );
@ -271,6 +273,8 @@ GEN_API CodeBody def_body( CodeType type );
GEN_API CodeBody def_class_body ( s32 num, ... );
GEN_API CodeBody def_class_body ( s32 num, Code* codes );
GEN_API CodeDefineParams def_define_params ( s32 num, ... );
GEN_API CodeDefineParams def_define_params ( s32 num, CodeDefineParams* codes );
GEN_API CodeBody def_enum_body ( s32 num, ... );
GEN_API CodeBody def_enum_body ( s32 num, Code* codes );
GEN_API CodeBody def_export_body ( s32 num, ... );

View File

@ -516,7 +516,6 @@ CodeClass def_class( Str name, Opts_def_struct p )
GEN_DEBUG_TRAP();
return InvalidCode;
}
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) );
GEN_DEBUG_TRAP();
@ -532,6 +531,9 @@ CodeClass def_class( Str name, Opts_def_struct p )
result = (CodeClass) make_code();
result->Name = cache_str( name );
result->ModuleFlags = p.mflags;
result->Attributes = p.attributes;
result->ParentAccess = p.parent_access;
result->ParentType = p.parent;
if ( p.body )
{
switch ( p.body->Type )
@ -552,44 +554,32 @@ CodeClass def_class( Str name, Opts_def_struct p )
else {
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++ ) {
class_add_interface(result, p.interfaces[idx] );
}
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 ) ) {
GEN_DEBUG_TRAP();
return InvalidCode;
}
CodeDefine
result = (CodeDefine) make_code();
result->Type = CT_Preprocess_Define;
result->Name = cache_str( name );
if ( content.Len <= 0 || content.Ptr == nullptr )
result->Content = cache_str( txt("") );
result->Params = p.params;
if ( p.content.Len <= 0 || p.content.Ptr == nullptr )
result->Body = untyped_str( txt("\n") );
else
result->Content = cache_str( strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S\n", content)) );
result->Body = untyped_str( strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S\n", p.content)) );
b32 append_preprocess_defines = ! p.dont_append_preprocess_defines;
if ( append_preprocess_defines ) {
// Add the define to PreprocessorDefines for usage in parsing
s32 lex_id_len = 0;
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) );
b32 register_define = ! p.dont_register_to_preprocess_macros;
if ( register_define ) {
PreprocessorMacro macro_entry = { result->Name, type, p.flags };
register_preprocess_macro(macro_entry);
}
return result;
}
@ -1410,6 +1400,67 @@ CodeBody def_class_body( s32 num, Code* codes )
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, ... )
{
def_body_start( def_enum_body );

View File

@ -112,6 +112,158 @@ void lexer_end_line( LexContext* 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();
while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) ) {
move_forward();
name.Text.Len++;
}
Specifier spec = str_to_specifier( name.Text );
TokType attrib = str_to_toktype( name.Text );
b32 not_specifier = spec == Spec_Invalid;
b32 not_attribute = attrib <= Tok___Attributes_Start;
PreprocessorMacro macro = { name.Text, MT_Statement, (MacroFlags)0 };
PreprocessorMacro* registered_macro = lookup_preprocess_macro(name.Text);
if ( registered_macro == nullptr && not_specifier && not_attribute ) {
log_fmt("Warning: '%S' was not registered before the lexer processed its #define directive, it will be registered as a statement macro\n"
, name.Text
);
GEN_DEBUG_TRAP();
}
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\n"
, name.Text
);
GEN_DEBUG_TRAP();
}
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();
Token last_parameter;
// We need to tokenize the define's arguments now:
while( ctx->left && * ctx->scanner != ')')
{
skip_whitespace();
Str possible_varadic = { ctx->scanner, 3 };
if ( ctx->left > 3 && str_are_equal( txt("..."), possible_varadic ) ) {
Token parameter = { { ctx->scanner, 3 }, Tok_Preprocess_Define_Param, ctx->line, ctx->column, TF_Preprocess };
move_forward();
move_forward();
move_forward();
array_append(_ctx->Lexer_Tokens, parameter);
skip_whitespace();
last_parameter = parameter;
while ( (* ctx->scanner) == '\\' ) {
move_forward();
skip_whitespace();
}
if (* ctx->scanner != ')' )
{
log_failure("lex_preprocessor_define(%d, %d): Expected a ')' after '...' (varaidc macro param) %S\n"
, ctx->line
, ctx->column
, name.Text
);
return Lex_ReturnNull;
}
break;
}
else if ( (* ctx->scanner) == '\\' ) {
move_forward();
skip_whitespace();
continue;
}
else 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();
last_parameter = parameter;
}
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;
}
if (* ctx->scanner == ')' )
break;
// 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
, last_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
, last_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();
}
else if ( registered_macro && macro_is_functional( * registered_macro) ) {
if (registered_macro && ! macro_is_functional(* registered_macro)) {
log_fmt("Warning: %S registered macro is flagged as functional yet the definition detects no opening parenthesis '(' for arguments\n"
, name.Text
);
GEN_DEBUG_TRAP();
}
}
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
s32 lex_preprocessor_directive( LexContext* ctx )
{
@ -215,31 +367,9 @@ s32 lex_preprocessor_directive( LexContext* ctx )
if ( ctx->token.Type == Tok_Preprocess_Define )
{
Token name = { { ctx->scanner, 0 }, Tok_Identifier, ctx->line, ctx->column, TF_Preprocess };
name.Text.Ptr = ctx->scanner;
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) );
u32 result = lex_preprocessor_define(ctx); // handles: #define <name>( <params> ) - define's content handled later on within this scope.
if (result != Lex_Continue)
return Lex_ReturnNull;
}
Token preprocess_content = { { ctx->scanner, 0 }, Tok_Preprocess_Content, ctx->line, ctx->column, TF_Preprocess };
@ -289,7 +419,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
s32 within_string = false;
s32 within_char = false;
// SkipWhitespace();
// Consume preprocess content
while ( ctx->left )
{
if ( (* ctx->scanner) == '"' && ! within_char )
@ -325,6 +455,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
, (* ctx->scanner), ctx->line, ctx->column
, directive_str, preprocess_content.Line, preprocess_content.Column
, content_str );
return Lex_ReturnNull;
break;
}
}
@ -352,30 +483,24 @@ s32 lex_preprocessor_directive( LexContext* ctx )
forceinline
void lex_found_token( LexContext* ctx )
{
if ( ctx->token.Type != Tok_Invalid )
{
if ( ctx->token.Type != Tok_Invalid ) {
array_append( _ctx->Lexer_Tokens, ctx->token );
return;
}
TokType type = str_to_toktype( tok_to_str(ctx->token) );
if (type <= Tok_Access_Public && type >= Tok_Access_Private )
{
if (type <= Tok_Access_Public && type >= Tok_Access_Private ) {
ctx->token.Flags |= TF_AccessSpecifier;
}
if ( type > Tok___Attributes_Start )
{
if ( type > Tok___Attributes_Start ) {
ctx->token.Flags |= TF_Attribute;
}
if ( type == Tok_Decl_Extern_Linkage )
{
skip_whitespace();
if ( (* ctx->scanner) != '"' )
{
if ( (* ctx->scanner) != '"' ) {
type = Tok_Spec_Extern;
ctx->token.Flags |= TF_Specifier;
}
@ -384,7 +509,6 @@ void lex_found_token( LexContext* ctx )
array_append( _ctx->Lexer_Tokens, ctx->token );
return;
}
if ( ( type <= Tok_Star && type >= Tok_Spec_Alignas)
|| type == Tok_Ampersand
|| type == Tok_Ampersand_DBL )
@ -394,8 +518,6 @@ void lex_found_token( LexContext* ctx )
array_append( _ctx->Lexer_Tokens, ctx->token );
return;
}
if ( type != Tok_Invalid )
{
ctx->token.Type = type;
@ -403,20 +525,17 @@ void lex_found_token( LexContext* ctx )
return;
}
u64 key = 0;
if ( (* ctx->scanner) == '(')
key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len + 1 );
else
key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len );
Str* define = hashtable_get(ctx->defines, key );
if ( define )
PreprocessorMacro* macro = lookup_preprocess_macro( ctx->token.Text );
if ( macro )
{
ctx->token.Type = Tok_Preprocess_Macro;
ctx->token.Type = macrotype_to_toktype(macro->Type);
// TODO(Ed): When we introduce a macro AST (and expression support), we'll properly lex this section.
// Want to ignore any arguments the define may have as they can be execution expressions.
if ( ctx->left && (* ctx->scanner) == '(' )
{
ctx->token.Flags |= TF_Macro_Functional;
move_forward();
ctx->token.Text.Len++;
@ -436,7 +555,6 @@ void lex_found_token( LexContext* ctx )
move_forward();
ctx->token.Text.Len++;
}
//if ( (* ctx->scanner) == '\r' && ctx->scanner[1] == '\n' )
//{
// move_forward();
@ -456,6 +574,7 @@ void lex_found_token( LexContext* ctx )
array_append( _ctx->Lexer_Tokens, ctx->token );
}
// TODO(Ed): We need to to attempt to recover from a lex failure?
neverinline
// TokArray lex( Array<Token> tokens, Str content )
TokArray lex( Str content )
@ -464,7 +583,6 @@ TokArray lex( Str content )
c.content = content;
c.left = content.Len;
c.scanner = content.Ptr;
c.defines = _ctx->Lexer_defines;
char const* word = c.scanner;
s32 word_length = 0;
@ -480,27 +598,10 @@ TokArray lex( Str content )
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);
b32 preprocess_args = true;
while (c.left )
{
#if 0
@ -942,7 +1043,7 @@ TokArray lex( Str content )
goto FoundToken;
}
// Dash is unfortunatlly a bit more complicated...
// Dash is unfortunately a bit more complicated...
case '-':
{
Str text = { c.scanner, 1 };
@ -1079,8 +1180,7 @@ TokArray lex( Str content )
c.token.Text = text;
move_forward();
while ( c.left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) )
{
while ( c.left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) ) {
move_forward();
c.token.Text.Len++;
}
@ -1106,8 +1206,7 @@ TokArray lex( Str content )
move_forward();
c.token.Text.Len++;
while ( c.left && char_is_hex_digit((* ctx->scanner)) )
{
while ( c.left && char_is_hex_digit((* ctx->scanner)) ) {
move_forward();
c.token.Text.Len++;
}
@ -1115,8 +1214,7 @@ TokArray lex( Str content )
goto FoundToken;
}
while ( c.left && char_is_digit((* ctx->scanner)) )
{
while ( c.left && char_is_digit((* ctx->scanner)) ) {
move_forward();
c.token.Text.Len++;
}
@ -1126,8 +1224,7 @@ TokArray lex( Str content )
move_forward();
c.token.Text.Len++;
while ( c.left && char_is_digit((* ctx->scanner)) )
{
while ( c.left && char_is_digit((* ctx->scanner)) ) {
move_forward();
c.token.Text.Len++;
}
@ -1145,8 +1242,7 @@ TokArray lex( Str content )
c.token.Text.Len++;
// Handle 'll'/'LL' as a special case when we just processed an 'l'/'L'
if (c.left && (prev == 'l' || prev == 'L') && ((* ctx->scanner) == 'l' || (* ctx->scanner) == 'L'))
{
if (c.left && (prev == 'l' || prev == 'L') && ((* ctx->scanner) == 'l' || (* ctx->scanner) == 'L')) {
move_forward();
c.token.Text.Len++;
}
@ -1172,8 +1268,7 @@ TokArray lex( Str content )
log_failure( "Failed to lex token '%c' (%d, %d)\n%s", (* ctx->scanner), c.line, c.column, context_str );
// Skip to next whitespace since we can't know if anything else is valid until then.
while ( c.left && ! char_is_space( (* ctx->scanner) ) )
{
while ( c.left && ! char_is_space( (* ctx->scanner) ) ) {
move_forward();
}
}
@ -1182,16 +1277,14 @@ TokArray lex( Str content )
{
lex_found_token( ctx );
TokType last_type = array_back(_ctx->Lexer_Tokens)->Type;
if ( last_type == Tok_Preprocess_Macro )
if ( last_type == Tok_Preprocess_Macro_Stmt )
{
Token thanks_c = { { c.scanner, 0 }, Tok_Invalid, c.line, c.column, TF_Null };
c.token = thanks_c;
if ( (* ctx->scanner) == '\r')
{
if ( (* ctx->scanner) == '\r') {
move_forward();
c.token.Text.Len = 1;
}
if ( (* ctx->scanner) == '\n' )
{
c.token.Type = Tok_NewLine;
@ -1205,18 +1298,16 @@ TokArray lex( Str content )
}
}
if ( array_num(_ctx->Lexer_Tokens) == 0 )
{
if ( array_num(_ctx->Lexer_Tokens) == 0 ) {
log_failure( "Failed to lex any tokens" );
{
TokArray tok_array = {};
return tok_array;
}
}
TokArray result = { _ctx->Lexer_Tokens, 0 };
return result;
}
#undef move_forward
#undef skip_whitespace
#undef end_line

File diff suppressed because it is too large Load Diff

View File

@ -4,36 +4,9 @@
#include "gen/ecode.hpp"
#include "gen/eoperator.hpp"
#include "gen/especifier.hpp"
#include "gen/etoktype.hpp"
#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
{
TF_Operator = bit(0),
@ -82,42 +55,42 @@ bool tok_is_valid( Token tok ) {
forceinline
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
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
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
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
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
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
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
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);
@ -153,3 +126,76 @@ struct ParseContext
TokArray Tokens;
StackNode* Scope;
};
enum MacroType : u16
{
MT_Statement, // A macro is assumed to be a statement if not resolved.
MT_Expression,
MT_Typename,
MT_Attribute, // More of a note to the parser than anythign else (attributes should be defined in the user attribues def).
MT_Specifier, // More of a note to the parser than anythign else (specifiers should be defined in the user attribues def).
MT_Block_Start, // Not Supported yet
MT_Block_End, // Not Supported yet
MT_Case_Statement, // Not Supported yet
MT_UnderlyingType = GEN_U16_MAX,
};
forceinline
TokType macrotype_to_toktype( MacroType type ) {
switch ( type ) {
case MT_Statement : return Tok_Preprocess_Macro_Stmt;
case MT_Expression : return Tok_Preprocess_Macro_Expr;
case MT_Typename : return Tok_Preprocess_Macro_Typename;
}
// All others unsupported for now.
return Tok_Invalid;
}
Str macrotype_to_str( MacroType type )
{
local_persist
Str lookup[] = {
{ "Statement", sizeof("Statement") - 1 },
{ "Expression", sizeof("Expression") - 1 },
{ "Typename", sizeof("Typename") - 1 },
{ "Attribute(Macro)", sizeof("Attribute(Macro)") - 1 },
{ "Specifier(Macro)", sizeof("Specifier(Macro)") - 1 },
{ "Block_Start", sizeof("Block_Start") - 1 },
{ "Block_End", sizeof("Block_End") - 1 },
{ "Case_Statement", sizeof("Case_Statement") - 1 },
};
local_persist
Str invalid = { "Invalid", sizeof("Invalid") };
if ( type > MT_Case_Statement )
return invalid;
return lookup[ type ];
}
enum EMacroFlags : 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,
};
typedef u16 MacroFlags;
struct PreprocessorMacro
{
StrCached Name;
MacroType Type;
MacroFlags Flags;
};
forceinline
b32 macro_is_functional( PreprocessorMacro macro ) {
return bitfield_is_set( b16, macro.Flags, MF_Functional );
}
forceinline
b32 macro_expects_body( PreprocessorMacro macro ) {
return bitfield_is_set( b16, macro.Flags, MF_Expects_Body );
}

View File

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

View File

@ -35,7 +35,7 @@
#ifndef bit
#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
// Mainly intended for forcing the base library to utilize only C-valid constructs or type coercion
@ -248,9 +248,9 @@
# if ! GEN_COMPILER_C
# define typeof decltype
# elif defined(_MSC_VER)
# define typeof(x) __typeof__(x)
# define typeof __typeof__
# elif defined(__GNUC__) || defined(__clang__)
# define typeof(x) __typeof__(x)
# define typeof __typeof__
# else
# error "Compiler not supported"
# endif

View File

@ -42,6 +42,7 @@ Number, "__number__"
Operator, "__operator__"
Preprocess_Hash, "#"
Preprocess_Define, "define"
Preprocess_Define_Param, "__define_param__"
Preprocess_If, "if"
Preprocess_IfDef, "ifdef"
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

@ -47,7 +47,7 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false )
Str codetype_to_str( CodeType type )
{
local_persist
Str lookup[<num>] = {
Str lookup[] = {
<entries>
};
return lookup[ type ];
@ -57,7 +57,7 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false )
Str codetype_to_keyword_str( CodeType type )
{
local_persist
Str lookup[ <num> ] = {
Str lookup[] = {
<keywords>
};
return lookup[ type ];
@ -139,7 +139,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
Str operator_to_str( Operator op )
{
local_persist
Str lookup[<num>] = {
Str lookup[] = {
<entries>
};
@ -353,7 +353,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
#undef GEN_DEFINE_ATTRIBUTE_TOKENS
CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), strbuilder_to_str(attribute_define_entries) );
CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), MT_Statement, { {}, strbuilder_to_str(attribute_define_entries) } );
#pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
// We cannot parse this enum, it has Attribute names as enums
@ -506,6 +506,7 @@ CodeBody gen_ast_inlines()
CodeBody impl_code_constr = parse_global_body( token_fmt( "typename", Str name(CodeConstructor), code_impl_tmpl ));
CodeBody impl_code_class = parse_global_body( token_fmt( "typename", Str name(CodeClass), code_impl_tmpl ));
CodeBody impl_code_define = parse_global_body( token_fmt( "typename", Str name(CodeDefine), code_impl_tmpl ));
CodeBody impl_code_define_params = parse_global_body( token_fmt( "typename", Str name(CodeDefineParams), code_impl_tmpl ));
CodeBody impl_code_destruct = parse_global_body( token_fmt( "typename", Str name(CodeDestructor), code_impl_tmpl ));
CodeBody impl_code_enum = parse_global_body( token_fmt( "typename", Str name(CodeEnum), code_impl_tmpl ));
CodeBody impl_code_exec = parse_global_body( token_fmt( "typename", Str name(CodeExec), code_impl_tmpl ));
@ -569,6 +570,7 @@ CodeBody gen_ast_inlines()
CodeBody impl_cast_constr = parse_global_body( token_fmt( "typename", Str name(Constructor), cast_tmpl ));
CodeBody impl_cast_class = parse_global_body( token_fmt( "typename", Str name(Class), cast_tmpl ));
CodeBody impl_cast_define = parse_global_body( token_fmt( "typename", Str name(Define), cast_tmpl ));
CodeBody impl_cast_define_params = parse_global_body( token_fmt( "typename", Str name(DefineParams), cast_tmpl ));
CodeBody impl_cast_destruct = parse_global_body( token_fmt( "typename", Str name(Destructor), cast_tmpl ));
CodeBody impl_cast_enum = parse_global_body( token_fmt( "typename", Str name(Enum), cast_tmpl ));
CodeBody impl_cast_exec = parse_global_body( token_fmt( "typename", Str name(Exec), cast_tmpl ));
@ -602,6 +604,7 @@ CodeBody gen_ast_inlines()
impl_code_constr,
impl_code_class,
impl_code_define,
impl_code_define_params,
impl_code_destruct,
impl_code_enum,
impl_code_exec,
@ -636,6 +639,7 @@ CodeBody gen_ast_inlines()
impl_cast_constr,
impl_cast_class,
impl_cast_define,
impl_cast_define_params,
impl_cast_destruct,
impl_cast_enum,
impl_cast_exec,

View File

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

View File

@ -21,7 +21,7 @@ word global, gen_global
word internal, gen_internal
word local_persist, gen_local_persist
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 ccast, gen_ccast
word pcast, gen_pcast

View File

@ -51,7 +51,9 @@ Preprocess_EndIf, "endif"
Preprocess_Include, "include"
Preprocess_Pragma, "pragma"
Preprocess_Content, "__macro_content__"
Preprocess_Macro, "__macro__"
Preprocess_Macro_Expr, "__macro_expression__"
Preprocess_Macro_Stmt, "__macro_statment__"
Preprocess_Macro_Typename, "__macro_typename__"
Preprocess_Unsupported, "__unsupported__"
Spec_Alignas, "alignas"
Spec_Const, "const"

1 Invalid __invalid__
51 Preprocess_Include include
52 Preprocess_Pragma pragma
53 Preprocess_Content __macro_content__
54 Preprocess_Macro Preprocess_Macro_Expr __macro__ __macro_expression__
55 Preprocess_Macro_Stmt __macro_statment__
56 Preprocess_Macro_Typename __macro_typename__
57 Preprocess_Unsupported __unsupported__
58 Spec_Alignas alignas
59 Spec_Const const

View File

@ -64,6 +64,45 @@ int gen_main()
Code ue_forceinline = code_str(FORCEINLINE);
// Code
register_preprocess_macros( args(
(PreprocessorMacro { txt("bit"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("bitfield_is_set"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("GEN_C_LIKE_CPP"), MT_Expression, MF_Null }),
(PreprocessorMacro { txt("cast"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("ccast"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("rcast"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("pcast"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("scast"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("stringize_va"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("stringize"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("do_once"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("do_once_defer"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("do_once_start"), MT_Statement, MF_Null }),
(PreprocessorMacro { txt("do_once_end"), MT_Statement, MF_Null }),
(PreprocessorMacro { txt("labeled_scope_start"), MT_Statement, MF_Null }),
(PreprocessorMacro { txt("labeled_scope_end"), MT_Statement, MF_Null }),
(PreprocessorMacro { txt("compiler_decorated_func_name"), MT_Expression, MF_Null }),
(PreprocessorMacro { txt("num_args_impl"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("num_args"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("count_of"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("clamp"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("is_between"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("size_of"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("min"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("max"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("offset_of"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("static_assert"), MT_Statement, MF_Functional }),
(PreprocessorMacro { txt("typeof"), MT_Expression, MF_Null }),
(PreprocessorMacro { txt("GEN_API_C_BEGIN"), MT_Statement, MF_Null }),
(PreprocessorMacro { txt("GEN_API_C_END"), MT_Statement, MF_Null }),
(PreprocessorMacro { txt("nullptr"), MT_Expression, MF_Null }),
(PreprocessorMacro { txt("GEN_REMOVE_PTR"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("GEN_PARAM_DEFAULT"), MT_Expression, MF_Null }),
(PreprocessorMacro { txt("struct_init"), MT_Expression, MF_Functional }),
(PreprocessorMacro { txt("GEN_OPTIMIZE_MAPPINGS_BEGIN"), MT_Statement, MF_Null }),
(PreprocessorMacro { txt("GEN_OPITMIZE_MAPPINGS_END"), MT_Statement, MF_Null })
));
// gen_dep.hpp
{
CodeBody macros = def_body( CT_Global_Body );