parser: added support for enum_underlying macro

This commit is contained in:
Edward R. Gonzalez 2024-12-06 00:33:53 -05:00
parent ec07c70dcf
commit 46562d54e7
10 changed files with 214 additions and 169 deletions

View File

@ -10,7 +10,7 @@
<IsVirtual>false</IsVirtual>
<IsFolder>false</IsFolder>
<BuildCommand>pwsh ./scripts/build.ps1 msvc debug bootstrap</BuildCommand>
<RebuildCommand></RebuildCommand>
<RebuildCommand>pwsh ./scripts/build.ps1 msvc debug c_library</RebuildCommand>
<BuildFileCommand></BuildFileCommand>
<CleanCommand>pwsh ./scripts/clean.ps1</CleanCommand>
<BuildWorkingDirectory></BuildWorkingDirectory>

View File

@ -559,7 +559,11 @@ void to_string( Code self, String* result )
break;
case CT_Union:
to_string( cast(CodeUnion, self), result );
to_string_def( cast(CodeUnion, self), result );
break;
case CT_Union_Fwd:
to_string_fwd( cast(CodeUnion, self), result );
break;
case CT_Using:
@ -778,6 +782,7 @@ bool is_equal( Code self, Code other )
check_member_ast( Attributes );
check_member_ast( UnderlyingType );
check_member_ast( Body );
check_member_ast( UnderlyingTypeMacro );
return true;
}
@ -789,6 +794,7 @@ bool is_equal( Code self, Code other )
check_member_str( Name );
check_member_ast( Attributes );
check_member_ast( UnderlyingType );
check_member_ast( UnderlyingTypeMacro );
return true;
}
@ -1058,6 +1064,13 @@ bool is_equal( Code self, Code other )
return true;
}
case CT_Union_Fwd:
{
check_member_val( ModuleFlags );
check_member_str( Name );
check_member_ast( Attributes );
}
case CT_Using:
case CT_Using_Namespace:

View File

@ -155,6 +155,7 @@ Define_Code(Var);
GEN_NS_PARSER_BEGIN
struct Token;
GEN_NS_PARSER_END
typedef struct GEN_NS_PARSER Token Token;
#if ! GEN_COMPILER_C
template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( Type*, & self ); }
@ -319,9 +320,10 @@ struct AST
Code ValueType; // Parameter, Variable
};
union {
Code Macro; // Parameter
Code BitfieldSize; // Variable (Class/Struct Data Member)
Code Params; // Constructor, Function, Operator, Template, Typename
Code Macro; // Parameter
Code BitfieldSize; // Variable (Class/Struct Data Member)
Code Params; // Constructor, Function, Operator, Template, Typename
Code UnderlyingTypeMacro; // Enum
};
union {
Code ArrExpr; // Typename
@ -363,7 +365,6 @@ struct AST
AccessSpec ParentAccess;
s32 NumEntries;
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
b32 EnumUnderlyingMacro; // Used by enums incase the user wants to wrap underlying type specification in a macro
};
};
static_assert( sizeof(AST) == AST_POD_Size, "ERROR: AST POD is not size of AST_POD_Size" );

View File

@ -15,7 +15,7 @@ struct AST_Body
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
Code Front;
Code Back;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -32,7 +32,7 @@ struct AST_Attributes
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -48,7 +48,7 @@ struct AST_BaseClass
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -65,10 +65,10 @@ struct AST_Comment
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
CodeType Type;
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
};
static_assert( sizeof(AST_Comment) == sizeof(AST), "ERROR: AST_Comment is not the same size as AST");
@ -90,7 +90,7 @@ struct AST_Class
};
CodeTypename Prev;
CodeTypename Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -116,7 +116,7 @@ struct AST_Constructor
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -132,7 +132,7 @@ struct AST_Define
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -156,7 +156,7 @@ struct AST_Destructor
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -181,12 +181,12 @@ struct AST_Enum
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
ModuleFlag ModuleFlags;
b32 EnumUnderlyingMacro;
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
};
static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST");
@ -198,7 +198,7 @@ struct AST_Exec
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -214,7 +214,7 @@ struct AST_Expr
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -229,7 +229,7 @@ struct AST_Expr_Assign
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -244,7 +244,7 @@ struct AST_Expr_Alignof
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -259,7 +259,7 @@ struct AST_Expr_Binary
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -274,7 +274,7 @@ struct AST_Expr_CStyleCast
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -289,7 +289,7 @@ struct AST_Expr_FunctionalCast
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -304,7 +304,7 @@ struct AST_Expr_CppCast
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -319,7 +319,7 @@ struct AST_Expr_ProcCall
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -334,7 +334,7 @@ struct AST_Expr_Decltype
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -349,7 +349,7 @@ struct AST_Expr_Comma
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -364,7 +364,7 @@ struct AST_Expr_AMS
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -379,7 +379,7 @@ struct AST_Expr_Sizeof
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -394,7 +394,7 @@ struct AST_Expr_Subscript
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -409,7 +409,7 @@ struct AST_Expr_Ternary
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -424,7 +424,7 @@ struct AST_Expr_UnaryPrefix
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -439,7 +439,7 @@ struct AST_Expr_UnaryPostfix
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -454,7 +454,7 @@ struct AST_Expr_Element
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -476,7 +476,7 @@ struct AST_Extern
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -492,7 +492,7 @@ struct AST_Include
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -514,7 +514,7 @@ struct AST_Friend
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -539,7 +539,7 @@ struct AST_Fn
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -553,7 +553,7 @@ struct AST_Module
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -574,7 +574,7 @@ struct AST_NS
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -600,7 +600,7 @@ struct AST_Operator
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -626,7 +626,7 @@ struct AST_OpCast
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -650,7 +650,7 @@ struct AST_Param
};
CodeParam Last;
CodeParam Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -667,7 +667,7 @@ struct AST_Pragma
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -683,7 +683,7 @@ struct AST_PreprocessCond
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -697,7 +697,7 @@ struct AST_Specifiers
CodeSpecifiers NextSpecs;
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -714,7 +714,7 @@ struct AST_Stmt
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -729,7 +729,7 @@ struct AST_Stmt_Break
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -744,7 +744,7 @@ struct AST_Stmt_Case
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -759,7 +759,7 @@ struct AST_Stmt_Continue
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -774,7 +774,7 @@ struct AST_Stmt_Decl
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -789,7 +789,7 @@ struct AST_Stmt_Do
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -804,7 +804,7 @@ struct AST_Stmt_Expr
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -819,7 +819,7 @@ struct AST_Stmt_Else
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -834,7 +834,7 @@ struct AST_Stmt_If
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -849,7 +849,7 @@ struct AST_Stmt_For
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -864,7 +864,7 @@ struct AST_Stmt_Goto
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -879,7 +879,7 @@ struct AST_Stmt_Label
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -894,7 +894,7 @@ struct AST_Stmt_Switch
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -909,7 +909,7 @@ struct AST_Stmt_While
};
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -935,7 +935,7 @@ struct AST_Struct
};
CodeTypename Prev;
CodeTypename Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -958,7 +958,7 @@ struct AST_Template
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -987,7 +987,7 @@ struct AST_Type
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -1014,7 +1014,7 @@ struct AST_Typename
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -1037,7 +1037,7 @@ struct AST_Typedef
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -1061,7 +1061,7 @@ struct AST_Union
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -1085,7 +1085,7 @@ struct AST_Using
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;
@ -1111,7 +1111,7 @@ struct AST_Var
};
Code Prev;
Code Next;
parser::Token* Tok;
Token* Tok;
Code Parent;
StringCached Name;
CodeType Type;

View File

@ -9,7 +9,7 @@ String to_string(CodeAttributes attributes) {
String to_string(CodeBody body)
{
GEN_ASSERT(body.ast != nullptr);
GEN_ASSERT_NOT_NULL(body.ast);
String result = string_make_reserve( GlobalAllocator, 128 );
switch ( body.ast->Type )
{
@ -350,6 +350,8 @@ void to_string_fwd(CodeEnum self, String* result )
if ( self->UnderlyingType )
string_append_fmt( result, "enum %SC : %S", self->Name, to_string(self->UnderlyingType) );
else if (self->UnderlyingTypeMacro)
string_append_fmt( result, "enum %SC : %S", self->Name, to_string(self->UnderlyingTypeMacro) );
else
string_append_fmt( result, "enum %SC", self->Name );
@ -1171,11 +1173,19 @@ void to_string(CodeTypename self, String* result )
String to_string(CodeUnion self)
{
String result = string_make_reserve( GlobalAllocator, 512 );
to_string( self, & result );
switch ( self->Type )
{
case CT_Union:
to_string_def( self, & result );
break;
case CT_Union_Fwd:
to_string_fwd( self, & result );
break;
}
return result;
}
void to_string(CodeUnion self, String* result )
void to_string_def(CodeUnion self, String* result )
{
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
string_append_strc( result, txt("export ") );
@ -1204,6 +1214,25 @@ void to_string(CodeUnion self, String* result )
string_append_strc( result, txt(";\n"));
}
void to_string_fwd(CodeUnion self, String* result )
{
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
string_append_strc( result, txt("export ") );
string_append_strc( result, txt("union ") );
if ( self->Attributes )
string_append_fmt( result, "%S ", to_string(self->Attributes) );
if ( self->Name )
{
string_append_fmt( result, "%SC", self->Name);
}
if ( self->Parent.ast == nullptr || ( self->Parent->Type != CT_Typedef && self->Parent->Type != CT_Variable ) )
string_append_strc( result, txt(";\n"));
}
String to_string(CodeUsing self)
{
String result = string_make_reserve( GlobalAllocator, 128 );

View File

@ -110,7 +110,8 @@ String to_string(CodeTypedef self);
void to_string(CodeTypedef self, String* result);
String to_string(CodeUnion self);
void to_string(CodeUnion self, String* result);
void to_string_def(CodeUnion self, String* result);
void to_string_fwd(CodeUnion self, String* result);
String to_string (CodeUsing op_cast );
void to_string (CodeUsing op_cast, String* result );

View File

@ -63,6 +63,7 @@ enum CodeType_Def : u32
CT_Typedef,
CT_Typename,
CT_Union,
CT_Union_Fwd,
CT_Union_Body,
CT_Using,
CT_Using_Namespace,
@ -130,6 +131,7 @@ inline StrC to_str( CodeType type )
{ sizeof( "Typedef" ), "Typedef" },
{ sizeof( "Typename" ), "Typename" },
{ sizeof( "Union" ), "Union" },
{ sizeof( "Union_Fwd" ), "Union_Fwd" },
{ sizeof( "Union_Body" ), "Union_Body" },
{ sizeof( "Using" ), "Using" },
{ sizeof( "Using_Namespace" ), "Using_Namespace" },

View File

@ -122,7 +122,7 @@ void define_constants()
fmt_newline = make_code();
fmt_newline->Type = CT_NewLine;
set_global(fmt_newline);
pragma_once = (CodePragma) make_code();
pragma_once->Type = CT_Preprocess_Pragma;
pragma_once->Name = get_cached_string( txt("once") );
@ -227,7 +227,7 @@ void define_constants()
# pragma pop_macro("neverinline")
# pragma push_macro("enum_underlying")
array_append(PreprocessorDefines, txt("enum_underlying("));
# pragma pop_macro("enum_underlying")
# undef def_constant_spec

View File

@ -215,7 +215,7 @@ internal Code parse_operator_function_or_variable( bool expects_fu
internal CodePragma parse_pragma ();
internal CodeParam parse_params ( bool use_template_capture = false );
internal CodePreprocessCond parse_preprocess_cond ();
internal Code parse_simple_preprocess ( TokType which );
internal Code parse_simple_preprocess ( TokType which, bool dont_consume_braces = false );
internal Code parse_static_assert ();
internal void parse_template_args ( Token& token );
internal CodeVar parse_variable_after_name ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeTypename type, StrC name );
@ -240,7 +240,8 @@ internal CodeTypedef parse_typedef ();
internal CodeUnion parse_union ( bool inplace_def = false );
internal CodeUsing parse_using ();
constexpr bool inplace_def = true;
constexpr bool inplace_def = true;
constexpr bool dont_consume_braces = true;
// Internal parsing functions
@ -2933,8 +2934,8 @@ CodePreprocessCond parse_preprocess_cond()
return cond;
}
internal inline
Code parse_simple_preprocess( TokType which )
internal
Code parse_simple_preprocess( TokType which, bool dont_consume_braces )
{
// TODO(Ed): We can handle a macro a bit better than this. It's AST can be made more robust..
// Make an AST_Macro, it should have an Name be the macro itself, with the function body being an optional function body node.
@ -2945,7 +2946,7 @@ Code parse_simple_preprocess( TokType which )
eat( which );
// <Macro>
if ( peektok.Type == Tok_BraceCurly_Open )
if ( ! dont_consume_braces && peektok.Type == Tok_BraceCurly_Open )
{
// Eat the block scope right after the macro. Were assuming the macro defines a function definition's signature
eat( Tok_BraceCurly_Open );
@ -2985,7 +2986,11 @@ Code parse_simple_preprocess( TokType which )
}
else
{
if ( str_compare_len( Context.Scope->Prev->ProcName.Ptr, "parse_typedef", Context.Scope->Prev->ProcName.Len ) != 0 )
if (strc_contains(Context.Scope->Prev->ProcName, txt("parse_enum")))
{
// Do nothing
}
else if (strc_contains(Context.Scope->Prev->ProcName, txt("parse_typedef")))
{
if ( peektok.Type == Tok_Statement_End )
{
@ -3614,15 +3619,14 @@ CodeEnum parse_enum( bool inplace_def )
}
// enum <class> <Attributes> <Name> : <UnderlyingType>
}
else if ( currtok.Type == Tok_Preprocess_Define )
else if ( currtok.Type == Tok_Preprocess_Macro )
{
// We'll support the enum_underlying macro
StrC sig = txt("enum_underlying");
if (currtok.Length >= sig.Len && str_compare_len(currtok.Text, sig.Ptr, sig.Len) == 0 )
StrC sig = txt("enum_underlying(");
if ( strc_contains(to_str(currtok), sig) )
{
use_macro_underlying = true;
underlying_macro = parse_simple_preprocess( Tok_Preprocess_Macro);
underlying_macro = parse_simple_preprocess( Tok_Preprocess_Macro, dont_consume_braces );
}
}
@ -3793,14 +3797,8 @@ CodeEnum parse_enum( bool inplace_def )
if ( attributes )
result->Attributes = attributes;
if ( type )
{
result->EnumUnderlyingMacro = use_macro_underlying;
if ( use_macro_underlying )
result->UnderlyingTypeMacro = underlying_macro;
else
result->UnderlyingType = type;
}
result->UnderlyingTypeMacro = underlying_macro;
result->UnderlyingType = type;
if ( inline_cmt )
result->InlineCmt = inline_cmt;
@ -5164,95 +5162,98 @@ CodeUnion parse_union( bool inplace_def )
eat( Tok_Identifier );
}
// <ModuleFlags> union <Attributes> <Name>
CodeBody body = { nullptr };
eat( Tok_BraceCurly_Open );
// <ModuleFlags> union <Attributes> <Name> {
body = make_code();
body->Type = CT_Union_Body;
while ( ! check_noskip( Tok_BraceCurly_Close ) )
if ( ! inplace_def || ! check(Tok_Identifier) )
{
if ( currtok_noskip.Type == Tok_Preprocess_Hash )
eat( Tok_Preprocess_Hash );
eat( Tok_BraceCurly_Open );
// <ModuleFlags> union <Attributes> <Name> {
Code member = { nullptr };
switch ( currtok_noskip.Type )
body = make_code();
body->Type = CT_Union_Body;
while ( ! check_noskip( Tok_BraceCurly_Close ) )
{
case Tok_NewLine:
member = fmt_newline;
eat( Tok_NewLine );
break;
if ( currtok_noskip.Type == Tok_Preprocess_Hash )
eat( Tok_Preprocess_Hash );
case Tok_Comment:
member = parse_comment();
break;
Code member = { nullptr };
switch ( currtok_noskip.Type )
{
case Tok_NewLine:
member = fmt_newline;
eat( Tok_NewLine );
break;
// TODO(Ed) : Unions can have constructors and destructors
case Tok_Comment:
member = parse_comment();
break;
case Tok_Decl_Class:
member = parse_complicated_definition( Tok_Decl_Class );
break;
// TODO(Ed) : Unions can have constructors and destructors
case Tok_Decl_Enum:
member = parse_complicated_definition( Tok_Decl_Enum );
break;
case Tok_Decl_Class:
member = parse_complicated_definition( Tok_Decl_Class );
break;
case Tok_Decl_Struct:
member = parse_complicated_definition( Tok_Decl_Struct );
break;
case Tok_Decl_Enum:
member = parse_complicated_definition( Tok_Decl_Enum );
break;
case Tok_Decl_Union:
member = parse_complicated_definition( Tok_Decl_Union );
break;
case Tok_Decl_Struct:
member = parse_complicated_definition( Tok_Decl_Struct );
break;
case Tok_Preprocess_Define:
member = parse_define();
break;
case Tok_Decl_Union:
member = parse_complicated_definition( Tok_Decl_Union );
break;
case Tok_Preprocess_If:
case Tok_Preprocess_IfDef:
case Tok_Preprocess_IfNotDef:
case Tok_Preprocess_ElIf:
member = parse_preprocess_cond();
break;
case Tok_Preprocess_Define:
member = parse_define();
break;
case Tok_Preprocess_Else:
member = preprocess_else;
eat( Tok_Preprocess_Else );
break;
case Tok_Preprocess_If:
case Tok_Preprocess_IfDef:
case Tok_Preprocess_IfNotDef:
case Tok_Preprocess_ElIf:
member = parse_preprocess_cond();
break;
case Tok_Preprocess_EndIf:
member = preprocess_endif;
eat( Tok_Preprocess_EndIf );
break;
case Tok_Preprocess_Else:
member = preprocess_else;
eat( Tok_Preprocess_Else );
break;
case Tok_Preprocess_Macro:
member = parse_simple_preprocess( Tok_Preprocess_Macro );
break;
case Tok_Preprocess_EndIf:
member = preprocess_endif;
eat( Tok_Preprocess_EndIf );
break;
case Tok_Preprocess_Pragma:
member = parse_pragma();
break;
case Tok_Preprocess_Macro:
member = parse_simple_preprocess( Tok_Preprocess_Macro );
break;
case Tok_Preprocess_Unsupported:
member = parse_simple_preprocess( Tok_Preprocess_Unsupported );
break;
case Tok_Preprocess_Pragma:
member = parse_pragma();
break;
default:
member = parse_variable();
break;
case Tok_Preprocess_Unsupported:
member = parse_simple_preprocess( Tok_Preprocess_Unsupported );
break;
default:
member = parse_variable();
break;
}
if ( member )
append(body, member );
}
if ( member )
append(body, member );
// <ModuleFlags> union <Attributes> <Name> { <Body>
eat( Tok_BraceCurly_Close );
// <ModuleFlags> union <Attributes> <Name> { <Body> }
}
// <ModuleFlags> union <Attributes> <Name> { <Body>
eat( Tok_BraceCurly_Close );
// <ModuleFlags> union <Attributes> <Name> { <Body> }
if ( ! inplace_def )
eat( Tok_Statement_End );
@ -5260,17 +5261,14 @@ CodeUnion parse_union( bool inplace_def )
CodeUnion
result = (CodeUnion) make_code();
result->Type = CT_Union;
result->Type = body ? CT_Union : CT_Union_Fwd;
result->ModuleFlags = mflags;
if ( name )
result->Name = get_cached_string( name );
if ( body )
result->Body = body;
if ( attributes )
result->Attributes = attributes;
result->Body = body;
result->Attributes = attributes;
pop(& Context);
return result;

View File

@ -54,6 +54,7 @@ Template
Typedef
Typename
Union
Union_Fwd
Union_Body
Using
Using_Namespace

1 Invalid
54 Typedef
55 Typename
56 Union
57 Union_Fwd
58 Union_Body
59 Using
60 Using_Namespace