diff --git a/gen_c_library/c_library.cpp b/gen_c_library/c_library.cpp index 46d5fd6..d91baba 100644 --- a/gen_c_library/c_library.cpp +++ b/gen_c_library/c_library.cpp @@ -105,6 +105,7 @@ int gen_main() PreprocessorDefines.append(txt("GEN_API_C_BEGIN")); PreprocessorDefines.append(txt("GEN_API_C_END")); + PreprocessorDefines.append(txt("Array(")); PreprocessorDefines.append(txt("HashTable(")); PreprocessorDefines.append(txt("GEN_NS_PARSER")); PreprocessorDefines.append(txt("GEN_NS_PARSER_BEGIN")); @@ -212,6 +213,8 @@ do \ { b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), body_entry, body, new_body ); if (found) break; + + new_body.append(body_entry); } break; @@ -313,6 +316,8 @@ do \ found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), entry, parsed_header_strings, header_strings); if (found) break; + + header_strings.append(entry); } break; @@ -458,7 +463,10 @@ do \ { case CT_Preprocess_IfDef: { - ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_parsing, header_parsing ); + if (found) break; + + header_parsing.append(entry); } break; @@ -552,9 +560,21 @@ do \ CodeBody types = def_body(CT_Global_Body); for ( Code entry = parsed_types.begin(); entry != parsed_types.end(); ++ entry ) switch(entry->Type) { + case CT_Preprocess_If: + { + b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_types, types ); + if (found) break; + + types.append(entry); + } + break; + case CT_Preprocess_IfDef: { - ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_types, types ); + if (found) break; + + types.append(entry); } break; @@ -614,7 +634,10 @@ do \ { case CT_Preprocess_IfDef: { - ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_ast, ast ); + if (found) break; + + ast.append(entry); } break; @@ -780,7 +803,7 @@ R"(#define AST_ArrSpecs_Cap \ { b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_code_types, code_types ); if (found) { - ++ entry; + ++ entry; // Skip a newline... break; } found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); @@ -926,7 +949,7 @@ R"(#define ( code ) _Generic( (code), \ { case CT_Preprocess_IfDef: { - b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_interface, interface ); if (found) break; interface.append(entry); @@ -983,6 +1006,9 @@ R"(#define ( code ) _Generic( (code), \ fn->Name = get_cached_string(new_name); interface.append(fn); interface.append(fn_macro); + if (entry->Next && entry->Next->Type != CT_NewLine) { + interface.append(fmt_newline); + } handled = true; break; } @@ -1012,7 +1038,10 @@ R"(#define ( code ) _Generic( (code), \ { case CT_Preprocess_IfDef: { - ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_inlines, inlines ); + if (found) break; + + inlines.append(entry); } break; @@ -1045,7 +1074,10 @@ R"(#define ( code ) _Generic( (code), \ { case CT_Preprocess_IfDef: { - ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_end, header_end ); + if (found) break; + + header_end.append(entry); } break; @@ -1094,8 +1126,6 @@ R"(#define ( code ) _Generic( (code), \ Code src_ast_case_macros = scan_file( project_dir "components/ast_case_macros.cpp" ); Code src_code_serialization = scan_file( project_dir "components/code_serialization.cpp" ); Code src_interface = scan_file( project_dir "components/interface.cpp" ); - // Code src_lexer = scan_file( project_dir "components/lexer.cpp" ); - // Code src_parser = scan_file( project_dir "components/parser.cpp" ); Code src_parsing_interface = scan_file( project_dir "components/interface.parsing.cpp" ); Code src_untyped = scan_file( project_dir "components/interface.untyped.cpp" ); @@ -1105,7 +1135,10 @@ R"(#define ( code ) _Generic( (code), \ { case CT_Preprocess_IfDef: { - ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_ast, src_ast ); + if (found) break; + + src_ast.append(entry); } break; @@ -1137,7 +1170,10 @@ R"(#define ( code ) _Generic( (code), \ { case CT_Preprocess_IfDef: { - ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_upfront, src_upfront ); + if (found) break; + + src_upfront.append(entry); } break; @@ -1181,34 +1217,42 @@ R"(#define ( code ) _Generic( (code), \ break; } + // CodeBody hashtable_strc = gen_hashtable(txt("StrC"), txt("HashTable_StrC")); + CodeBody parsed_src_lexer = parse_file( project_dir "components/lexer.cpp" ); CodeBody src_lexer = def_body(CT_Global_Body); - for ( Code entry = parsed_src_ast.begin(); entry != parsed_src_ast.end(); ++ entry ) switch( entry ->Type ) + for ( Code entry = parsed_src_lexer.begin(); entry != parsed_src_lexer.end(); ++ entry ) switch( entry ->Type ) { case CT_Preprocess_IfDef: { - ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_lexer, src_lexer ); + if (found) break; + + src_lexer.append(entry); } break; - CT_Enum: + case CT_Enum: { if (entry->Name.Len) { - convert_cpp_enum_to_c() + convert_cpp_enum_to_c(cast(CodeEnum, entry), src_lexer); + break; } + + src_lexer.append(entry); } break; - CT_Struct: + case CT_Struct: { if ( entry->Name.is_equal(txt("Token"))) { // Add struct Token forward and typedef early. CodeStruct token_fwd = parse_struct(code( struct Token; )); CodeTypedef token_typedef = parse_typedef(code( typedef struct Token Token; )); - header_parsing.append(token_fwd); - header_parsing.append(token_typedef); + src_lexer.append(token_fwd); + src_lexer.append(token_typedef); // Skip typedef since we added it b32 continue_for = true; @@ -1239,12 +1283,29 @@ R"(#define ( code ) _Generic( (code), \ continue; } - CodeTypedef struct_tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))) + CodeTypedef struct_tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); src_lexer.append(entry); src_lexer.append(struct_tdef); } break; + case CT_Variable: + { + CodeVar var = cast(CodeVar, entry); + if (var->Specs && var->Specs.has(Spec_Constexpr) > -1) { + Code define_ver = untyped_str(token_fmt( + "name", var->Name + , "value", var->Value->Content + , "type", var->ValueType.to_string().to_strc() + , "#define () \n" + )); + src_lexer.append(define_ver); + continue; + } + src_lexer.append(entry); + } + break; + default: src_lexer.append(entry); break; @@ -1256,15 +1317,18 @@ R"(#define ( code ) _Generic( (code), \ { case CT_Preprocess_IfDef: { - ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_parser, src_parser ); + if (found) break; + + src_parser.append(entry); } break; case CT_Struct: { CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); - header_memory.append(entry); - header_memory.append(tdef); + src_parser.append(entry); + src_parser.append(tdef); } default: @@ -1419,8 +1483,8 @@ R"(#define ( code ) _Generic( (code), \ header.print( format_code_to_untyped(src_upfront) ); header.print_fmt( "\n#pragma region Parsing\n\n" ); header.print( format_code_to_untyped(etoktype) ); - header.print( lexer ); - // header.print( parser ); + header.print( format_code_to_untyped(src_lexer) ); + header.print( format_code_to_untyped(src_parser) ); // header.print( parsing_interface ); header.print_fmt( "\n#pragma endregion Parsing\n" ); // header.print( untyped ); diff --git a/gen_c_library/components/containers.array.hpp b/gen_c_library/components/containers.array.hpp index e0d8dba..2533fb0 100644 --- a/gen_c_library/components/containers.array.hpp +++ b/gen_c_library/components/containers.array.hpp @@ -23,7 +23,22 @@ CodeBody gen_array_base() Code get_header = untyped_str( txt( "#define array_get_header( self ) ( (ArrayHeader*)( self ) - 1)\n" )); Code type_define = untyped_str( txt( "#define Array(Type) Array_##Type\n")); - return def_global_body( args( fmt_newline, td_header, header, type_define, grow_formula, get_header, fmt_newline ) ); + Code array_begin = def_define(txt("array_begin(array)"), code( (array) )); + Code array_end = def_define(txt("array_end(array)"), code( (array + array_get_header(array)->Num ) )); + Code array_next = def_define(txt("array_next(array, entry)"), code( (entry + 1) )); + + return def_global_body( args( + fmt_newline, + td_header, + header, + type_define, + grow_formula, + get_header, + array_begin, + array_end, + array_next, + fmt_newline + )); }; CodeBody gen_array( StrC type, StrC array_name ) diff --git a/gen_c_library/components/memory.fixed_arena.hpp b/gen_c_library/components/memory.fixed_arena.hpp index 4ae7cf7..b8a5fe4 100644 --- a/gen_c_library/components/memory.fixed_arena.hpp +++ b/gen_c_library/components/memory.fixed_arena.hpp @@ -9,12 +9,12 @@ CodeBody gen_fixed_arenas() result.append(def_pragma(txt("region FixedArena"))); char const* template_struct = stringize( - struct FixedArena__Def + struct FixedArena_ { char memory[]; Arena arena; }; - typedef struct FixedArena__Def FixedArena_; + typedef struct FixedArena_ FixedArena_; ); char const* template_interface = stringize( diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index bdc9910..e6b53ac 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -114,7 +114,7 @@ CodeEnum parse_enum( StrC def ) } Context.Tokens = toks; - return parse_enum(); + return parse_enum( parser_not_inplace_def); } CodeBody parse_export_body( StrC def ) @@ -263,7 +263,7 @@ CodeTypename parse_type( StrC def ) return InvalidCode; Context.Tokens = toks; - return parse_type(); + return parse_type( parser_not_from_template, nullptr); } CodeTypedef parse_typedef( StrC def ) @@ -289,7 +289,7 @@ CodeUnion parse_union( StrC def ) return InvalidCode; Context.Tokens = toks; - return parse_union(); + return parse_union( parser_not_inplace_def); } CodeUsing parse_using( StrC def ) diff --git a/project/components/lexer.cpp b/project/components/lexer.cpp index 9c09e6a..d179a15 100644 --- a/project/components/lexer.cpp +++ b/project/components/lexer.cpp @@ -21,6 +21,7 @@ enum TokFlags : u32 TF_Literal = bit( 12 ), TF_Null = 0, + TF_UnderlyingType = GEN_U32_MAX, }; struct Token @@ -42,7 +43,8 @@ AccessSpec tok_to_access_specifier(Token tok) StrC tok_to_str(Token tok) { - return { tok.Length, tok.Text }; + StrC str = { tok.Length, tok.Text }; + return str; } bool tok_is_valid( Token tok ) @@ -169,9 +171,9 @@ Token* lex_next(TokArray self, bool skip_formatting) return & self.Arr[idx + 1]; } -global Arena_256KB Lexer_defines_map_arena; -global HashTable(StrC) Lexer_defines; -global Array(Token) Lexer_Tokens; +global FixedArena_256KB Lexer_defines_map_arena; +global StringTable Lexer_defines; +global Array(Token) Lexer_Tokens; #define current ( * ctx->scanner ) @@ -228,7 +230,7 @@ struct LexContext char const* scanner; s32 line; s32 column; - HashTable(StrC) defines; + StringTable defines; Token token; }; @@ -593,13 +595,14 @@ TokArray lex( StrC content ) if ( c.left <= 0 ) { log_failure( "gen::lex: no tokens found (only whitespace provided)" ); - return { {}, 0 }; + TokArray null_array = {}; + return null_array; } for ( StringCached* entry = array_begin(PreprocessorDefines); entry != array_end(PreprocessorDefines); entry = array_next(PreprocessorDefines, entry)) { s32 length = 0; - char const* entry_scanner = * entry; + char const* entry_scanner = (*entry).Ptr; while ( entry->Len > length && (char_is_alphanumeric( *entry_scanner ) || *entry_scanner == '_') ) { entry_scanner++; @@ -610,8 +613,8 @@ TokArray lex( StrC content ) length++; } - u64 key = crc32( * entry, length ); - hashtable_set(c.defines, key, (StrC) * entry ); + u64 key = crc32( entry->Ptr, length ); + hashtable_set(c.defines, key, * entry ); } array_clear(Lexer_Tokens); @@ -625,7 +628,10 @@ TokArray lex( StrC content ) } #endif - c.token = { 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 }; + c.token = thanks_c; + } bool is_define = false; @@ -667,7 +673,10 @@ TokArray lex( StrC content ) //TokType last_type = Tokens[array_get_header(Tokens)->Num - 2].Type; //if ( last_type == Tok_Preprocess_Pragma ) { - c.token = { 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 }; + c.token = thanks_c; + } if ( current == '\r') { move_forward(); @@ -688,7 +697,10 @@ TokArray lex( StrC content ) } case Lex_ReturnNull: - return { {}, 0 }; + { + TokArray tok_array = {}; + return tok_array; + } } } case '.': @@ -1291,7 +1303,8 @@ TokArray lex( StrC content ) TokType last_type = array_back(Lexer_Tokens)->Type; if ( last_type == Tok_Preprocess_Macro ) { - c.token = { 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 }; + c.token = thanks_c; if ( current == '\r') { move_forward(); @@ -1314,7 +1327,10 @@ TokArray lex( StrC content ) if ( array_num(Lexer_Tokens) == 0 ) { log_failure( "Failed to lex any tokens" ); - return { {}, 0 }; + { + TokArray tok_array = {}; + return tok_array; + } } hashtable_clear(Lexer_defines); diff --git a/project/components/parser.cpp b/project/components/parser.cpp index d856244..3c8b1ee 100644 --- a/project/components/parser.cpp +++ b/project/components/parser.cpp @@ -9,8 +9,8 @@ GEN_NS_PARSER_BEGIN // TODO(Ed) : Rename ETok_Capture_Start, ETok_Capture_End to Open_Parenthesis adn Close_Parenthesis -constexpr bool dont_skip_formatting = false; -constexpr bool skip_formatting = true; +constexpr bool lex_dont_skip_formatting = false; +constexpr bool lex_skip_formatting = true; struct StackNode { @@ -113,7 +113,7 @@ bool lex__eat(TokArray* self, TokType type ) if ( at_idx.Type != type ) { - Token tok = * lex_current( self, skip_formatting ); + Token tok = * lex_current( self, lex_skip_formatting ); log_failure( "Parse Error, TokArray::eat, Expected: ' %s ' not ' %.*s ' (%d, %d)`\n%s" , toktype_to_str(type).Ptr , at_idx.Length, at_idx.Text @@ -170,11 +170,12 @@ bool _check_parse_args( StrC def, char const* func_name ) return true; } -# define currtok_noskip (* lex_current( & Context.Tokens, dont_skip_formatting )) -# define currtok (* lex_current( & Context.Tokens, skip_formatting )) -# define peektok (* lex_peek(Context.Tokens, skip_formatting)) -# define prevtok (* lex_previous( Context.Tokens, dont_skip_formatting)) -# define nexttok (* lex_next( Context.Tokens, skip_formatting )) +# define currtok_noskip (* lex_current( & Context.Tokens, lex_dont_skip_formatting )) +# define currtok (* lex_current( & Context.Tokens, lex_skip_formatting )) +# define peektok (* lex_peek(Context.Tokens, lex_skip_formatting)) +# define prevtok (* lex_previous( Context.Tokens, lex_dont_skip_formatting)) +# define nexttok (* lex_next( Context.Tokens, lex_skip_formatting )) +# define nexttok_noskip (* lex_next( Context.Tokens, lex_dont_skip_formatting)) # define eat( Type_ ) lex__eat( & Context.Tokens, Type_ ) # define left ( array_num(Context.Tokens.Arr) - Context.Tokens.Idx ) @@ -208,23 +209,23 @@ internal CodeFn parse_function_after_name ( ModuleFlag mfla internal Code parse_function_body (); internal Code parse_global_nspace (); internal Code parse_global_nspace_constructor_destructor( CodeSpecifiers specifiers ); -internal Token parse_identifier ( bool* possible_member_function = nullptr ); +internal Token parse_identifier ( bool* possible_member_function ); internal CodeInclude parse_include (); internal CodeOperator parse_operator_after_ret_type ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeTypename ret_type ); internal Code parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers ); internal CodePragma parse_pragma (); -internal CodeParam parse_params ( bool use_template_capture = false ); +internal CodeParam parse_params ( bool use_template_capture ); internal CodePreprocessCond parse_preprocess_cond (); -internal Code parse_simple_preprocess ( TokType which, bool dont_consume_braces = false ); +internal Code parse_simple_preprocess ( TokType which, bool dont_consume_braces ); 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 ); internal CodeVar parse_variable_declaration_list (); -internal CodeClass parse_class ( bool inplace_def = false ); +internal CodeClass parse_class ( bool inplace_def ); internal CodeConstructor parse_constructor ( CodeSpecifiers specifiers ); internal CodeDestructor parse_destructor ( CodeSpecifiers specifiers = NullCode ); -internal CodeEnum parse_enum ( bool inplace_def = false ); +internal CodeEnum parse_enum ( bool inplace_def ); internal CodeBody parse_export_body (); internal CodeBody parse_extern_link_body(); internal CodeExtern parse_extern_link (); @@ -232,20 +233,25 @@ internal CodeFriend parse_friend (); internal CodeFn parse_function (); internal CodeNS parse_namespace (); internal CodeOpCast parse_operator_cast ( CodeSpecifiers specifiers = NullCode ); -internal CodeStruct parse_struct ( bool inplace_def = false ); +internal CodeStruct parse_struct ( bool inplace_def ); internal CodeVar parse_variable (); internal CodeTemplate parse_template (); -internal CodeTypename parse_type ( bool from_template = false, bool* is_function = nullptr ); +internal CodeTypename parse_type ( bool from_template, bool* is_function ); internal CodeTypedef parse_typedef (); -internal CodeUnion parse_union ( bool inplace_def = false ); +internal CodeUnion parse_union ( bool inplace_def ); internal CodeUsing parse_using (); -constexpr bool inplace_def = true; -constexpr bool dont_consume_braces = true; +constexpr bool parser_inplace_def = true; +constexpr bool parser_not_inplace_def = false; +constexpr bool parser_dont_consume_braces = true; +constexpr bool parser_consume_braces = false; +constexpr bool parser_not_from_template = false; + +constexpr bool parser_use_parenthesis = false; // Internal parsing functions -constexpr bool strip_formatting_dont_preserve_newlines = false; +constexpr bool parser_strip_formatting_dont_preserve_newlines = false; /* This function was an attempt at stripping formatting from any c++ code. It has edge case failures that prevent it from being used in function bodies. @@ -667,7 +673,7 @@ CodeAttributes parse_attributes() StrC attribute_txt = { len, start.Text }; parser_pop(& Context); - String name_stripped = strip_formatting( attribute_txt, strip_formatting_dont_preserve_newlines ); + String name_stripped = strip_formatting( attribute_txt, parser_strip_formatting_dont_preserve_newlines ); Code result = make_code(); result->Type = CT_PlatformAttributes; @@ -716,7 +722,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) if ( check( Tok_Identifier ) ) { - name = parse_identifier(); + name = parse_identifier(nullptr); Context.Scope->Name = name; } // @@ -741,7 +747,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) eat( currtok.Type ); } - Token parent_tok = parse_identifier(); + Token parent_tok = parse_identifier(nullptr); parent = def_type( tok_to_str(parent_tok) ); // : @@ -754,7 +760,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) { eat(currtok.Type); } - Token interface_tok = parse_identifier(); + Token interface_tok = parse_identifier(nullptr); array_append( interfaces, def_type( tok_to_str(interface_tok) ) ); // : , ... @@ -822,6 +828,8 @@ CodeBody parse_class_struct_body( TokType which, Token name ) if ( currtok_noskip.Type == Tok_Preprocess_Hash ) eat( Tok_Preprocess_Hash ); + b32 macro_found = true; + switch ( currtok_noskip.Type ) { case Tok_Statement_End: @@ -948,8 +956,9 @@ CodeBody parse_class_struct_body( TokType which, Token name ) break; case Tok_Preprocess_Macro: - member = parse_simple_preprocess( Tok_Preprocess_Macro ); // + macro_found = true; + goto Preprocess_Macro_Bare_In_Body; break; case Tok_Preprocess_Pragma: @@ -958,7 +967,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) break; case Tok_Preprocess_Unsupported: - member = parse_simple_preprocess( Tok_Preprocess_Unsupported ); + member = parse_simple_preprocess( Tok_Preprocess_Unsupported, parser_consume_braces ); // # break; @@ -1097,6 +1106,28 @@ CodeBody parse_class_struct_body( TokType which, Token name ) } } + if (macro_found) + { + Preprocess_Macro_Bare_In_Body: + b32 lone_macro = nexttok.Type == Tok_Statement_End || nexttok_noskip.Type == Tok_NewLine; + if (lone_macro) + { + member = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces ); + // ; + + if ( member == Code_Invalid ) + { + log_failure( "Failed to parse member\n%s", parser_to_string(Context) ); + parser_pop(& Context); + return InvalidCode; + } + continue; + } + + // We have a macro but its most likely behaving as a typename + // operator ... // or @@ -1239,7 +1270,7 @@ Code parse_complicated_definition( TokType which ) // : ; // : ; ok_to_parse = true; - Code result = parse_enum(); + Code result = parse_enum( ! parser_inplace_def); parser_pop(& Context); return result; } @@ -1279,7 +1310,7 @@ Code parse_complicated_definition( TokType which ) // Its a forward declaration of an enum class // : ; // : ; - Code result = parse_enum(); + Code result = parse_enum( ! parser_inplace_def); parser_pop(& Context); return result; } @@ -1347,7 +1378,7 @@ CodeDefine parse_define() return define; } - define->Content = get_cached_string( string_to_strc( strip_formatting( tok_to_str(currtok), strip_formatting_dont_preserve_newlines )) ); + define->Content = get_cached_string( string_to_strc( strip_formatting( tok_to_str(currtok), parser_strip_formatting_dont_preserve_newlines )) ); eat( Tok_Preprocess_Content ); // #define @@ -1436,7 +1467,7 @@ CodeFn parse_function_after_name( ) { push_scope(); - CodeParam params = parse_params(); + CodeParam params = parse_params(parser_use_parenthesis); // ( ) // TODO(Ed), Review old comment : These have to be kept separate from the return type's specifiers. @@ -1612,6 +1643,8 @@ CodeBody parse_global_nspace( CodeType which ) if ( currtok_noskip.Type == Tok_Preprocess_Hash ) eat( Tok_Preprocess_Hash ); + b32 macro_found = false; + switch ( currtok_noskip.Type ) { case Tok_Comma: @@ -1716,45 +1749,41 @@ CodeBody parse_global_nspace( CodeType which ) // #endif break; - case Tok_Preprocess_Macro: - { - member = parse_simple_preprocess( Tok_Preprocess_Macro ); + case Tok_Preprocess_Macro: { // - - if ( member == Code_Invalid ) - { - log_failure( "Failed to parse member\n%s", parser_to_string(Context) ); - parser_pop(& Context); - return InvalidCode; - } + macro_found = true; + goto Preprocess_Macro_Bare_In_Body; } break; - case Tok_Preprocess_Pragma: + case Tok_Preprocess_Pragma: { member = parse_pragma(); // #pragma ... + } break; - case Tok_Preprocess_Unsupported: - member = parse_simple_preprocess( Tok_Preprocess_Unsupported ); + case Tok_Preprocess_Unsupported: { + member = parse_simple_preprocess( Tok_Preprocess_Unsupported, parser_consume_braces ); // # ... + } break; - case Tok_StaticAssert: + case Tok_StaticAssert: { member = parse_static_assert(); // static_assert( , ... ); + } break; - case Tok_Module_Export: + case Tok_Module_Export: { if ( which == CT_Export_Body ) log_failure( "Nested export declaration\n%s", parser_to_string(Context) ); member = parse_export_body(); // export { ... } + } break; - case Tok_Module_Import: - { + case Tok_Module_Import: { not_implemented( context ); // import ... } @@ -1847,42 +1876,67 @@ CodeBody parse_global_nspace( CodeType which ) case Tok_Type_double: case Tok_Type_int: { - Code constructor_destructor = parse_global_nspace_constructor_destructor( specifiers ); - // Possible constructor implemented at global file scope. - if ( constructor_destructor ) + // This s only in a scope so that Preprocess_Macro_Bare_In_Body works without microsoft extension warnings { - member = constructor_destructor; - break; - } - - bool found_operator_cast_outside_class_implmentation = false; - s32 idx = Context.Tokens.Idx; - - for ( ; idx < array_num(Context.Tokens.Arr); idx++ ) - { - Token tok = Context.Tokens.Arr[ idx ]; - - if ( tok.Type == Tok_Identifier ) + Code constructor_destructor = parse_global_nspace_constructor_destructor( specifiers ); + // Possible constructor implemented at global file scope. + if ( constructor_destructor ) { - idx++; - tok = Context.Tokens.Arr[ idx ]; - if ( tok.Type == Tok_Access_StaticSymbol ) - continue; + member = constructor_destructor; + break; + } + + bool found_operator_cast_outside_class_implmentation = false; + s32 idx = Context.Tokens.Idx; + + for ( ; idx < array_num(Context.Tokens.Arr); idx++ ) + { + Token tok = Context.Tokens.Arr[ idx ]; + + if ( tok.Type == Tok_Identifier ) + { + idx++; + tok = Context.Tokens.Arr[ idx ]; + if ( tok.Type == Tok_Access_StaticSymbol ) + continue; + + break; + } + + if ( tok.Type == Tok_Decl_Operator ) + found_operator_cast_outside_class_implmentation = true; break; } - if ( tok.Type == Tok_Decl_Operator ) - found_operator_cast_outside_class_implmentation = true; - - break; + if ( found_operator_cast_outside_class_implmentation ) + { + member = parse_operator_cast( specifiers ); + // ::operator () { ... } + break; + } } - if ( found_operator_cast_outside_class_implmentation ) + if (macro_found) { - member = parse_operator_cast( specifiers ); - // ::operator () { ... } - break; + Preprocess_Macro_Bare_In_Body: + b32 lone_macro = nexttok.Type == Tok_Statement_End || nexttok_noskip.Type == Tok_NewLine; + if (lone_macro) + { + member = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces ); + // ; + + if ( member == Code_Invalid ) + { + log_failure( "Failed to parse member\n%s", parser_to_string(Context) ); + parser_pop(& Context); + return InvalidCode; + } + goto Member_Resolved_To_Lone_Macro; + } + + // We have a macro but its most likely behaving as a typename + // operator // Parse Params - CodeParam params = parse_params(); + CodeParam params = parse_params(parser_use_parenthesis); // operator ( ) if ( params.ast == nullptr && op == Op_Multiply ) @@ -2509,17 +2564,19 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes Code result = InvalidCode; #ifndef GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES - if ( currtok.Type == Tok_Preprocess_Macro ) + b32 lone_macro = false; + + if ( currtok.Type == Tok_Preprocess_Macro && nexttok.Type == Tok_Statement_End ) { - // Were dealing with a macro after attributes/specifiers. - result = parse_simple_preprocess( Tok_Preprocess_Macro ); + // Were dealing with a lone macro after attributes/specifiers, there was a end statement ';' after. + result = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces ); parser_pop(& Context); return result; // } #endif - CodeTypename type = parse_type(); + CodeTypename type = parse_type( parser_not_from_template, nullptr ); // if ( type == InvalidCode ) @@ -2559,7 +2616,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes } else { - Token name = parse_identifier(); + Token name = parse_identifier(nullptr); Context.Scope->Name = name; bool detected_capture = check( Tok_Capture_Start ); @@ -2679,12 +2736,12 @@ CodeParam parse_params( bool use_template_capture ) // AddComponentByClass(UPARAM(meta = (AllowAbstract = "false")) TSubclassOf Class, bool bManualAttachment, ... if ( check(Tok_Preprocess_Macro)) { - macro = parse_simple_preprocess(Tok_Preprocess_Macro); + macro = parse_simple_preprocess(Tok_Preprocess_Macro, parser_consume_braces); // ( } if ( currtok.Type != Tok_Comma ) { - type = parse_type( use_template_capture ); + type = parse_type( use_template_capture, nullptr ); if ( type == Code_Invalid ) { parser_pop(& Context); @@ -2705,7 +2762,7 @@ CodeParam parse_params( bool use_template_capture ) // So we need to consume that. if ( check( Tok_Preprocess_Macro )) { - post_name_macro = parse_simple_preprocess( Tok_Preprocess_Macro ); + post_name_macro = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces ); } // In template captures you can have a typename have direct assignment without a name @@ -2747,7 +2804,7 @@ CodeParam parse_params( bool use_template_capture ) eat( currtok.Type ); } - value = untyped_str( string_to_strc(strip_formatting( tok_to_str(value_tok), strip_formatting_dont_preserve_newlines )) ); + value = untyped_str( string_to_strc(strip_formatting( tok_to_str(value_tok), parser_strip_formatting_dont_preserve_newlines )) ); // ( = } } @@ -2789,12 +2846,12 @@ CodeParam parse_params( bool use_template_capture ) // AddComponentByClass(UPARAM(meta = (AllowAbstract = "false")) TSubclassOf Class, bool bManualAttachment, ... if ( check(Tok_Preprocess_Macro)) { - macro = parse_simple_preprocess(Tok_Preprocess_Macro); + macro = parse_simple_preprocess(Tok_Preprocess_Macro, parser_dont_consume_braces); // ( } if ( currtok.Type != Tok_Comma ) { - type = parse_type( use_template_capture ); + type = parse_type( use_template_capture, nullptr ); if ( type == Code_Invalid ) { parser_pop(& Context); @@ -2817,7 +2874,7 @@ CodeParam parse_params( bool use_template_capture ) // So we need to consume that. if ( check( Tok_Preprocess_Macro )) { - post_name_macro = parse_simple_preprocess( Tok_Preprocess_Macro ); + post_name_macro = parse_simple_preprocess( Tok_Preprocess_Macro, parser_dont_consume_braces ); } // In template captures you can have a typename have direct assignment without a name @@ -2862,7 +2919,7 @@ CodeParam parse_params( bool use_template_capture ) eat( currtok.Type ); } - value = untyped_str( string_to_strc(strip_formatting( tok_to_str(value_tok), strip_formatting_dont_preserve_newlines )) ); + value = untyped_str( string_to_strc(strip_formatting( tok_to_str(value_tok), parser_strip_formatting_dont_preserve_newlines )) ); // ( = , = } // ( = , = , .. @@ -3402,8 +3459,8 @@ CodeConstructor parse_constructor( CodeSpecifiers specifiers ) { push_scope(); - Token identifier = parse_identifier(); - CodeParam params = parse_params(); + Token identifier = parse_identifier(nullptr); + CodeParam params = parse_params(parser_not_from_template); // ( ) Code initializer_list = NullCode; @@ -3507,7 +3564,7 @@ CodeDestructor parse_destructor( CodeSpecifiers specifiers ) Token prefix_identifier = NullToken; if (is_in_global_nspace) - prefix_identifier = parse_identifier(); + prefix_identifier = parse_identifier(nullptr); if ( left && currtok.Text[ 0 ] == '~' ) eat( Tok_Operator ); @@ -3519,7 +3576,7 @@ CodeDestructor parse_destructor( CodeSpecifiers specifiers ) } // ~ - Token identifier = parse_identifier(); + Token identifier = parse_identifier(nullptr); CodeBody body = { nullptr }; CodeComment inline_cmt = NullCode; // ~ @@ -3646,7 +3703,7 @@ CodeEnum parse_enum( bool inplace_def ) eat( Tok_Assign_Classifer ); // enum : - type = parse_type(); + type = parse_type(parser_not_from_template, nullptr); if ( type == Code_Invalid ) { log_failure( "Failed to parse enum classifier\n%s", parser_to_string(Context) ); @@ -3662,7 +3719,7 @@ CodeEnum parse_enum( bool inplace_def ) if ( strc_contains( tok_to_str(currtok), sig) ) { use_macro_underlying = true; - underlying_macro = parse_simple_preprocess( Tok_Preprocess_Macro, dont_consume_braces ); + underlying_macro = parse_simple_preprocess( Tok_Preprocess_Macro, parser_dont_consume_braces ); } } @@ -3726,7 +3783,7 @@ CodeEnum parse_enum( bool inplace_def ) break; case Tok_Preprocess_Macro: - member = parse_simple_preprocess( Tok_Preprocess_Macro ); + member = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces); // break; @@ -3736,7 +3793,7 @@ CodeEnum parse_enum( bool inplace_def ) break; case Tok_Preprocess_Unsupported: - member = parse_simple_preprocess( Tok_Preprocess_Unsupported ); + member = parse_simple_preprocess( Tok_Preprocess_Unsupported, parser_consume_braces ); // # break; @@ -3781,7 +3838,7 @@ CodeEnum parse_enum( bool inplace_def ) // = , // // } - Token prev = * lex_previous(Context.Tokens, dont_skip_formatting); + Token prev = * lex_previous(Context.Tokens, lex_dont_skip_formatting); entry.Length = ( (sptr)prev.Text + prev.Length ) - (sptr)entry.Text; member = untyped_str( tok_to_str(entry) ); @@ -3948,7 +4005,7 @@ CodeFriend parse_friend() } // Type declaration or return type - CodeTypename type = parse_type(); + CodeTypename type = parse_type(parser_not_from_template, nullptr); if ( type == Code_Invalid ) { parser_pop(& Context); @@ -3960,7 +4017,7 @@ CodeFriend parse_friend() if ( currtok.Type == Tok_Identifier ) { // Name - Token name = parse_identifier(); + Token name = parse_identifier(nullptr); Context.Scope->Name = name; // friend @@ -4074,7 +4131,7 @@ CodeFn parse_function() } // - CodeTypename ret_type = parse_type(); + CodeTypename ret_type = parse_type(parser_not_from_template, nullptr); if ( ret_type == Code_Invalid ) { parser_pop(& Context); @@ -4082,7 +4139,7 @@ CodeFn parse_function() } // - Token name = parse_identifier(); + Token name = parse_identifier(nullptr); Context.Scope->Name = name; if ( ! tok_is_valid(name) ) { @@ -4106,7 +4163,7 @@ CodeNS parse_namespace() eat( Tok_Decl_Namespace ); // namespace - Token name = parse_identifier(); + Token name = parse_identifier(nullptr); Context.Scope->Name = name; // namespace @@ -4186,7 +4243,7 @@ CodeOperator parse_operator() // // Parse Return Type - CodeTypename ret_type = parse_type(); + CodeTypename ret_type = parse_type(parser_not_from_template, nullptr); // CodeOperator result = parse_operator_after_ret_type( mflags, attributes, specifiers, ret_type ); @@ -4223,7 +4280,7 @@ CodeOpCast parse_operator_cast( CodeSpecifiers specifiers ) eat( Tok_Decl_Operator ); // :: ... operator - Code type = parse_type(); + Code type = parse_type(parser_not_from_template, nullptr); // :: ... operator Context.Scope->Name = { type->Name.Ptr, type->Name.Len }; @@ -4350,21 +4407,21 @@ CodeTemplate parse_template() { if ( check( Tok_Decl_Class ) ) { - definition = parse_class(); + definition = parse_class( parser_not_inplace_def); // template< > class ... break; } if ( check( Tok_Decl_Struct ) ) { - definition = parse_struct(); + definition = parse_struct( parser_not_inplace_def); // template< > struct ... break; } if ( check( Tok_Decl_Union ) ) { - definition = parse_union(); + definition = parse_union( parser_not_inplace_def); // template< > union ... break; } @@ -4583,7 +4640,7 @@ CodeTypename parse_type( bool from_template, bool* typedef_is_function ) eat( currtok.Type ); // - name = parse_identifier(); + name = parse_identifier(nullptr); // name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text; // eat( Tok_Identifier ); @@ -4643,7 +4700,7 @@ else if ( currtok.Type == Tok_DeclType ) if ( ! from_template ) { - name = parse_identifier(); + name = parse_identifier(nullptr); Context.Scope->Name = name; if ( ! tok_is_valid(name) ) { @@ -4653,11 +4710,16 @@ else if ( currtok.Type == Tok_DeclType ) } } } + else if ( currtok.Type == Tok_Preprocess_Macro ) { + // Typename is a macro + name = currtok; + eat(Tok_Preprocess_Macro); + } // The usual Identifier type signature that may have namespace qualifiers else { - name = parse_identifier(); + name = parse_identifier(nullptr); Context.Scope->Name = name; if ( ! tok_is_valid(name) ) { @@ -4782,7 +4844,7 @@ else if ( currtok.Type == Tok_DeclType ) if ( ! check( Tok_Capture_Start ) ) { // Started with an identifier immeidately, which means its of the format: ; - name = parse_identifier(); + name = parse_identifier(nullptr); } // @@ -4866,7 +4928,7 @@ else if ( currtok.Type == Tok_DeclType ) } // Were now dealing with the parameters of the function - params = parse_params(); + params = parse_params(parser_use_parenthesis); // ( ) // Look for suffix specifiers for the function @@ -4913,7 +4975,7 @@ else if ( currtok.Type == Tok_DeclType ) // result->Token = Context.Scope->Start; // Need to wait until were using the new parsing method to do this. - String name_stripped = strip_formatting( tok_to_str(name), strip_formatting_dont_preserve_newlines ); + String name_stripped = strip_formatting( tok_to_str(name), parser_strip_formatting_dont_preserve_newlines ); // name_stripped.strip_space(); @@ -5105,7 +5167,7 @@ CodeTypedef parse_typedef() { // Its an array definition // [ ... ]; - type = parse_type(); + type = parse_type(parser_not_from_template, nullptr); // typedef } else @@ -5278,7 +5340,13 @@ CodeUnion parse_union( bool inplace_def ) break; case Tok_Preprocess_Macro: - member = parse_simple_preprocess( Tok_Preprocess_Macro ); + if ( nexttok.Type == Tok_Identifier ) { + // Its a variable with a macro typename + member = parse_variable(); + break; + } + + member = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces ); break; case Tok_Preprocess_Pragma: @@ -5286,7 +5354,7 @@ CodeUnion parse_union( bool inplace_def ) break; case Tok_Preprocess_Unsupported: - member = parse_simple_preprocess( Tok_Preprocess_Unsupported ); + member = parse_simple_preprocess( Tok_Preprocess_Unsupported, parser_consume_braces ); break; default: @@ -5371,7 +5439,7 @@ CodeUsing parse_using() eat( Tok_Operator ); // using = - type = parse_type(); + type = parse_type(parser_not_from_template, nullptr); // using = array_expr = parse_array_decl(); @@ -5481,13 +5549,13 @@ CodeVar parse_variable() } // - CodeTypename type = parse_type(); + CodeTypename type = parse_type(parser_not_from_template, nullptr); // if ( type == Code_Invalid ) return InvalidCode; - Context.Scope->Name = parse_identifier(); + Context.Scope->Name = parse_identifier(nullptr); // CodeVar result = parse_variable_after_name( mflags, attributes, specifiers, type, tok_to_str(Context.Scope->Name) ); diff --git a/project/dependencies/memory.hpp b/project/dependencies/memory.hpp index 9f187ac..386d0ac 100644 --- a/project/dependencies/memory.hpp +++ b/project/dependencies/memory.hpp @@ -365,18 +365,18 @@ ssize fixed_arena_size_remaining(FixedArena* fixed_arena, ssize alignment) return size_remaining(fixed_arena->arena, alignment); } -using Arena_1KB = FixedArena< kilobytes( 1 ) >; -using Arena_4KB = FixedArena< kilobytes( 4 ) >; -using Arena_8KB = FixedArena< kilobytes( 8 ) >; -using Arena_16KB = FixedArena< kilobytes( 16 ) >; -using Arena_32KB = FixedArena< kilobytes( 32 ) >; -using Arena_64KB = FixedArena< kilobytes( 64 ) >; -using Arena_128KB = FixedArena< kilobytes( 128 ) >; -using Arena_256KB = FixedArena< kilobytes( 256 ) >; -using Arena_512KB = FixedArena< kilobytes( 512 ) >; -using Arena_1MB = FixedArena< megabytes( 1 ) >; -using Arena_2MB = FixedArena< megabytes( 2 ) >; -using Arena_4MB = FixedArena< megabytes( 4 ) >; +using FixedArena_1KB = FixedArena< kilobytes( 1 ) >; +using FixedArena_4KB = FixedArena< kilobytes( 4 ) >; +using FixedArena_8KB = FixedArena< kilobytes( 8 ) >; +using FixedArena_16KB = FixedArena< kilobytes( 16 ) >; +using FixedArena_32KB = FixedArena< kilobytes( 32 ) >; +using FixedArena_64KB = FixedArena< kilobytes( 64 ) >; +using FixedArena_128KB = FixedArena< kilobytes( 128 ) >; +using FixedArena_256KB = FixedArena< kilobytes( 256 ) >; +using FixedArena_512KB = FixedArena< kilobytes( 512 ) >; +using FixedArena_1MB = FixedArena< megabytes( 1 ) >; +using FixedArena_2MB = FixedArena< megabytes( 2 ) >; +using FixedArena_4MB = FixedArena< megabytes( 4 ) >; #pragma endregion FixedArena #pragma region Pool