diff --git a/.gitignore b/.gitignore index c953c64..bdd372f 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ gen_c_library/gen **/*.vcxproj **/*.vcxproj.filters **/*.vcxproj.user +test/c_library/gen +test/cpp_library/gen diff --git a/Readme.md b/Readme.md index 1c3de45..713616e 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,8 @@ # gencpp -An attempt at simple staged metaprogramming for C/C++. +An attempt at simple staged metaprogramming for C/C++. Reflect and generate code for your codebase at runtime! + +![splash](./docs/assets/Code_-_Insiders_2024-12-15_22-52-13.gif) The library API is a composition of code element constructors, and a non-standards-compliant single-pass C/C++ parser. These build up a code AST to then serialize with a file builder, or can be traversed for staged-reflection of C/C++ code. @@ -49,7 +51,11 @@ Within `program.cpp` : u32 gen_main() { + gen::Context ctx; + gen::init(& ctx); ... + gen::deinit(& ctx); + return 0; } #endif diff --git a/base/components/code_serialization.cpp b/base/components/code_serialization.cpp index 94e601a..ea78d1c 100644 --- a/base/components/code_serialization.cpp +++ b/base/components/code_serialization.cpp @@ -1036,12 +1036,24 @@ void specifiers_to_strbuilder_ref( CodeSpecifiers self, StrBuilder* result ) GEN_ASSERT(result); s32 idx = 0; s32 left = self->NumEntries; - while ( left-- ) + while ( left -- ) { - Str spec = spec_to_str( self->ArrSpecs[idx] ); - strbuilder_append_fmt( result, "%.*s ", spec.Len, spec.Ptr ); + Specifier spec = self->ArrSpecs[idx]; + Str spec_str = spec_to_str( spec ); + if ( idx > 0 ) switch (spec) { + case Spec_Ptr: + case Spec_Ref: + case Spec_RValue: + break; + + default: + strbuilder_append_str(result, txt(" ")); + break; + } + strbuilder_append_fmt( result, "%S", spec_str ); idx++; } + strbuilder_append_str(result, txt(" ")); } StrBuilder struct_to_strbuilder(CodeStruct self) @@ -1445,7 +1457,7 @@ void var_to_strbuilder_ref(CodeVar self, StrBuilder* result ) strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) ); if ( self->Specs ) - strbuilder_append_fmt( result, "%SB\n", specifiers_to_strbuilder(self->Specs) ); + strbuilder_append_fmt( result, "%SB", specifiers_to_strbuilder(self->Specs) ); strbuilder_append_fmt( result, "%SB %S", typename_to_strbuilder(self->ValueType), self->Name ); diff --git a/base/components/interface.cpp b/base/components/interface.cpp index f0e97ee..78d29f7 100644 --- a/base/components/interface.cpp +++ b/base/components/interface.cpp @@ -503,7 +503,7 @@ void register_macros( s32 num, ... ) va_end(va); } -void register_macros( s32 num, Macro* macros ) +void register_macros_arr( s32 num, Macro* macros ) { GEN_ASSERT(num > 0); do diff --git a/base/components/interface.hpp b/base/components/interface.hpp index 8a849ad..90e7fbe 100644 --- a/base/components/interface.hpp +++ b/base/components/interface.hpp @@ -93,6 +93,9 @@ struct Context // TODO(Ed): Active parse context vs a parse result need to be separated conceptually ParseContext parser; + + // TODO(Ed): Formatting - This will eventually be in a separate struct when in the process of serialization of the builder. + s32 temp_serialize_indent; }; // Initialize the library. There first ctx initialized must exist for lifetime of other contextes that come after as its the one that @@ -121,7 +124,11 @@ GEN_API void register_macro( Macro macro ); // Ease of use batch registration GEN_API void register_macros( s32 num, ... ); -GEN_API void register_macros( s32 num, Macro* macros ); +GEN_API void register_macros_arr( s32 num, Macro* macros ); + +#if GEN_COMPILER_CPP +forceinline void register_macros( s32 num, Macro* macros ) { return register_macros_arr(num, macros); } +#endif // Used internally to retrive or make string allocations. // Strings are stored in a series of string arenas of fixed size (SizePer_StringArena) @@ -276,30 +283,45 @@ GEN_API CodeBody def_body( CodeType type ); // There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num, /// or provide as an array of Code objects. -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, ... ); -GEN_API CodeBody def_export_body ( s32 num, Code* codes); -GEN_API CodeBody def_extern_link_body( s32 num, ... ); -GEN_API CodeBody def_extern_link_body( s32 num, Code* codes ); -GEN_API CodeBody def_function_body ( s32 num, ... ); -GEN_API CodeBody def_function_body ( s32 num, Code* codes ); -GEN_API CodeBody def_global_body ( s32 num, ... ); -GEN_API CodeBody def_global_body ( s32 num, Code* codes ); -GEN_API CodeBody def_namespace_body ( s32 num, ... ); -GEN_API CodeBody def_namespace_body ( s32 num, Code* codes ); -GEN_API CodeParams def_params ( s32 num, ... ); -GEN_API CodeParams def_params ( s32 num, CodeParams* params ); -GEN_API CodeSpecifiers def_specifiers ( s32 num, ... ); -GEN_API CodeSpecifiers def_specifiers ( s32 num, Specifier* specs ); -GEN_API CodeBody def_struct_body ( s32 num, ... ); -GEN_API CodeBody def_struct_body ( s32 num, Code* codes ); -GEN_API CodeBody def_union_body ( s32 num, ... ); -GEN_API CodeBody def_union_body ( s32 num, Code* codes ); +GEN_API CodeBody def_class_body ( s32 num, ... ); +GEN_API CodeBody def_class_body_arr ( s32 num, Code* codes ); +GEN_API CodeDefineParams def_define_params ( s32 num, ... ); +GEN_API CodeDefineParams def_define_params_arr ( s32 num, CodeDefineParams* codes ); +GEN_API CodeBody def_enum_body ( s32 num, ... ); +GEN_API CodeBody def_enum_body_arr ( s32 num, Code* codes ); +GEN_API CodeBody def_export_body ( s32 num, ... ); +GEN_API CodeBody def_export_body_arr ( s32 num, Code* codes); +GEN_API CodeBody def_extern_link_body ( s32 num, ... ); +GEN_API CodeBody def_extern_link_body_arr ( s32 num, Code* codes ); +GEN_API CodeBody def_function_body ( s32 num, ... ); +GEN_API CodeBody def_function_body_arr ( s32 num, Code* codes ); +GEN_API CodeBody def_global_body ( s32 num, ... ); +GEN_API CodeBody def_global_body_arr ( s32 num, Code* codes ); +GEN_API CodeBody def_namespace_body ( s32 num, ... ); +GEN_API CodeBody def_namespace_body_arr ( s32 num, Code* codes ); +GEN_API CodeParams def_params ( s32 num, ... ); +GEN_API CodeParams def_params_arr ( s32 num, CodeParams* params ); +GEN_API CodeSpecifiers def_specifiers ( s32 num, ... ); +GEN_API CodeSpecifiers def_specifiers_arr ( s32 num, Specifier* specs ); +GEN_API CodeBody def_struct_body ( s32 num, ... ); +GEN_API CodeBody def_struct_body_arr ( s32 num, Code* codes ); +GEN_API CodeBody def_union_body ( s32 num, ... ); +GEN_API CodeBody def_union_body_arr ( s32 num, Code* codes ); + +#if GEN_COMPILER_CPP +forceinline CodeBody def_class_body ( s32 num, Code* codes ) { return def_class_body_arr(num, codes); } +forceinline CodeDefineParams def_define_params ( s32 num, CodeDefineParams* codes ) { return def_define_params_arr(num, codes); } +forceinline CodeBody def_enum_body ( s32 num, Code* codes ) { return def_enum_body_arr(num, codes); } +forceinline CodeBody def_export_body ( s32 num, Code* codes) { return def_export_body_arr(num, codes); } +forceinline CodeBody def_extern_link_body( s32 num, Code* codes ) { return def_extern_link_body_arr(num, codes); } +forceinline CodeBody def_function_body ( s32 num, Code* codes ) { return def_function_body_arr(num, codes); } +forceinline CodeBody def_global_body ( s32 num, Code* codes ) { return def_global_body_arr(num, codes); } +forceinline CodeBody def_namespace_body ( s32 num, Code* codes ) { return def_namespace_body_arr(num, codes); } +forceinline CodeParams def_params ( s32 num, CodeParams* params ) { return def_params_arr(num, params); } +forceinline CodeSpecifiers def_specifiers ( s32 num, Specifier* specs ) { return def_specifiers_arr(num, specs); } +forceinline CodeBody def_struct_body ( s32 num, Code* codes ) { return def_struct_body_arr(num, codes); } +forceinline CodeBody def_union_body ( s32 num, Code* codes ) { return def_union_body_arr(num, codes); } +#endif #pragma endregion Upfront diff --git a/base/components/interface.parsing.cpp b/base/components/interface.parsing.cpp index eea7def..92f14f6 100644 --- a/base/components/interface.parsing.cpp +++ b/base/components/interface.parsing.cpp @@ -73,7 +73,7 @@ CodeConstructor parse_constructor( Str def ) if ( NumSpecifiers ) { - specifiers = def_specifiers( NumSpecifiers, specs_found ); + specifiers = def_specifiers_arr( NumSpecifiers, specs_found ); // ... } diff --git a/base/components/interface.upfront.cpp b/base/components/interface.upfront.cpp index d064a8b..79b56a0 100644 --- a/base/components/interface.upfront.cpp +++ b/base/components/interface.upfront.cpp @@ -1369,7 +1369,7 @@ CodeBody def_class_body( s32 num, ... ) return result; } -CodeBody def_class_body( s32 num, Code* codes ) +CodeBody def_class_body_arr( s32 num, Code* codes ) { def_body_code_array_start( def_class_body ); @@ -1432,7 +1432,7 @@ CodeDefineParams def_define_params( s32 num, ... ) return result; } -CodeDefineParams def_define_params( s32 num, CodeDefineParams* codes ) +CodeDefineParams def_define_params_arr( s32 num, CodeDefineParams* codes ) { def_body_code_array_start( def_define_params ); @@ -1491,7 +1491,7 @@ CodeBody def_enum_body( s32 num, ... ) return (CodeBody) result; } -CodeBody def_enum_body( s32 num, Code* codes ) +CodeBody def_enum_body_arr( s32 num, Code* codes ) { def_body_code_array_start( def_enum_body ); @@ -1552,7 +1552,7 @@ CodeBody def_export_body( s32 num, ... ) return result; } -CodeBody def_export_body( s32 num, Code* codes ) +CodeBody def_export_body_arr( s32 num, Code* codes ) { def_body_code_array_start( def_export_body ); @@ -1618,7 +1618,7 @@ CodeBody def_extern_link_body( s32 num, ... ) return result; } -CodeBody def_extern_link_body( s32 num, Code* codes ) +CodeBody def_extern_link_body_arr( s32 num, Code* codes ) { def_body_code_array_start( def_extern_linkage_body ); @@ -1685,7 +1685,7 @@ CodeBody def_function_body( s32 num, ... ) return result; } -CodeBody def_function_body( s32 num, Code* codes ) +CodeBody def_function_body_arr( s32 num, Code* codes ) { def_body_code_array_start( def_function_body ); @@ -1756,7 +1756,7 @@ CodeBody def_global_body( s32 num, ... ) return result; } -CodeBody def_global_body( s32 num, Code* codes ) +CodeBody def_global_body_arr( s32 num, Code* codes ) { def_body_code_array_start( def_global_body ); @@ -1827,7 +1827,7 @@ CodeBody def_namespace_body( s32 num, ... ) return result; } -CodeBody def_namespace_body( s32 num, Code* codes ) +CodeBody def_namespace_body_arr( s32 num, Code* codes ) { def_body_code_array_start( def_namespace_body ); @@ -1889,7 +1889,7 @@ CodeParams def_params( s32 num, ... ) return result; } -CodeParams def_params( s32 num, CodeParams* codes ) +CodeParams def_params_arr( s32 num, CodeParams* codes ) { def_body_code_array_start( def_params ); @@ -1945,7 +1945,7 @@ CodeSpecifiers def_specifiers( s32 num, ... ) return result; } -CodeSpecifiers def_specifiers( s32 num, Specifier* specs ) +CodeSpecifiers def_specifiers_arr( s32 num, Specifier* specs ) { if ( num <= 0 ) { log_failure("gen::def_specifiers: num cannot be zero or less"); @@ -2004,7 +2004,7 @@ CodeBody def_struct_body( s32 num, ... ) return result; } -CodeBody def_struct_body( s32 num, Code* codes ) +CodeBody def_struct_body_arr( s32 num, Code* codes ) { def_body_code_array_start( def_struct_body ); @@ -2065,7 +2065,7 @@ CodeBody def_union_body( s32 num, ... ) return result; } -CodeBody def_union_body( s32 num, Code* codes ) +CodeBody def_union_body_arr( s32 num, Code* codes ) { def_body_code_array_start( def_union_body ); diff --git a/base/components/lexer.cpp b/base/components/lexer.cpp index 07cf62f..7f4a7e7 100644 --- a/base/components/lexer.cpp +++ b/base/components/lexer.cpp @@ -532,7 +532,7 @@ void lex_found_token( LexContext* ctx ) ctx->token.Type = macrotype_to_toktype(macro->Type); b32 is_functional = macro_is_functional(* macro); resolved_to_macro = has_args ? is_functional : ! is_functional; - if ( ! resolved_to_macro ) { + if ( ! resolved_to_macro && GEN_BUILD_DEBUG ) { log_fmt("Info(%d, %d): %S identified as a macro but usage here does not resolve to one (interpreting as identifier)\n" , ctx->token.Line , ctx->token.Line diff --git a/base/components/parser.cpp b/base/components/parser.cpp index 47b5813..0848930 100644 --- a/base/components/parser.cpp +++ b/base/components/parser.cpp @@ -1028,7 +1028,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) if ( NumSpecifiers ) { - specifiers = def_specifiers( NumSpecifiers, specs_found ); + specifiers = def_specifiers_arr( NumSpecifiers, specs_found ); } // @@ -1753,7 +1753,7 @@ CodeBody parse_global_nspace( CodeType which ) if ( NumSpecifiers ) { - specifiers = def_specifiers( NumSpecifiers, specs_found ); + specifiers = def_specifiers_arr( NumSpecifiers, specs_found ); } // } @@ -4012,7 +4012,7 @@ CodeFriend parser_parse_friend() } if ( NumSpecifiers ) { - specifiers = def_specifiers( NumSpecifiers, specs_found ); + specifiers = def_specifiers_arr( NumSpecifiers, specs_found ); } // } @@ -4129,7 +4129,7 @@ CodeFn parser_parse_function() } if ( NumSpecifiers ) { - specifiers = def_specifiers( NumSpecifiers, specs_found ); + specifiers = def_specifiers_arr( NumSpecifiers, specs_found ); } // @@ -4237,7 +4237,7 @@ CodeOperator parser_parse_operator() } if ( NumSpecifiers ) { - specifiers = def_specifiers( NumSpecifiers, specs_found ); + specifiers = def_specifiers_arr( NumSpecifiers, specs_found ); } // @@ -4475,7 +4475,7 @@ CodeTemplate parser_parse_template() } if ( NumSpecifiers ) { - specifiers = def_specifiers( NumSpecifiers, specs_found ); + specifiers = def_specifiers_arr( NumSpecifiers, specs_found ); } // template< > } @@ -4733,7 +4733,7 @@ else if ( currtok.Type == Tok_DeclType ) #ifdef GEN_USE_NEW_TYPENAME_PARSING if ( NumSpecifiers ) { - specifiers = def_specifiers( NumSpecifiers, specs_found ); + specifiers = def_specifiers_arr( NumSpecifiers, specs_found ); NumSpecifiers = 0; } #endif @@ -4813,7 +4813,7 @@ else if ( currtok.Type == Tok_DeclType ) #else if ( NumSpecifiers ) - return_type->Specs = def_specifiers( NumSpecifiers, ( Specifier* )specs_found ); + return_type->Specs = def_specifiers_arr( NumSpecifiers, ( Specifier* )specs_found ); // Reset specifiers, the function itself will have its own suffix specifiers possibly. NumSpecifiers = 0; @@ -4864,7 +4864,7 @@ else if ( currtok.Type == Tok_DeclType ) if ( NumSpecifiers ) { - specifiers = def_specifiers( NumSpecifiers, specs_found ); + specifiers = def_specifiers_arr( NumSpecifiers, specs_found ); } NumSpecifiers = 0; // ( @@ -4935,7 +4935,7 @@ else if ( currtok.Type == Tok_DeclType ) #ifdef GEN_USE_NEW_TYPENAME_PARSING if ( NumSpecifiers ) { - func_suffix_specs = def_specifiers( NumSpecifiers, specs_found ); + func_suffix_specs = def_specifiers_arr( NumSpecifiers, specs_found ); NumSpecifiers = 0; } #endif @@ -4985,7 +4985,7 @@ else if ( currtok.Type == Tok_DeclType ) #else if ( NumSpecifiers ) { - CodeSpecifiers specifiers = def_specifiers( NumSpecifiers, ( Specifier* )specs_found ); + CodeSpecifiers specifiers = def_specifiers_arr( NumSpecifiers, ( Specifier* )specs_found ); result->Specs = specifiers; } #endif @@ -5523,7 +5523,7 @@ CodeVar parser_parse_variable() } if ( NumSpecifiers ) { - specifiers = def_specifiers( NumSpecifiers, specs_found ); + specifiers = def_specifiers_arr( NumSpecifiers, specs_found ); } // diff --git a/base/components/static_data.cpp b/base/components/static_data.cpp index 3c9c0f1..021bc26 100644 --- a/base/components/static_data.cpp +++ b/base/components/static_data.cpp @@ -5,10 +5,9 @@ #pragma region StaticData global Context* _ctx; +global u32 context_counter; #pragma region Constants -global u32 context_counter; - global Macro enum_underlying_macro; global Code Code_Global; diff --git a/base/dependencies/containers.hpp b/base/dependencies/containers.hpp index a84d148..afbed26 100644 --- a/base/dependencies/containers.hpp +++ b/base/dependencies/containers.hpp @@ -282,10 +282,9 @@ bool array_fill(Array array, usize begin, usize end, Type value) ArrayHeader* header = array_get_header(array); if (begin < 0 || end > header->Num) - return false; + return false; - for (ssize idx = ssize(begin); idx < ssize(end); idx++) - { + for (ssize idx = ssize(begin); idx < ssize(end); idx++) { array[idx] = value; } @@ -754,7 +753,7 @@ HashTableFindResult hashtable__find(HashTable table, u64 key) if (table.Entries[result.EntryIndex].Key == key) break; - result.PrevIndex = result.EntryIndex; + result.PrevIndex = result.EntryIndex; result.EntryIndex = table.Entries[result.EntryIndex].Next; } } diff --git a/base/dependencies/debug.hpp b/base/dependencies/debug.hpp index 858b277..04ddcbd 100644 --- a/base/dependencies/debug.hpp +++ b/base/dependencies/debug.hpp @@ -11,10 +11,10 @@ #if GEN_BUILD_DEBUG # if defined( GEN_COMPILER_MSVC ) # if _MSC_VER < 1300 -#pragma message("GEN_BUILD_DEBUG: __asm int 3") +// #pragma message("GEN_BUILD_DEBUG: __asm int 3") # define GEN_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */ # else -#pragma message("GEN_BUILD_DEBUG: __debugbreak()") +// #pragma message("GEN_BUILD_DEBUG: __debugbreak()") # define GEN_DEBUG_TRAP() __debugbreak() # endif # elif defined( GEN_COMPILER_TINYC ) @@ -23,7 +23,7 @@ # define GEN_DEBUG_TRAP() __builtin_trap() # endif #else -#pragma message("GEN_BUILD_DEBUG: omitted") +// #pragma message("GEN_BUILD_DEBUG: omitted") # define GEN_DEBUG_TRAP() #endif diff --git a/base/dependencies/macros.hpp b/base/dependencies/macros.hpp index f582d65..29b559a 100644 --- a/base/dependencies/macros.hpp +++ b/base/dependencies/macros.hpp @@ -89,13 +89,13 @@ #define src_line_str stringize(__LINE__) #ifndef do_once -#define do_once() \ - static int __do_once_counter_##src_line_str = 0; \ - for(; __do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1 ) \ +#define do_once() \ + local_persist int __do_once_counter_##src_line_str = 0; \ + for(; __do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1 ) \ -#define do_once_defer( expression ) \ - static int __do_once_counter_##src_line_str = 0; \ - for(; __do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1, (expression)) \ +#define do_once_defer( expression ) \ + local_persist int __do_once_counter_##src_line_str = 0; \ + for(;__do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1, (expression)) \ #define do_once_start \ do \ diff --git a/docs/Readme.md b/docs/Readme.md index 4655f0a..22319f1 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -238,6 +238,7 @@ Interface : * parse_class * parse_constructor +* parse_define * parse_destructor * parse_enum * parse_export_body @@ -322,6 +323,7 @@ Code = parse_( gen_code_str ); The following are provided predefined by the library as they are commonly used: +* `enum_underlying_macro` * `access_public` * `access_protected` * `access_private` diff --git a/docs/assets/Code_-_Insiders_2024-12-15_22-52-13.gif b/docs/assets/Code_-_Insiders_2024-12-15_22-52-13.gif new file mode 100644 index 0000000..8a68afe Binary files /dev/null and b/docs/assets/Code_-_Insiders_2024-12-15_22-52-13.gif differ diff --git a/gen_c_library/c_library.cpp b/gen_c_library/c_library.cpp index 275ddff..1db0f2a 100644 --- a/gen_c_library/c_library.cpp +++ b/gen_c_library/c_library.cpp @@ -1126,6 +1126,9 @@ R"(#define ( code ) _Generic( (code), \ b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_interface, interface ); if (found) break; + found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_interface, interface); + if (found) break; + interface.append(entry); } break; @@ -1136,12 +1139,14 @@ R"(#define ( code ) _Generic( (code), \ CodeFn fn = cast(CodeFn, entry); Code prev = entry->Prev; + #if 0 if (prev && prev->Name.is_equal(entry->Name)) { // rename second definition so there isn't a symbol conflict StrBuilder postfix_arr = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "%S_arr", entry->Name); entry->Name = cache_str(postfix_arr.to_str()); postfix_arr.free(); } + #endif b32 handled= false; for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_"))) @@ -1368,6 +1373,7 @@ R"(#define ( code ) _Generic( (code), \ { CodeFn fn = cast(CodeFn, entry); Code prev = entry->Prev; + #if 0 for ( CodeParams arr_param : fn->Params ) { b32 repeat_register_macros = fn->Name.is_equal(txt("register_macros")) && arr_param->Name.is_equal(txt("num")) && ! arr_param->Next->Name.is_equal(txt("...")); @@ -1377,6 +1383,7 @@ R"(#define ( code ) _Generic( (code), \ fn->Name = cache_str(postfix_arr.to_str()); } } + #endif src_interface.append(fn); } break; @@ -1444,6 +1451,7 @@ R"(#define ( code ) _Generic( (code), \ CodeFn fn = cast(CodeFn, entry); Code prev = entry->Prev; + #if 0 for ( CodeParams arr_param : fn->Params ) { b32 repeat_def_array = fn->Name.starts_with(txt("def_")) && arr_param->Name.is_equal(txt("num")) && ! arr_param->Next->Name.is_equal(txt("...")); @@ -1453,6 +1461,7 @@ R"(#define ( code ) _Generic( (code), \ fn->Name = cache_str(postfix_arr.to_str()); } } + #endif for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_"))) { // The frontend names are warapped in macros so we need to give it the intenral symbol name diff --git a/gen_c_library/c_library.refactor b/gen_c_library/c_library.refactor index 1dc2e85..a6a9262 100644 --- a/gen_c_library/c_library.refactor +++ b/gen_c_library/c_library.refactor @@ -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_set, gen_bitfield_is_set +word bitfield_is_set, gen_bitfield_is_set word cast, gen_cast word ccast, gen_ccast word pcast, gen_pcast @@ -408,6 +408,8 @@ namespace var_, gen_var_ // Gen Interface +word _ctx, gen__ctx + word init, gen_init word deinit, gen_deinit word reset, gen_reset diff --git a/gen_c_library/components/containers.array.hpp b/gen_c_library/components/containers.array.hpp index e2fd8b3..a7314b6 100644 --- a/gen_c_library/components/containers.array.hpp +++ b/gen_c_library/components/containers.array.hpp @@ -238,10 +238,10 @@ CodeBody gen_array( Str type, Str array_name ) GEN_ASSERT(begin <= end); ArrayHeader* header = array_get_header( self ); - if ( begin < 0 || end >= header->Num ) + if ( begin < 0 || end > header->Num ) return false; - for ( ssize idx = begin; idx < end; idx ++ ) + for ( ssize idx = (ssize)begin; idx < (ssize)end; idx ++ ) self[ idx ] = value; return true; diff --git a/gen_unreal_engine/enums/AttributeTokens.csv b/gen_unreal_engine/enums/AttributeTokens.csv index 4ac524b..8986955 100644 --- a/gen_unreal_engine/enums/AttributeTokens.csv +++ b/gen_unreal_engine/enums/AttributeTokens.csv @@ -4,3 +4,4 @@ COREUOBJECT_API, COREUOBJECT_API ENGINE_API, ENGINE_API GAMEPLAYABILITIES_API, GAMEPLAYABILITIES_API UMG_API, UMG_API +GASA_API, GASA_API \ No newline at end of file diff --git a/gen_unreal_engine/unreal.cpp b/gen_unreal_engine/unreal.cpp index 2afa5ae..839a7a9 100644 --- a/gen_unreal_engine/unreal.cpp +++ b/gen_unreal_engine/unreal.cpp @@ -100,7 +100,8 @@ int gen_main() (Macro { txt("GEN_PARAM_DEFAULT"), MT_Expression, MF_Null }), (Macro { txt("struct_init"), MT_Expression, MF_Functional }), (Macro { txt("GEN_OPTIMIZE_MAPPINGS_BEGIN"), MT_Statement, MF_Null }), - (Macro { txt("GEN_OPITMIZE_MAPPINGS_END"), MT_Statement, MF_Null }) + (Macro { txt("GEN_OPITMIZE_MAPPINGS_END"), MT_Statement, MF_Null }), + (Macro { txt("src_line_str"), MT_Expression, MF_Null }) )); // gen_dep.hpp diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index c38bea2..c821170 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -325,18 +325,23 @@ if ( $unreal ) . $refactor_unreal } +# C Library testing if ( $test ) { - $path_test_c_lib = join-path $path_test c_library - $path_build = join-path $path_test_c_lib build - + $path_test_c = join-path $path_test c_library + $path_build = join-path $path_test_c build + $path_gen = join-path $path_test_c gen if ( -not(Test-Path($path_build) )) { New-Item -ItemType Directory -Path $path_build } + if ( -not(Test-Path($path_gen) )) { + New-Item -ItemType Directory -Path $path_gen + } - $includes = @( $path_c_library ) - $unit = join-path $path_test_c_lib "gen.c" - $executable = join-path $path_build "gen_c_library_test.exe" + $path_singleheader_include = join-path $path_c_library gen + $includes = @( $path_singleheader_include ) + $unit = join-path $path_test_c "test.c" + $executable = join-path $path_build "test.exe" $compiler_args = @() $compiler_args += ( $flag_define + 'GEN_TIME' ) @@ -350,7 +355,46 @@ if ( $test ) $result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable - Push-Location $path_test_c_lib + Push-Location $path_test_c + if ( Test-Path( $executable ) ) { + write-host "`nRunning c_library test" + $time_taken = Measure-Command { & $executable + | ForEach-Object { + write-host `t $_ -ForegroundColor Green + } + } + write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms" + } + Pop-Location +} + +if ($test) +{ + $path_test_cpp = join-path $path_test cpp_library + $path_build = join-path $path_test_cpp build + $path_gen = join-path $path_test_cpp gen + if ( -not(Test-Path($path_build) )) { + New-Item -ItemType Directory -Path $path_build + } + if ( -not(Test-Path($path_gen) )) { + New-Item -ItemType Directory -Path $path_gen + } + + $path_singleheader_include = join-path $path_singleheader gen + $includes = @( $path_singleheader_include ) + $unit = join-path $path_test_cpp "test.cpp" + $executable = join-path $path_build "test.exe" + + $compiler_args = @() + $compiler_args += ( $flag_define + 'GEN_TIME' ) + + $linker_args = @( + $flag_link_win_subsystem_console + ) + + $result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable + + Push-Location $path_test_cpp if ( Test-Path( $executable ) ) { write-host "`nRunning c_library test" $time_taken = Measure-Command { & $executable diff --git a/test/c_library/gen.c b/test/c_library/gen.c deleted file mode 100644 index 30ff855..0000000 --- a/test/c_library/gen.c +++ /dev/null @@ -1,9 +0,0 @@ -#define GEN_IMPLEMENTATION -#include "gen/gen_singleheader.h" - -int gen_main() -{ - // init(); - __debugbreak(); - return 0; -} diff --git a/test/c_library/test.c b/test/c_library/test.c new file mode 100644 index 0000000..78e7ccd --- /dev/null +++ b/test/c_library/test.c @@ -0,0 +1,33 @@ +#define GEN_IMPLEMENTATION +#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS +#define GEN_ENFORCE_STRONG_CODE_TYPES +#include "gen_singleheader.h" + +#define gen_iterator( Type, container, iter ) \ + gen_begin_ ## Type(container); \ + iter != gen_end_ ## Type(container); \ + code = gen_next_ ## Type(container, iter) + +int main() +{ + gen_Context ctx = {0}; + gen_init(& ctx); + + gen_Builder src_hello = gen_builder_open("gen/hello.c"); + gen_CodeVar hello_var = gen_parse_variable(code( + char const* hello_gencpp_str = "HELLO GENCPP C11 !"; + )); + gen_builder_print( & src_hello, (gen_Code)hello_var ); + gen_builder_write(& src_hello); + + gen_CodeBody body = gen_parse_file("gen/hello.c"); + for (gen_Code code = gen_iterator(CodeBody, body, code)) switch (code->Type) { + case CT_Variable: + gen_CodeVar var = (gen_CodeVar) code; + gen_log_fmt("%S", var->Value); + break; + } + + gen_deinit(& ctx); + return 0; +} diff --git a/test/cpp_library/test.cpp b/test/cpp_library/test.cpp new file mode 100644 index 0000000..8ee2088 --- /dev/null +++ b/test/cpp_library/test.cpp @@ -0,0 +1,29 @@ +#define GEN_IMPLEMENTATION +#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS +#define GEN_ENFORCE_STRONG_CODE_TYPES +#include "gen.hpp" + +int main() +{ + using namespace gen; + Context ctx = {}; + gen::init( & ctx); + + Builder src_hello = builder_open("gen/hello.cpp"); + CodeVar hello_var = parse_variable( code( + constexpr char const* hello_gencpp_str = "HELLO GENCPP !"; + )); + src_hello.print(hello_var); + src_hello.write(); + + CodeBody body = parse_file("gen/hello.cpp"); + for ( Code code : body ) switch (code->Type) { + case CT_Variable: + CodeVar var = cast(CodeVar, code); + log_fmt("%S", var->Value); + break; + } + + gen::deinit(& ctx); + return 0; +}