From 6d04165b96d6838fd2c49b49bd97bf3f3a0c75d6 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 30 Nov 2024 18:54:19 -0500 Subject: [PATCH] Reduce cpp freatures usage of Array container. Almost ready to be inter-operable with C --- gen_c_library/c_library.cpp | 40 +++++++++++++ project/components/interface.cpp | 57 +++++++++--------- project/components/lexer.cpp | 40 ++++++------- project/components/parser.cpp | 26 ++++----- project/dependencies/containers.hpp | 90 ++++++++++++++++++----------- project/dependencies/filesystem.cpp | 14 ++--- project/dependencies/macros.hpp | 10 +++- project/dependencies/parsing.cpp | 46 +++++++-------- project/dependencies/platform.hpp | 2 + project/helpers/helper.hpp | 10 ++-- scripts/build.ci.ps1 | 33 +++++++++++ 11 files changed, 235 insertions(+), 133 deletions(-) diff --git a/gen_c_library/c_library.cpp b/gen_c_library/c_library.cpp index adbe936..4d8ea1a 100644 --- a/gen_c_library/c_library.cpp +++ b/gen_c_library/c_library.cpp @@ -18,6 +18,32 @@ GEN_NS_END using namespace gen; +constexpr char const* generation_notice = +"// This file was generated automatially by gencpp's c_library.cpp" +"(See: https://github.com/Ed94/gencpp)\n\n"; + +constexpr StrC roll_own_dependencies_guard_start = txt(R"( +//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. +// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl +#ifndef GEN_ROLL_OWN_DEPENDENCIES +)"); + +constexpr StrC roll_own_dependencies_guard_end = txt(R"( +// GEN_ROLL_OWN_DEPENDENCIES +#endif +)"); + +constexpr StrC implementation_guard_start = txt(R"( +#pragma region GENCPP IMPLEMENTATION GUARD +#if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED) +# define GEN_IMPLEMENTED +)"); + +constexpr StrC implementation_guard_end = txt(R"( +#endif +#pragma endregion GENCPP IMPLEMENTATION GUARD +)"); + void format_file( char const* path ) { String resolved_path = String::make(GlobalAllocator, to_str(path)); @@ -59,6 +85,20 @@ int gen_main() #define project_dir "../project/" gen::init(); + Code push_ignores = scan_file( project_dir "helpers/push_ignores.inline.hpp" ); + Code pop_ignores = scan_file( project_dir "helpers/pop_ignores.inline.hpp" ); + Code single_header_start = scan_file( "components/header_start.hpp" ); + + Builder + header = Builder::open( "gen/gen.hpp" ); + header.print_fmt( generation_notice ); + header.print_fmt("#pragma once\n\n"); + header.print( push_ignores ); + + // Headers + { + + } gen::deinit(); return 0; diff --git a/project/components/interface.cpp b/project/components/interface.cpp index f4fe0ee..3d22496 100644 --- a/project/components/interface.cpp +++ b/project/components/interface.cpp @@ -11,7 +11,7 @@ internal void deinit(); internal void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) { - Arena* last = & Global_AllocatorBuckets.back(); + Arena* last = & back(Global_AllocatorBuckets); switch ( type ) { @@ -24,10 +24,10 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s if ( bucket.PhysicalStart == nullptr ) GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets"); - if ( ! Global_AllocatorBuckets.append( bucket ) ) + if ( ! append( Global_AllocatorBuckets, bucket ) ) GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets"); - last = & Global_AllocatorBuckets.back(); + last = & back(Global_AllocatorBuckets); } return alloc_align( allocator_info(* last), size, alignment ); @@ -51,10 +51,10 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s if ( bucket.PhysicalStart == nullptr ) GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets"); - if ( ! Global_AllocatorBuckets.append( bucket ) ) + if ( ! append( Global_AllocatorBuckets, bucket ) ) GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets"); - last = & Global_AllocatorBuckets.back(); + last = & back(Global_AllocatorBuckets); } void* result = alloc_align( last->Backing, size, alignment ); @@ -235,7 +235,7 @@ void init() { GlobalAllocator = AllocatorInfo { & Global_Allocator_Proc, nullptr }; - Global_AllocatorBuckets = Array::init_reserve( heap(), 128 ); + Global_AllocatorBuckets = array_init_reserve( heap(), 128 ); if ( Global_AllocatorBuckets == nullptr ) GEN_FATAL( "Failed to reserve memory for Global_AllocatorBuckets"); @@ -245,18 +245,17 @@ void init() if ( bucket.PhysicalStart == nullptr ) GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets"); - Global_AllocatorBuckets.append( bucket ); - + append( Global_AllocatorBuckets, bucket ); } // Setup the arrays { - CodePools = Array::init_reserve( Allocator_DataArrays, InitSize_DataArrays ); + CodePools = array_init_reserve( Allocator_DataArrays, InitSize_DataArrays ); if ( CodePools == nullptr ) GEN_FATAL( "gen::init: Failed to initialize the CodePools array" ); - StringArenas = Array::init_reserve( Allocator_DataArrays, InitSize_DataArrays ); + StringArenas = array_init_reserve( Allocator_DataArrays, InitSize_DataArrays ); if ( StringArenas == nullptr ) GEN_FATAL( "gen::init: Failed to initialize the StringArenas array" ); @@ -269,7 +268,7 @@ void init() if ( code_pool.PhysicalStart == nullptr ) GEN_FATAL( "gen::init: Failed to initialize the code pool" ); - CodePools.append( code_pool ); + append(CodePools, code_pool ); LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size ); @@ -278,7 +277,7 @@ void init() if ( string_arena.PhysicalStart == nullptr ) GEN_FATAL( "gen::init: Failed to initialize the string arena" ); - StringArenas.append( string_arena ); + append(StringArenas, string_arena ); } // Setup the hash tables @@ -290,7 +289,7 @@ void init() } // Preprocessor Defines - PreprocessorDefines = Array::init_reserve( GlobalAllocator, kilobytes(1) ); + PreprocessorDefines = array_init_reserve( GlobalAllocator, kilobytes(1) ); define_constants(); parser::init(); @@ -299,7 +298,7 @@ void init() void deinit() { usize index = 0; - usize left = CodePools.num(); + usize left = num(CodePools); do { Pool* code_pool = & CodePools[index]; @@ -309,7 +308,7 @@ void deinit() while ( left--, left ); index = 0; - left = StringArenas.num(); + left = num(StringArenas); do { Arena* string_arena = & StringArenas[index]; @@ -320,15 +319,15 @@ void deinit() StringCache.destroy(); - CodePools.free(); - StringArenas.free(); + free(CodePools); + free(StringArenas); free(LexArena); - PreprocessorDefines.free(); + free(PreprocessorDefines); index = 0; - left = Global_AllocatorBuckets.num(); + left = num(Global_AllocatorBuckets); do { Arena* bucket = & Global_AllocatorBuckets[ index ]; @@ -337,14 +336,14 @@ void deinit() } while ( left--, left ); - Global_AllocatorBuckets.free(); + free(Global_AllocatorBuckets); parser::deinit(); } void reset() { s32 index = 0; - s32 left = CodePools.num(); + s32 left = num(CodePools); do { Pool* code_pool = & CodePools[index]; @@ -354,7 +353,7 @@ void reset() while ( left--, left ); index = 0; - left = StringArenas.num(); + left = num(StringArenas); do { Arena* string_arena = & StringArenas[index]; @@ -363,14 +362,14 @@ void reset() } while ( left--, left ); - StringCache.clear(); + clear(StringCache); define_constants(); } AllocatorInfo get_string_allocator( s32 str_length ) { - Arena* last = & StringArenas.back(); + Arena* last = & back(StringArenas); usize size_req = str_length + sizeof(StringHeader) + sizeof(char*); @@ -378,10 +377,10 @@ AllocatorInfo get_string_allocator( s32 str_length ) { Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena ); - if ( ! StringArenas.append( new_arena ) ) + if ( ! append(StringArenas, new_arena ) ) GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" ); - last = & StringArenas.back(); + last = & back(StringArenas); } return allocator_info(* last); @@ -408,7 +407,7 @@ StringCached get_cached_string( StrC str ) // Used internally to retireve a Code object form the CodePool. Code make_code() { - Pool* allocator = & CodePools.back(); + Pool* allocator = & back(CodePools); if ( allocator->FreeList == nullptr ) { Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) ); @@ -416,10 +415,10 @@ Code make_code() if ( code_pool.PhysicalStart == nullptr ) GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." ); - if ( ! CodePools.append( code_pool ) ) + if ( ! append( CodePools, code_pool ) ) GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." ); - allocator = & CodePools.back(); + allocator = & back(CodePools); } Code result { rcast( AST*, alloc( allocator_info(* allocator), sizeof(AST) )) }; diff --git a/project/components/lexer.cpp b/project/components/lexer.cpp index 4587544..12788a8 100644 --- a/project/components/lexer.cpp +++ b/project/components/lexer.cpp @@ -222,7 +222,7 @@ s32 lex_preprocessor_directive( , Token& token ) { char const* hash = scanner; - Tokens.append( { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } ); + append(Tokens, { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } ); move_forward(); SkipWhitespace(); @@ -298,14 +298,14 @@ s32 lex_preprocessor_directive( token.Length = token.Length + token.Text - hash; token.Text = hash; - Tokens.append( token ); + append(Tokens, token ); return Lex_Continue; // Skip found token, its all handled here. } if ( token.Type == TokType::Preprocess_Else || token.Type == TokType::Preprocess_EndIf ) { token.Flags |= TF_Preprocess_Cond; - Tokens.append( token ); + append(Tokens, token ); end_line(); return Lex_Continue; } @@ -314,7 +314,7 @@ s32 lex_preprocessor_directive( token.Flags |= TF_Preprocess_Cond; } - Tokens.append( token ); + append(Tokens, token ); SkipWhitespace(); @@ -338,7 +338,7 @@ s32 lex_preprocessor_directive( name.Length++; } - Tokens.append( name ); + append(Tokens, name ); u64 key = crc32( name.Text, name.Length ); defines.set( key, name ); @@ -384,7 +384,7 @@ s32 lex_preprocessor_directive( move_forward(); } - Tokens.append( preprocess_content ); + append(Tokens, preprocess_content ); return Lex_Continue; // Skip found token, its all handled here. } @@ -446,7 +446,7 @@ s32 lex_preprocessor_directive( preprocess_content.Length++; } - Tokens.append( preprocess_content ); + append(Tokens, preprocess_content ); return Lex_Continue; // Skip found token, its all handled here. } @@ -461,7 +461,7 @@ void lex_found_token( StrC& content { if ( token.Type != TokType::Invalid ) { - Tokens.append( token ); + append(Tokens, token ); return; } @@ -488,7 +488,7 @@ void lex_found_token( StrC& content } token.Type = type; - Tokens.append( token ); + append(Tokens, token ); return; } @@ -498,7 +498,7 @@ void lex_found_token( StrC& content { token.Type = type; token.Flags |= TF_Specifier; - Tokens.append( token ); + append(Tokens, token ); return; } @@ -506,7 +506,7 @@ void lex_found_token( StrC& content if ( type != TokType::Invalid ) { token.Type = type; - Tokens.append( token ); + append(Tokens, token ); return; } @@ -558,7 +558,7 @@ void lex_found_token( StrC& content token.Type = TokType::Identifier; } - Tokens.append( token ); + append(Tokens, token ); } @@ -582,7 +582,7 @@ TokArray lex( StrC content ) return { { nullptr }, 0 }; } - for ( StringCached entry : PreprocessorDefines ) + foreach( StringCached, entry, PreprocessorDefines ) { s32 length = 0; char const* scanner = entry.Data; @@ -600,7 +600,7 @@ TokArray lex( StrC content ) defines.set( key, entry ); } - Tokens.clear(); + clear(Tokens); while (left ) { @@ -630,7 +630,7 @@ TokArray lex( StrC content ) token.Type = TokType::NewLine; token.Length++; - Tokens.append( token ); + append(Tokens, token ); continue; } } @@ -1099,7 +1099,7 @@ TokArray lex( StrC content ) move_forward(); token.Length++; } - Tokens.append( token ); + append(Tokens, token ); continue; } else if ( current == '*' ) @@ -1135,7 +1135,7 @@ TokArray lex( StrC content ) move_forward(); token.Length++; } - Tokens.append( token ); + append(Tokens, token ); // end_line(); continue; } @@ -1228,9 +1228,9 @@ TokArray lex( StrC content ) } else { - s32 start = max( 0, Tokens.num() - 100 ); + s32 start = max( 0, num(Tokens) - 100 ); log_fmt("\n%d\n", start); - for ( s32 idx = start; idx < Tokens.num(); idx++ ) + for ( s32 idx = start; idx < num(Tokens); idx++ ) { log_fmt( "Token %d Type: %s : %.*s\n" , idx @@ -1253,7 +1253,7 @@ TokArray lex( StrC content ) lex_found_token( content, left, scanner, line, column, defines, token ); } - if ( Tokens.num() == 0 ) + if ( num(Tokens) == 0 ) { log_failure( "Failed to lex any tokens" ); return { { nullptr }, 0 }; diff --git a/project/components/parser.cpp b/project/components/parser.cpp index 94e5315..2c19973 100644 --- a/project/components/parser.cpp +++ b/project/components/parser.cpp @@ -48,11 +48,11 @@ struct ParseContext String result = String::make_reserve( GlobalAllocator, kilobytes(4) ); Token scope_start = Scope->Start; - Token last_valid = Tokens.Idx >= Tokens.Arr.num() ? Tokens.Arr[Tokens.Arr.num() -1] : Tokens.current(); + Token last_valid = Tokens.Idx >= num(Tokens.Arr) ? Tokens.Arr[num(Tokens.Arr) -1] : Tokens.current(); sptr length = scope_start.Length; char const* current = scope_start.Text + length; - while ( current <= Tokens.Arr.back().Text && *current != '\n' && length < 74 ) + while ( current <= back(Tokens.Arr).Text && *current != '\n' && length < 74 ) { current++; length++; @@ -96,7 +96,7 @@ global ParseContext Context; bool TokArray::__eat( TokType type ) { - if ( Arr.num() - Idx <= 0 ) + if ( num(Arr) - Idx <= 0 ) { log_failure( "No tokens left.\n%s", Context.to_string() ); return false; @@ -167,7 +167,7 @@ if ( def.Ptr == nullptr ) \ # define prevtok Context.Tokens.previous() # define nexttok Context.Tokens.next() # define eat( Type_ ) Context.Tokens.__eat( Type_ ) -# define left ( Context.Tokens.Arr.num() - Context.Tokens.Idx ) +# define left ( num(Context.Tokens.Arr) - Context.Tokens.Idx ) #ifdef check #define CHECK_WAS_DEFINED @@ -745,7 +745,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) } Token interface_tok = parse_identifier(); - interfaces.append( def_type( interface_tok ) ); + append(interfaces, def_type( interface_tok ) ); // : , ... } } @@ -777,7 +777,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) if ( inline_cmt ) result->InlineCmt = inline_cmt; - interfaces.free(); + free(interfaces); return result; } @@ -1152,7 +1152,7 @@ Code parse_complicated_definition( TokType which ) s32 idx = tokens.Idx; s32 level = 0; - for ( ; idx < tokens.Arr.num(); idx++ ) + for ( ; idx < num(tokens.Arr); idx++ ) { if ( tokens[ idx ].Type == TokType::BraceCurly_Open ) level++; @@ -1837,7 +1837,7 @@ CodeBody parse_global_nspace( CodeT which ) bool found_operator_cast_outside_class_implmentation = false; s32 idx = Context.Tokens.Idx; - for ( ; idx < Context.Tokens.Arr.num(); idx++ ) + for ( ; idx < num(Context.Tokens.Arr); idx++ ) { Token tok = Context.Tokens[ idx ]; @@ -1909,14 +1909,14 @@ Code parse_global_nspace_constructor_destructor( CodeSpecifiers specifiers ) s32 idx = tokens.Idx; Token nav = tokens[ idx ]; - for ( ; idx < tokens.Arr.num(); idx++, nav = tokens[ idx ] ) + for ( ; idx < num(tokens.Arr); idx++, nav = tokens[ idx ] ) { if ( nav.Text[0] == '<' ) { // Skip templated expressions as they mey have expressions with the () operators s32 capture_level = 0; s32 template_level = 0; - for ( ; idx < tokens.Arr.num(); idx++, nav = tokens[idx] ) + for ( ; idx < num(tokens.Arr); idx++, nav = tokens[idx] ) { if (nav.Text[ 0 ] == '<') ++ template_level; @@ -2511,7 +2511,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes bool found_operator = false; s32 idx = Context.Tokens.Idx; - for ( ; idx < Context.Tokens.Arr.num(); idx++ ) + for ( ; idx < num(Context.Tokens.Arr); idx++ ) { Token tok = Context.Tokens[ idx ]; @@ -4348,7 +4348,7 @@ CodeTemplate parse_template() bool found_operator_cast_outside_class_implmentation = false; s32 idx = Context.Tokens.Idx; - for ( ; idx < Context.Tokens.Arr.num(); idx++ ) + for ( ; idx < num(Context.Tokens.Arr); idx++ ) { Token tok = Context.Tokens[ idx ]; @@ -4896,7 +4896,7 @@ CodeTypedef parse_typedef() s32 idx = tokens.Idx; s32 level = 0; - for ( ; idx < tokens.Arr.num(); idx ++ ) + for ( ; idx < num(tokens.Arr); idx ++ ) { if ( tokens[idx].Type == TokType::BraceCurly_Open ) level++; diff --git a/project/dependencies/containers.hpp b/project/dependencies/containers.hpp index d185b24..9c12af2 100644 --- a/project/dependencies/containers.hpp +++ b/project/dependencies/containers.hpp @@ -14,12 +14,26 @@ template using TRemoveConst = typename RemoveConst::Type; #pragma region Array +#if ! GEN_COMPILER_C +#define Array(Type) Array + +// #define array_init(Type, ...) array_init (__VA_ARGS__) +// #define array_init_reserve(Type, ...) array_init_reserve(__VA_ARGS__) +#endif + struct ArrayHeader; + +#if GEN_SUPPORT_CPP_MEMBER_FEATURES template struct Array; +#else +template +using Array = Type*; +#endif + +usize array_grow_formula(ssize value); template Array array_init(AllocatorInfo allocator); template Array array_init_reserve(AllocatorInfo allocator, ssize capacity); -template usize array_grow_formula(ssize value); template bool append(Array& array, Array other); template bool append(Array& array, Type value); template bool append(Array& array, Type* items, usize item_num); @@ -38,18 +52,22 @@ template bool resize(Array& array, usize num); template bool set_capacity(Array& array, usize new_capacity); template ArrayHeader* get_header(Array& array); +template forceinline Type* begin(Array& array) { return array; } +template forceinline Type* end(Array& array) { return array + get_header(array)->Num; } +template forceinline Type* next(Type* entry) { return entry + 1; } + struct ArrayHeader { AllocatorInfo Allocator; usize Capacity; usize Num; }; +#if GEN_SUPPORT_CPP_MEMBER_FEATURES template struct Array { Type* Data; -#if 1 #pragma region Member Mapping forceinline static Array init(AllocatorInfo allocator) { return GEN_NS array_init(allocator); } forceinline static Array init_reserve(AllocatorInfo allocator, ssize capacity) { return GEN_NS array_init_reserve(allocator, capacity); } @@ -78,12 +96,12 @@ struct Array forceinline Type* begin() { return Data; } forceinline Type* end() { return Data + get_header()->Num; } #pragma endregion Member Mapping -#endif }; +#endif template inline Array array_init(AllocatorInfo allocator) { - return array_init_reserve(allocator, array_grow_formula(0)); + return array_init_reserve(allocator, array_grow_formula(0)); } template inline @@ -101,7 +119,6 @@ Array array_init_reserve(AllocatorInfo allocator, ssize capacity) return {rcast(Type*, header + 1)}; } -template inline usize array_grow_formula(ssize value) { return 2 * value + 8; } @@ -123,7 +140,7 @@ bool append(Array& array, Type value) header = get_header(array); } - array.Data[header->Num] = value; + array[header->Num] = value; header->Num++; return true; @@ -166,7 +183,7 @@ bool append_at(Array& array, Type item, usize idx) header = get_header(array); } - Type* target = array.Data + idx; + Type* target = array + idx; mem_move(target + 1, target, (header->Num - idx) * sizeof(Type)); header->Num++; @@ -205,7 +222,7 @@ bool append_at(Array& array, Type* items, usize item_num, usize idx) template inline Type& back(Array& array) { ArrayHeader* header = get_header(array); - return array.Data[header->Num - 1]; + return array[header->Num - 1]; } template inline @@ -224,7 +241,7 @@ bool fill(Array& array, usize begin, usize end, Type value) for (ssize idx = ssize(begin); idx < ssize(end); idx++) { - array.Data[idx] = value; + array[idx] = value; } return true; @@ -234,20 +251,22 @@ template inline void free(Array& array) { ArrayHeader* header = get_header(array); gen::free(header->Allocator, header); - array.Data = nullptr; + Type*& Data = rcast(Type*&, array); + Data = nullptr; } template inline ArrayHeader* get_header(Array& array) { using NonConstType = TRemoveConst; - return rcast(ArrayHeader*, const_cast(array.Data)) - 1; + Type* Data = array; // This should do nothing in C but in C++ gets member Data struct. + return rcast(ArrayHeader*, const_cast(Data)) - 1; } template inline bool grow(Array& array, usize min_capacity) { ArrayHeader* header = get_header(array); - usize new_capacity = array_grow_formula(header->Capacity); + usize new_capacity = array_grow_formula(header->Capacity); if (new_capacity < min_capacity) new_capacity = min_capacity; @@ -273,7 +292,7 @@ void remove_at(Array& array, usize idx) ArrayHeader* header = get_header(array); GEN_ASSERT(idx < header->Num); - mem_move(array.Data + idx, array.Data + idx + 1, sizeof(Type) * (header->Num - idx - 1)); + mem_move(array + idx, array + idx + 1, sizeof(Type) * (header->Num - idx - 1)); header->Num--; } @@ -329,7 +348,8 @@ bool set_capacity(Array& array, usize new_capacity) GEN_NS free(header->Allocator, header); - array.Data = rcast(Type*, new_header + 1); + Type*& Data = rcast(Type*&, array); + Data = rcast(Type*, new_header + 1); return true; } #pragma endregion Array @@ -371,11 +391,11 @@ template bool full(HashTable& table); template void map(HashTable& table, void (*map_proc)(u64 key, Type value)); template void map_mut(HashTable& table, void (*map_proc)(u64 key, Type* value)); +static constexpr f32 HashTable_CriticalLoadScale = 0.7f; + template struct HashTable { - static constexpr f32 CriticalLoadScale = 0.7f; - Array Hashes; Array> Entries; @@ -411,26 +431,26 @@ HashTable hashtable_init_reserve(AllocatorInfo allocator, usize num) { HashTable result = { { nullptr }, { nullptr } }; - result.Hashes = Array::init_reserve(allocator, num); - result.Hashes.get_header()->Num = num; - result.Hashes.resize(num); - result.Hashes.fill(0, num, -1); + result.Hashes = array_init_reserve(allocator, num); + get_header(result.Hashes)->Num = num; + resize(result.Hashes, num); + fill(result.Hashes, 0, num, -1); - result.Entries = Array>::init_reserve(allocator, num); + result.Entries = array_init_reserve>(allocator, num); return result; } template inline void clear(HashTable& table) { - table.Entries.clear(); - table.Hashes.fill(0, table.Hashes.num(), -1); + clear(table.Entries); + fill(table.Hashes, 0, num(table.Hashes), -1); } template inline void destroy(HashTable& table) { - if (table.Hashes && table.Hashes.get_header()->Capacity) { - table.Hashes.free(); - table.Entries.free(); + if (table.Hashes && get_header(table.Hashes)->Capacity) { + free(table.Hashes); + free(table.Entries); } } @@ -463,7 +483,7 @@ void map_mut(HashTable& table, void (*map_proc)(u64 key, Type* value)) { template inline void grow(HashTable& table) { - ssize new_num = Array>::grow_formula(table.Entries.num()); + ssize new_num = array_grow_formula(num(table.Entries)); rehash(table, new_num); } @@ -471,9 +491,9 @@ template inline void rehash(HashTable& table, ssize new_num) { ssize last_added_index; - HashTable new_ht = hashtable_init_reserve(table.Hashes.get_header()->Allocator, new_num); + HashTable new_ht = hashtable_init_reserve(get_header(table.Hashes)->Allocator, new_num); - for (ssize idx = 0; idx < ssize(table.Entries.num()); ++idx) + for (ssize idx = 0; idx < ssize(num(table.Entries)); ++idx) { HashTableFindResult find_result; HashTableEntry& entry = table.Entries[idx]; @@ -580,8 +600,8 @@ ssize add_entry(HashTable& table, u64 key) { ssize idx; HashTableEntry entry = { key, -1 }; - idx = table.Entries.num(); - table.Entries.append(entry); + idx = num(table.Entries); + append(table.Entries, entry); return idx; } @@ -590,9 +610,9 @@ HashTableFindResult find(HashTable& table, u64 key) { HashTableFindResult result = { -1, -1, -1 }; - if (table.Hashes.num() > 0) + if (num(table.Hashes) > 0) { - result.HashIndex = key % table.Hashes.num(); + result.HashIndex = key % num(table.Hashes); result.EntryIndex = table.Hashes[result.HashIndex]; while (result.EntryIndex >= 0) @@ -610,8 +630,8 @@ HashTableFindResult find(HashTable& table, u64 key) template inline bool full(HashTable& table) { - usize critical_load = usize(HashTable::CriticalLoadScale * f32(table.Hashes.num())); - b32 result = table.Entries.num() > critical_load; + usize critical_load = usize(HashTable_CriticalLoadScale * f32(num(table.Hashes))); + b32 result = num(table.Entries) > critical_load; return result; } #pragma endregion HashTable diff --git a/project/dependencies/filesystem.cpp b/project/dependencies/filesystem.cpp index c6c0444..931f9cd 100644 --- a/project/dependencies/filesystem.cpp +++ b/project/dependencies/filesystem.cpp @@ -505,7 +505,7 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator ) d->allocator = allocator; d->flags = EFileStream_CLONE_WRITABLE; d->cap = 0; - d->buf = Array::init( allocator ); + d->buf = array_init( allocator ); if ( ! d->buf ) return false; @@ -531,7 +531,7 @@ b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize d->flags = flags; if ( d->flags & EFileStream_CLONE_WRITABLE ) { - Array arr = Array::init_reserve( allocator, size ); + Array arr = array_init_reserve( allocator, size ); d->buf = arr; if ( ! d->buf ) @@ -540,7 +540,7 @@ b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize mem_copy( d->buf, buffer, size ); d->cap = size; - arr.get_header()->Num = size; + get_header(arr)->Num = size; } else { @@ -610,9 +610,9 @@ GEN_FILE_WRITE_AT_PROC( _memory_file_write ) { Array arr = { d->buf }; - if ( arr.get_header()->Capacity < usize(new_cap) ) + if ( get_header(arr)->Capacity < usize(new_cap) ) { - if ( ! arr.grow( ( s64 )( new_cap ) ) ) + if ( ! grow( arr, ( s64 )( new_cap ) ) ) return false; d->buf = arr; } @@ -626,7 +626,7 @@ GEN_FILE_WRITE_AT_PROC( _memory_file_write ) mem_copy( d->buf + offset + rwlen, pointer_add_const( buffer, rwlen ), extralen ); d->cap = new_cap; - arr.get_header()->Capacity = new_cap; + get_header(arr)->Capacity = new_cap; } else { @@ -647,7 +647,7 @@ GEN_FILE_CLOSE_PROC( _memory_file_close ) if ( d->flags & EFileStream_CLONE_WRITABLE ) { Array arr = { d->buf }; - arr.free(); + free(arr); } free( allocator, d ); diff --git a/project/dependencies/macros.hpp b/project/dependencies/macros.hpp index 41ee2d6..790f1b4 100644 --- a/project/dependencies/macros.hpp +++ b/project/dependencies/macros.hpp @@ -187,7 +187,7 @@ #if !defined(typeof) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L) # if ! GEN_COMPILER_C -# define typeof +# define typeof decltype # elif defined(_MSC_VER) # define typeof(x) __typeof(x) # elif defined(__GNUC__) || defined(__clang__) @@ -197,4 +197,12 @@ # endif #endif +// This is intended to only really be used internally or with the C-library variant +// C++ users can just use the for-range directly. +#if GEN_COMPILER_C +# define foreach(Type, entry_id, iterable) for ( Type entry_id = begin(iterable); entry_id != end(iterable); entry_id = next(entry_id) ) +#else +# define foreach(Type, entry_id, iterable) for ( Type entry_id : iterable ) +#endif + #pragma endregion Macros diff --git a/project/dependencies/parsing.cpp b/project/dependencies/parsing.cpp index 293555e..c314218 100644 --- a/project/dependencies/parsing.cpp +++ b/project/dependencies/parsing.cpp @@ -23,7 +23,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( backing ); if ( ! node->nodes ) return EADT_ERROR_OUT_OF_MEMORY; @@ -36,12 +36,12 @@ u8 adt_destroy_branch( ADT_Node* node ) GEN_ASSERT_NOT_NULL( node ); if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes ) { - for ( ssize i = 0; i < scast(ssize, node->nodes.num()); ++i ) + for ( ssize i = 0; i < scast(ssize, num(node->nodes)); ++i ) { adt_destroy_branch( node->nodes + i ); } - node->nodes.free(); + free(node->nodes); } return 0; } @@ -66,7 +66,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ) return NULL; } - for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ ) + for ( ssize i = 0; i < scast(ssize, num(node->nodes)); i++ ) { if ( ! str_compare( node->nodes[ i ].name, name ) ) { @@ -76,7 +76,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ) if ( deep_search ) { - for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ ) + for ( ssize i = 0; i < scast(ssize, num(node->nodes)); i++ ) { ADT_Node* res = adt_find( node->nodes + i, name, deep_search ); @@ -132,7 +132,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value ) internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value ) { - for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ ) + for ( ssize i = 0; i < scast(ssize, num(node->nodes)); i++ ) { if ( ! str_compare( node->nodes[ i ].name, name ) ) { @@ -207,7 +207,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) /* run a value comparison against any child that is an object node */ else if ( node->type == EADT_TYPE_ARRAY ) { - for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ ) + for ( ssize i = 0; i < scast(ssize, num(node->nodes)); i++ ) { ADT_Node* child = &node->nodes[ i ]; if ( child->type != EADT_TYPE_OBJECT ) @@ -225,7 +225,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) /* [value] */ else { - for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ ) + for ( ssize i = 0; i < scast(ssize, num(node->nodes)); i++ ) { ADT_Node* child = &node->nodes[ i ]; if ( _adt_get_value( child, l_b2 ) ) @@ -257,7 +257,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) else { ssize idx = ( ssize )str_to_i64( buf, NULL, 10 ); - if ( idx >= 0 && idx < scast(ssize, node->nodes.num()) ) + if ( idx >= 0 && idx < scast(ssize, num(node->nodes)) ) { found_node = &node->nodes[ idx ]; @@ -282,12 +282,12 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index ) if ( ! parent->nodes ) return NULL; - if ( index < 0 || index > scast(ssize, parent->nodes.num()) ) + if ( index < 0 || index > scast(ssize, num(parent->nodes)) ) return NULL; ADT_Node o = { 0 }; o.parent = parent; - if ( ! parent->nodes.append_at( o, index ) ) + if ( ! append_at( parent->nodes, o, index ) ) return NULL; return parent->nodes + index; @@ -303,7 +303,7 @@ ADT_Node* adt_alloc( ADT_Node* parent ) if ( ! parent->nodes ) return NULL; - return adt_alloc_at( parent, parent->nodes.num() ); + return adt_alloc_at( parent, num(parent->nodes) ); } b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing ) @@ -357,7 +357,7 @@ ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent ) GEN_ASSERT_NOT_NULL( node ); GEN_ASSERT_NOT_NULL( new_parent ); GEN_ASSERT( new_parent->type == EADT_TYPE_ARRAY || new_parent->type == EADT_TYPE_OBJECT ); - return adt_move_node_at( node, new_parent, new_parent->nodes.num() ); + return adt_move_node_at( node, new_parent, num(new_parent->nodes) ); } void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node ) @@ -381,7 +381,7 @@ void adt_remove_node( ADT_Node* node ) GEN_ASSERT_NOT_NULL( node->parent ); ADT_Node* parent = node->parent; ssize index = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) ); - parent->nodes.remove_at( index ); + remove_at( parent->nodes, index ); } ADT_Node* adt_append_obj( ADT_Node* parent, char const* name ) @@ -389,7 +389,7 @@ ADT_Node* adt_append_obj( ADT_Node* parent, char const* name ) ADT_Node* o = adt_alloc( parent ); if ( ! o ) return NULL; - if ( adt_set_obj( o, name, parent->nodes.get_header()->Allocator ) ) + if ( adt_set_obj( o, name, get_header(parent->nodes)->Allocator ) ) { adt_remove_node( o ); return NULL; @@ -402,7 +402,7 @@ ADT_Node* adt_append_arr( ADT_Node* parent, char const* name ) ADT_Node* o = adt_alloc( parent ); if ( ! o ) return NULL; - if ( adt_set_arr( o, name, parent->nodes.get_header()->Allocator ) ) + if ( adt_set_arr( o, name, get_header(parent->nodes)->Allocator ) ) { adt_remove_node( o ); return NULL; @@ -946,12 +946,12 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b } } - if ( columnIndex >= scast(ssize, root->nodes.num()) ) + if ( columnIndex >= scast(ssize, num(root->nodes)) ) { adt_append_arr( root, NULL ); } - root->nodes[ columnIndex ].nodes.append( rowItem ); + append(root->nodes[ columnIndex ].nodes, rowItem ); if ( delimiter == delim ) { @@ -979,7 +979,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b } while ( *currentChar ); - if ( root->nodes.num() == 0 ) + if (num( root->nodes) == 0 ) { GEN_CSV_ASSERT( "unexpected end of input. stream is empty." ); error = ECSV_Error__UNEXPECTED_END_OF_INPUT; @@ -989,12 +989,12 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b /* consider first row as a header. */ if ( has_header ) { - for ( ssize i = 0; i < scast(ssize, root->nodes.num()); i++ ) + for ( ssize i = 0; i < scast(ssize, num(root->nodes)); i++ ) { CSV_Object* col = root->nodes + i; CSV_Object* hdr = col->nodes; col->name = hdr->string; - col->nodes.remove_at( 0 ); + remove_at(col->nodes, 0 ); } } @@ -1057,11 +1057,11 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter ) GEN_ASSERT_NOT_NULL( file ); GEN_ASSERT_NOT_NULL( obj ); GEN_ASSERT( obj->nodes ); - ssize cols = obj->nodes.num(); + ssize cols = num(obj->nodes); if ( cols == 0 ) return; - ssize rows = obj->nodes[ 0 ].nodes.num(); + ssize rows = num(obj->nodes[ 0 ].nodes); if ( rows == 0 ) return; diff --git a/project/dependencies/platform.hpp b/project/dependencies/platform.hpp index 272dadb..ca837af 100644 --- a/project/dependencies/platform.hpp +++ b/project/dependencies/platform.hpp @@ -1,3 +1,5 @@ +#define GEN_SUPPORT_CPP_MEMBER_FEATURES 1 + #ifdef GEN_INTELLISENSE_DIRECTIVES # pragma once #endif diff --git a/project/helpers/helper.hpp b/project/helpers/helper.hpp index 60a3e0d..fde3a3d 100644 --- a/project/helpers/helper.hpp +++ b/project/helpers/helper.hpp @@ -70,7 +70,7 @@ CodeBody gen_eoperator( char const* path ) String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(1) ); String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) ); - for (usize idx = 0; idx < enum_strs.num(); idx++) + for (usize idx = 0; idx < num(enum_strs); idx++) { char const* enum_str = enum_strs[idx].string; char const* entry_to_str = str_strs [idx].string; @@ -126,7 +126,7 @@ CodeBody gen_especifier( char const* path ) String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(1) ); String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) ); - for (usize idx = 0; idx < enum_strs.num(); idx++) + for (usize idx = 0; idx < num(enum_strs); idx++) { char const* enum_str = enum_strs[idx].string; char const* entry_to_str = str_strs [idx].string; @@ -243,7 +243,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) String to_str_attributes = String::make_reserve( GlobalAllocator, kilobytes(4) ); String attribute_define_entries = String::make_reserve( GlobalAllocator, kilobytes(4) ); - for (usize idx = 0; idx < enum_strs.num(); idx++) + for (usize idx = 0; idx < num(enum_strs); idx++) { char const* enum_str = enum_strs[idx].string; char const* entry_to_str = enum_str_strs [idx].string; @@ -252,7 +252,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); } - for ( usize idx = 0; idx < attribute_strs.num(); idx++ ) + for ( usize idx = 0; idx < num(attribute_strs); idx++ ) { char const* attribute_str = attribute_strs[idx].string; char const* entry_to_str = attribute_str_strs [idx].string; @@ -261,7 +261,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) to_str_attributes.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); attribute_define_entries.append_fmt( "Entry( Attribute_%s, \"%s\" )", attribute_str, entry_to_str ); - if ( idx < attribute_strs.num() - 1 ) + if ( idx < num(attribute_strs) - 1 ) attribute_define_entries.append( " \\\n"); else attribute_define_entries.append( "\n"); diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index 877d522..73cd1b3 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -192,7 +192,40 @@ if ( $singleheader ) if ( $c_library ) { + $path_build = join-path $path_c_library build + $path_gen = join-path $path_c_library 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_project ) + $unit = join-path $path_c_library "c_library.cpp" + $executable = join-path $path_build "c_library.exe" + + $compiler_args = @() + $compiler_args += ( $flag_define + 'GEN_TIME' ) + + $linker_args = @( + $flag_link_win_subsystem_console + ) + + build-simple $path_build $includes $compiler_args $linker_args $unit $executable + + Push-Location $path_singleheader + if ( Test-Path( $executable ) ) { + write-host "`nRunning c_library generator" + $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 ( $unreal )