diff --git a/.vscode/settings.json b/.vscode/settings.json index f3a91f7..fc55c5f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -72,5 +72,5 @@ }, "autoHide.autoHidePanel": false, "autoHide.autoHideSideBar": false, - "dimmer.enabled": false + "dimmer.enabled": true } diff --git a/gen_c_library/c_library.cpp b/gen_c_library/c_library.cpp index 736eb91..d26a866 100644 --- a/gen_c_library/c_library.cpp +++ b/gen_c_library/c_library.cpp @@ -172,6 +172,19 @@ int gen_main() case CT_Enum: { + if (entry->Name.is_equal(txt("ETypenameTag"))) + { +#pragma push_macro("enum_underlying") +#undef enum_underlying + entry->UnderlyingTypeMacro = untyped_str(token_fmt("type", entry->UnderlyingType->Name, stringize(enum_underlying()))); + entry->UnderlyingType = CodeTypename{nullptr}; + types.append(entry); +#pragma pop_macro("enum_underlying") + + CodeTypedef entry_td = parse_typedef(code( typedef u16 ETypenameTag; )); + types.append(entry_td); + continue; + } //log_fmt("Detected ENUM: %S", entry->Name); convert_cpp_enum_to_c(cast(CodeEnum, entry), types); } @@ -735,6 +748,89 @@ do \ break; } + CodeBody array_adt_node = gen_array(txt("ADT_Node"), txt("Array_ADT_Node")); + + CodeBody parsed_parsing = parse_file( project_dir "dependencies/parsing.hpp" ); + CodeBody parsing = def_body(CT_Global_Body); + for ( Code entry = parsed_parsing.begin(); entry != parsed_parsing.end(); ++ entry ) switch (entry->Type) + { + case CT_Preprocess_Pragma: + { + if ( entry->Content.contains(txt("ADT")) ) + { + parsing.append(entry); + parsing.append(fmt_newline); + + // Add ADT_Node forward and typedef early. + CodeStruct adt_node_fwd = parse_struct(code( struct ADT_Node; )); + CodeTypedef adt_node_typedef = parse_typedef(code( typedef struct ADT_Node ADT_Node; )); + parsing.append(adt_node_fwd); + parsing.append(adt_node_typedef); + + // Skip typedef since we added it + b32 continue_for = true; + for (Code array_entry = array_adt_node.begin(); continue_for && array_entry != array_adt_node.end(); ++ array_entry) switch (array_entry->Type) + { + case CT_Typedef: + { + // pop the array entry + array_adt_node->NumEntries -= 1; + Code next = array_entry->Next; + Code prev = array_entry->Prev; + next->Prev = array_entry->Prev; + prev->Next = next; + if ( array_adt_node->Front == array_entry ) + array_adt_node->Front = next; + + parsing.append(array_entry); + continue_for = false; + } + break; + } + + } + } + break; + + case CT_Enum: + { + convert_cpp_enum_to_c(cast(CodeEnum, entry), parsing); + } + break; + + case CT_Struct: + { + CodeStruct struct_def = cast(CodeStruct, entry); + if ( struct_def->Name.is_equal(txt("ADT_Node") ) ) + { + parsing.append(entry); + + // We need to define the array for ADT_Node right here. + parsing.append(array_adt_node); + parsing.append(fmt_newline); + continue; + } + + StrC type_str = codetype_to_keyword_str(entry->Type); + StrC formated_tmpl = token_fmt_impl( 3, + "type", type_str + , "name", entry->Name, + stringize( + typedef ; + )); + CodeTypedef tdef = parse_typedef(formated_tmpl); + parsing.append(entry); + parsing.append(tdef); + } + break; + + default: + { + parsing.append(entry); + } + break; + } + CodeBody array_string_cached = gen_array(txt("StringCached"), txt("Array_StringCached")); CodeBody containers = def_body(CT_Global_Body); @@ -776,6 +872,19 @@ do \ header.print( dump_to_scratch_and_retireve(strings)); header.print( dump_to_scratch_and_retireve(filesystem)); header.print( timing ); + + // CodeStruct fwd = parse_struct(txt("struct ADT_Node;")); + + header.print_fmt( "\n#pragma region Parsing\n" ); + + // header.print( fwd ); + // header.print( adt_node_typedef ); + // header.print( fmt_newline ); + // header.print(dump_to_scratch_and_retireve(array_adt_node)); + + header.print( dump_to_scratch_and_retireve(parsing) ); + header.print_fmt( "#pragma endregion Parsing\n\n" ); + header.print_fmt( "\nGEN_NS_END\n" ); header.print_fmt( roll_own_dependencies_guard_end ); #pragma endregion Print Dependencies @@ -834,7 +943,7 @@ do \ Code strings = scan_file( project_dir "dependencies/strings.cpp" ); Code filesystem = scan_file( project_dir "dependencies/filesystem.cpp" ); Code timing = scan_file( project_dir "dependencies/timing.cpp" ); -#pragma region Scan, Parse, and Generate Dependencies +#pragma endregion Scan, Parse, and Generate Dependencies #pragma region Scan, Parse, and Generate Components Code static_data = scan_file( project_dir "components/static_data.cpp" ); @@ -873,7 +982,38 @@ do \ #pragma endregion Print Dependencies #pragma region Print Components +#if 0 + CodeBody etoktype = gen_etoktype( project_dir "enums/ETokType.csv", project_dir "enums/AttributeTokens.csv" ); + header.print_fmt( "\nGEN_NS_BEGIN\n"); + header.print( static_data ); + + header.print_fmt( "#pragma region AST\n\n" ); + header.print( ast_case_macros ); + header.print( ast ); + header.print( code ); + header.print_fmt( "#pragma endregion AST\n\n" ); + + header.print_fmt( "#pragma region Interface\n" ); + header.print( interface ); + header.print( upfront ); + header.print_fmt( "\n#pragma region Parsing\n\n" ); + header.print( dump_to_scratch_and_retireve(parser_nspace) ); + header.print( lexer ); + header.print( parser ); + header.print( parsing_interface ); + header.print_fmt( "\n#pragma endregion Parsing\n" ); + header.print( untyped ); + header.print_fmt( "\n#pragma endregion Interface\n\n"); + + header.print_fmt( "#pragma region Builder\n" ); + header.print( scan_file( project_dir "auxillary/builder.cpp" ) ); + header.print_fmt( "\n#pragma endregion Builder\n\n" ); + + header.print_fmt( "\n#pragma region Scanner\n" ); + header.print( scan_file( project_dir "auxillary/scanner.hpp" ) ); + header.print_fmt( "#pragma endregion Scanner\n\n" ); +#endif #pragma endregion Print Components header.print_fmt( implementation_guard_end ); @@ -882,8 +1022,6 @@ do \ header.print( pop_ignores ); header.write(); - //k - gen::deinit(); return 0; #undef project_dir diff --git a/gen_c_library/components/containers.array.hpp b/gen_c_library/components/containers.array.hpp index 44322d1..e0d8dba 100644 --- a/gen_c_library/components/containers.array.hpp +++ b/gen_c_library/components/containers.array.hpp @@ -402,7 +402,9 @@ CodeBody gen_array_generic_selection_interface() interface_defines.append( gen_generic_selection_function_macro( Array_DefinitionCounter, txt("array_init"), GenericSel_Direct_Type )); interface_defines.append( gen_generic_selection_function_macro( Array_DefinitionCounter, txt("array_init_reserve"), GenericSel_Direct_Type )); interface_defines.append( gen_generic_selection_function_macro( Array_DefinitionCounter, txt("array_append"), GenericSel_By_Ref )); + interface_defines.append( gen_generic_selection_function_macro( Array_DefinitionCounter, txt("array_append_at"), GenericSel_By_Ref )); interface_defines.append( gen_generic_selection_function_macro( Array_DefinitionCounter, txt("array_append_items"), GenericSel_By_Ref )); + interface_defines.append( gen_generic_selection_function_macro( Array_DefinitionCounter, txt("array_append_items_at"), GenericSel_By_Ref )); interface_defines.append( gen_generic_selection_function_macro( Array_DefinitionCounter, txt("array_back"), GenericSel_Default, GenericSel_One_Arg )); interface_defines.append( gen_generic_selection_function_macro( Array_DefinitionCounter, txt("array_clear"), GenericSel_Default, GenericSel_One_Arg )); interface_defines.append( gen_generic_selection_function_macro( Array_DefinitionCounter, txt("array_fill")) ); diff --git a/project/components/ast.hpp b/project/components/ast.hpp index ceb2310..80fcb0e 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -384,7 +384,10 @@ struct AST ModuleFlag ModuleFlags; union { b32 IsFunction; // Used by typedef to not serialize the name field. - b32 IsParamPack; // Used by typename to know if type should be considered a parameter pack. + struct { + b16 IsParamPack; // Used by typename to know if type should be considered a parameter pack. + ETypenameTag TypeTag; // Used by typename to keep track of explicitly declared tags for the identifier (enum, struct, union) + }; Operator Op; AccessSpec ParentAccess; s32 NumEntries; diff --git a/project/components/ast_types.hpp b/project/components/ast_types.hpp index 9a15e1c..be105cb 100644 --- a/project/components/ast_types.hpp +++ b/project/components/ast_types.hpp @@ -1017,6 +1017,7 @@ struct AST_Type static_assert( sizeof(AST_Type) == sizeof(AST), "ERROR: AST_Type is not the same size as AST"); #endif +// TODO(Ed): Add support for preserving the typename's keyword qualifier (struct, class, enum, etc), mostly needed for C. struct AST_Typename { union { @@ -1039,7 +1040,10 @@ struct AST_Typename Code Parent; CodeType Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) ]; - b32 IsParamPack; + struct { + b16 IsParamPack; // Used by typename to know if type should be considered a parameter pack. + ETypenameTag TypeTag; // Used by typename to keep track of explicitly declared tags for the identifier (enum, struct, union) + }; }; static_assert( sizeof(AST_Typename) == sizeof(AST), "ERROR: AST_Type is not the same size as AST"); diff --git a/project/components/code_serialization.cpp b/project/components/code_serialization.cpp index 8f0ee50..369f28e 100644 --- a/project/components/code_serialization.cpp +++ b/project/components/code_serialization.cpp @@ -1194,6 +1194,16 @@ void typename_to_string_ref(CodeTypename self, String* result ) if ( self->Attributes ) string_append_fmt( result, "%S ", attributes_to_string(self->Attributes) ); + switch ( self->TypeTag ) + { + case Tag_Class : string_append_strc( result, txt("class ")); break; + case Tag_Enum : string_append_strc( result, txt("enum ")); break; + case Tag_Struct : string_append_strc( result, txt("struct ")); break; + case Tag_Union : string_append_strc( result, txt("union ")); break; + default: + break; + } + if ( self->Specs ) string_append_fmt( result, "%SC %S", self->Name, specifiers_to_string(self->Specs) ); else diff --git a/project/components/interface.hpp b/project/components/interface.hpp index c7e550a..d23cccb 100644 --- a/project/components/interface.hpp +++ b/project/components/interface.hpp @@ -138,6 +138,7 @@ struct Opts_def_template { ModuleFlag mflags; }; CodeTemplate def_template( CodeParam params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT ); struct Opts_def_type { + ETypenameTag type_tag; Code arrayexpr; CodeSpecifiers specifiers; CodeAttributes attributes; diff --git a/project/components/interface.upfront.cpp b/project/components/interface.upfront.cpp index 337826b..45214ab 100644 --- a/project/components/interface.upfront.cpp +++ b/project/components/interface.upfront.cpp @@ -1303,6 +1303,8 @@ CodeTypename def_type( StrC name, Opts_def_type p ) if ( arrayexpr ) result->ArrExpr = arrayexpr; + result->TypeTag = p.type_tag; + return result; } diff --git a/project/components/parser.cpp b/project/components/parser.cpp index dc96bda..b129139 100644 --- a/project/components/parser.cpp +++ b/project/components/parser.cpp @@ -4523,9 +4523,11 @@ CodeTypename parse_type( bool from_template, bool* typedef_is_function ) Token context_tok = prevtok; Specifier specs_found[ 16 ] { Spec_NumSpecifiers }; - s32 NumSpecifiers = 0; + s32 NumSpecifiers = 0; - Token name = { nullptr, 0, Tok_Invalid }; + Token name= { nullptr, 0, Tok_Invalid }; + + ETypenameTag tag = Tag_None; // Attributes are assumed to be before the type signature CodeAttributes attributes = parse_attributes(); @@ -4568,6 +4570,14 @@ CodeTypename parse_type( bool from_template, bool* typedef_is_function ) else if ( currtok.Type == Tok_Decl_Class || currtok.Type == Tok_Decl_Enum || currtok.Type == Tok_Decl_Struct || currtok.Type == Tok_Decl_Union ) { + switch (currtok.Type) { + case Tok_Decl_Class : tag = Tag_Class; break; + case Tok_Decl_Enum : tag = Tag_Enum; break; + case Tok_Decl_Struct : tag = Tag_Struct; break; + case Tok_Decl_Union : tag = Tag_Union; break; + default: + break; + } eat( currtok.Type ); // @@ -4950,6 +4960,8 @@ else if ( currtok.Type == Tok_DeclType ) if ( params ) result->Params = params; + result->TypeTag = tag; + pop(& Context); return result; } diff --git a/project/components/types.hpp b/project/components/types.hpp index bd82215..7b8231f 100644 --- a/project/components/types.hpp +++ b/project/components/types.hpp @@ -123,3 +123,15 @@ enum EPreprocessCond : u32 EPreprocessCond_SizeDef = GEN_U32_MAX, }; static_assert( size_of(EPreprocessCond) == size_of(u32), "EPreprocessCond not u32 size" ); + +enum ETypenameTag : u16 +{ + Tag_None, + Tag_Class, + Tag_Enum, + Tag_Struct, + Tag_Union, + + Tag_UnderlyingType = GEN_U16_MAX, +}; +static_assert( size_of(ETypenameTag) == size_of(u16), "ETypenameTag is not u16 size"); diff --git a/project/dependencies/parsing.cpp b/project/dependencies/parsing.cpp index 7882701..465e705 100644 --- a/project/dependencies/parsing.cpp +++ b/project/dependencies/parsing.cpp @@ -24,7 +24,7 @@ u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32 node->type = type; node->name = name; node->parent = parent; - node->nodes = array_init( backing ); + node->nodes = array_init(ADT_Node, backing ); if ( ! node->nodes ) return EADT_ERROR_OUT_OF_MEMORY; diff --git a/project/helpers/helper.hpp b/project/helpers/helper.hpp index 7687429..7b80072 100644 --- a/project/helpers/helper.hpp +++ b/project/helpers/helper.hpp @@ -349,7 +349,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) return result; } -CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) +CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_definition = false ) { char scratch_mem[kilobytes(16)]; Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );