From fec709cc7640eef46c43e0d31a60e7646b079ef3 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sun, 1 Dec 2024 21:59:43 -0500 Subject: [PATCH] Progresss --- docs/Readme.md | 2 + gen_c_library/c_library.cpp | 52 +++- .../components/memory.fixed_arena.hpp | 2 +- gen_c_library/components/misc.hpp | 6 +- gen_c_library/gen.c | 7 + project/Readme.md | 7 + project/components/interface.cpp | 34 +-- project/components/lexer.cpp | 30 +-- project/components/parser.cpp | 6 +- project/dependencies/containers.hpp | 231 +++++++++--------- project/dependencies/filesystem.cpp | 4 +- project/dependencies/parsing.cpp | 13 +- project/dependencies/parsing.hpp | 2 +- project/helpers/helper.hpp | 3 +- 14 files changed, 233 insertions(+), 166 deletions(-) create mode 100644 gen_c_library/gen.c diff --git a/docs/Readme.md b/docs/Readme.md index 7f2da37..4621d56 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -25,6 +25,8 @@ This library was written in a subset of C++ where the following are not used at * Exceptions Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads. +The base library itself does not use anything but C-like features to allow for generating a derviative compatiable with C (WIP). + There are only 4 template definitions in the entire library. (`Array`, `Hashtable`, `swap`, and `AST/Code::cast`) Two generic templated containers are used throughout the library: diff --git a/gen_c_library/c_library.cpp b/gen_c_library/c_library.cpp index f192f67..79baf1c 100644 --- a/gen_c_library/c_library.cpp +++ b/gen_c_library/c_library.cpp @@ -2,6 +2,7 @@ #define GEN_ENFORCE_STRONG_CODE_TYPES #define GEN_EXPOSE_BACKEND #define GEN_SUPPORT_CPP_MEMBER_FEATURES 1 +#define GEN_SUPPORT_CPP_REFERENCES 1 #include "../project/gen.cpp" #include "helpers/push_ignores.inline.hpp" @@ -135,26 +136,40 @@ int gen_main() case ECode::Using: { log_fmt("REPLACE THIS MANUALLY: %S\n", entry->Name); - CodeUsing using_ver = entry.cast(); + CodeUsing using_ver = entry.code_cast(); CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); memory.append(typedef_ver); } break; + case ECode::Function_Fwd: + { + CodeFn fn = entry.code_cast(); + if ( fn->Name.is_equal(txt("free")) ) + { + fn->Name = get_cached_string(txt("gen_free_ptr")); + } + memory.append(entry); + } + break; case ECode::Function: { - CodeFn fn = entry.cast(); + CodeFn fn = entry.code_cast(); s32 constexpr_found = fn->Specs.remove( ESpecifier::Constexpr ); if (constexpr_found > -1) { log_fmt("Found constexpr: %S\n", entry->to_string()); fn->Specs.append(ESpecifier::Inline); } + if ( fn->Name.is_equal(txt("free")) ) + { + fn->Name = get_cached_string(txt("gen_free_ptr")); + } memory.append(entry); } break; case ECode::Template: { - CodeTemplate tmpl = entry.cast(); + CodeTemplate tmpl = entry.code_cast(); if ( tmpl->Declaration->Name.contains(txt("swap"))) { CodeBody macro_swap = parse_global_body( txt(R"( @@ -297,7 +312,7 @@ int gen_main() { if ( entry->Name.is_equal(txt("String")) ) { - CodeTypedef c_def = parse_typedef(code( typedef Type* String; )); + CodeTypedef c_def = parse_typedef(code( typedef char* String; )); strings.append(c_def); strings.append(fmt_newline); ++ entry; @@ -307,6 +322,29 @@ int gen_main() } break; + case ECode::Struct: + { + CodeBody body = entry->Body->operator CodeBody(); + CodeBody new_body = def_body( entry->Body->Type ); + for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch + (body_entry->Type) { + case ECode::Preprocess_If: + { + b32 found = ignore_preprocess_cond_block(txt("! GEN_COMPILER_C"), body_entry, body ); + if (found) break; + + new_body.append(body_entry); + } + break; + default: + new_body.append(body_entry); + break; + } + entry->Body = rcast(AST*, new_body.ast); + strings.append(entry); + } + break; + default: strings.append(entry); break; @@ -316,8 +354,8 @@ int gen_main() Code filesystem = scan_file( project_dir "dependencies/filesystem.hpp" ); Code timing = scan_file( project_dir "dependencies/timing.hpp" ); - header.print( filesystem ); - header.print( timing ); + // header.print( filesystem ); + // header.print( timing ); header.print_fmt( "\nGEN_NS_END\n" ); header.print_fmt( roll_own_dependencies_guard_end ); @@ -335,6 +373,7 @@ int gen_main() CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv" ); CodeBody ast_inlines = gen_ast_inlines(); +#if 0 header.print_fmt("#pragma region Types\n"); header.print( types ); header.print( fmt_newline ); @@ -345,6 +384,7 @@ int gen_main() header.print( dump_to_scratch_and_retireve( especifier )); header.print( fmt_newline ); header.print_fmt("#pragma endregion Types\n\n"); + #endif } header.print( pop_ignores ); diff --git a/gen_c_library/components/memory.fixed_arena.hpp b/gen_c_library/components/memory.fixed_arena.hpp index d136ec5..e75a6eb 100644 --- a/gen_c_library/components/memory.fixed_arena.hpp +++ b/gen_c_library/components/memory.fixed_arena.hpp @@ -20,7 +20,7 @@ CodeBody gen_fixed_arenas() inline void fixed_arena_init_(FixedArena_* result) { zero_size(& result->memory[0], ); - result.arena = arena_init_from_memory(& result->memory[0], ); + result->arena = arena_init_from_memory(& result->memory[0], ); } inline diff --git a/gen_c_library/components/misc.hpp b/gen_c_library/components/misc.hpp index 109f42b..c323713 100644 --- a/gen_c_library/components/misc.hpp +++ b/gen_c_library/components/misc.hpp @@ -8,7 +8,7 @@ using SwapContentProc = CodeBody(void); b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& body ) { b32 found = false; - CodePreprocessCond cond = entry_iter.cast(); + CodePreprocessCond cond = entry_iter.code_cast(); if ( cond->Content.contains(cond_sig) ) { log_fmt("Preprocess cond found: %S\n", cond->Content); @@ -44,7 +44,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& bod bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body ) { bool found = false; - CodePragma possible_region = entry_iter.cast(); + CodePragma possible_region = entry_iter.code_cast(); String region_sig = string_fmt_buf(GlobalAllocator, "region %s", region_name.Ptr); String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr); @@ -58,7 +58,7 @@ bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_ (entry_iter->Type) { case ECode::Preprocess_Pragma: { - CodePragma possible_end_region = entry_iter.cast(); + CodePragma possible_end_region = entry_iter.code_cast(); if ( possible_end_region->Content.contains(endregion_sig) ) { // body.append(possible_end_region); continue_for = false; diff --git a/gen_c_library/gen.c b/gen_c_library/gen.c new file mode 100644 index 0000000..eb14df1 --- /dev/null +++ b/gen_c_library/gen.c @@ -0,0 +1,7 @@ +#define GEN_IMPLEMENTATION +#include "gen/gen.h" + +int main() +{ + // init(); +} diff --git a/project/Readme.md b/project/Readme.md index d1f2030..ecf7c8d 100644 --- a/project/Readme.md +++ b/project/Readme.md @@ -30,6 +30,13 @@ Feature Macros: * `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves. * `GEN_DONT_ALLOW_INVALID_CODE` (Not implemented yet) : Will fail when an invalid code is constructed, parsed, or serialized. +By default the base library implementation strictly uses a C-like interface. This is to allow for the generation of a C-variant of the library using [gen_c_library](../gen_c_library/). However, the library was written in C++ and supports some of its features: + +* `GEN_SUPPORT_CPP_REFERENCES` : Will enable support for reference interface on some definitions +* `GEN_SUPPORT_CPP_MEMBER_FEATURES` : Will enable support for definitions to have their interface as members. + +*Note: A variant of the C++ library could be generated where those additonal support features are removed (see gen_c_library implementation for an idea of how)* + ## On multi-threading Currently unsupported. I want the library to be *stable* and *correct*, with the addition of exhausting all basic single-threaded optimizations before I consider multi-threading. diff --git a/project/components/interface.cpp b/project/components/interface.cpp index b62d537..9b3cbfb 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 = & back(Global_AllocatorBuckets); + 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 ( ! append( Global_AllocatorBuckets, bucket ) ) + if ( ! append( & Global_AllocatorBuckets, bucket ) ) GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets"); - last = & back(Global_AllocatorBuckets); + 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 ( ! append( Global_AllocatorBuckets, bucket ) ) + if ( ! append( & Global_AllocatorBuckets, bucket ) ) GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets"); - last = & back(Global_AllocatorBuckets); + last = back(& Global_AllocatorBuckets); } void* result = alloc_align( last->Backing, size, alignment ); @@ -249,7 +249,7 @@ void init() if ( bucket.PhysicalStart == nullptr ) GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets"); - append( Global_AllocatorBuckets, bucket ); + append( & Global_AllocatorBuckets, bucket ); } // Setup the arrays @@ -272,7 +272,7 @@ void init() if ( code_pool.PhysicalStart == nullptr ) GEN_FATAL( "gen::init: Failed to initialize the code pool" ); - append(CodePools, code_pool ); + append( & CodePools, code_pool ); LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size ); @@ -281,7 +281,7 @@ void init() if ( string_arena.PhysicalStart == nullptr ) GEN_FATAL( "gen::init: Failed to initialize the string arena" ); - append(StringArenas, string_arena ); + append( & StringArenas, string_arena ); } // Setup the hash tables @@ -323,12 +323,12 @@ void deinit() destroy(StringCache); - free(CodePools); - free(StringArenas); + free( & CodePools); + free( & StringArenas); free(& LexArena); - free(PreprocessorDefines); + free(& PreprocessorDefines); index = 0; left = num(Global_AllocatorBuckets); @@ -373,7 +373,7 @@ void reset() AllocatorInfo get_string_allocator( s32 str_length ) { - Arena* last = & back(StringArenas); + Arena* last = back(& StringArenas); usize size_req = str_length + sizeof(StringHeader) + sizeof(char*); @@ -381,10 +381,10 @@ AllocatorInfo get_string_allocator( s32 str_length ) { Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena ); - if ( ! append(StringArenas, new_arena ) ) + if ( ! append( & StringArenas, new_arena ) ) GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" ); - last = & back(StringArenas); + last = back(& StringArenas); } return allocator_info(last); @@ -411,7 +411,7 @@ StringCached get_cached_string( StrC str ) // Used internally to retireve a Code object form the CodePool. Code make_code() { - Pool* allocator = & back(CodePools); + Pool* allocator = back( & CodePools); if ( allocator->FreeList == nullptr ) { Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) ); @@ -419,10 +419,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 ( ! append( CodePools, 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 = & back(CodePools); + 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 61e4283..8e4164f 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; - append(Tokens, { 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; - append(Tokens, 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; - append(Tokens, token ); + append( & Tokens, token ); end_line(); return Lex_Continue; } @@ -314,7 +314,7 @@ s32 lex_preprocessor_directive( token.Flags |= TF_Preprocess_Cond; } - append(Tokens, token ); + append( & Tokens, token ); SkipWhitespace(); @@ -338,7 +338,7 @@ s32 lex_preprocessor_directive( name.Length++; } - append(Tokens, name ); + append( & Tokens, name ); u64 key = crc32( name.Text, name.Length ); set(defines, key, name ); @@ -384,7 +384,7 @@ s32 lex_preprocessor_directive( move_forward(); } - append(Tokens, 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++; } - append(Tokens, 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 ) { - append(Tokens, token ); + append( & Tokens, token ); return; } @@ -488,7 +488,7 @@ void lex_found_token( StrC& content } token.Type = type; - append(Tokens, token ); + append( & Tokens, token ); return; } @@ -498,7 +498,7 @@ void lex_found_token( StrC& content { token.Type = type; token.Flags |= TF_Specifier; - append(Tokens, token ); + append( & Tokens, token ); return; } @@ -506,7 +506,7 @@ void lex_found_token( StrC& content if ( type != TokType::Invalid ) { token.Type = type; - append(Tokens, token ); + append( & Tokens, token ); return; } @@ -558,7 +558,7 @@ void lex_found_token( StrC& content token.Type = TokType::Identifier; } - append(Tokens, token ); + append( & Tokens, token ); } @@ -630,7 +630,7 @@ TokArray lex( StrC content ) token.Type = TokType::NewLine; token.Length++; - append(Tokens, token ); + append( & Tokens, token ); continue; } } @@ -1099,7 +1099,7 @@ TokArray lex( StrC content ) move_forward(); token.Length++; } - append(Tokens, token ); + append( & Tokens, token ); continue; } else if ( current == '*' ) @@ -1135,7 +1135,7 @@ TokArray lex( StrC content ) move_forward(); token.Length++; } - append(Tokens, token ); + append( & Tokens, token ); // end_line(); continue; } diff --git a/project/components/parser.cpp b/project/components/parser.cpp index b04fd0a..f184d70 100644 --- a/project/components/parser.cpp +++ b/project/components/parser.cpp @@ -52,7 +52,7 @@ struct ParseContext sptr length = scope_start.Length; char const* current = scope_start.Text + length; - while ( current <= back(Tokens.Arr).Text && *current != '\n' && length < 74 ) + while ( current <= back( & Tokens.Arr)->Text && *current != '\n' && length < 74 ) { current++; length++; @@ -745,7 +745,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) } Token interface_tok = parse_identifier(); - append(interfaces, 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; - free(interfaces); + free(& interfaces); return result; } diff --git a/project/dependencies/containers.hpp b/project/dependencies/containers.hpp index 66c6565..f59fb2f 100644 --- a/project/dependencies/containers.hpp +++ b/project/dependencies/containers.hpp @@ -29,29 +29,29 @@ struct ArrayHeader; usize array_grow_formula(ssize value); -template Array array_init(AllocatorInfo allocator); -template Array array_init_reserve(AllocatorInfo allocator, ssize capacity); -template bool append(Array& array, Array other); -template bool append(Array& array, Type value); -template bool append(Array& array, Type* items, usize item_num); -template bool append_at(Array& array, Type item, usize idx); -template bool append_at(Array& array, Type* items, usize item_num, usize idx); -template Type& back(Array& array); -template void clear(Array& array); -template bool fill(Array& array, usize begin, usize end, Type value); -template void free(Array& array); -template bool grow(Array& array, usize min_capacity); -template usize num(Array& array); -template void pop(Array& array); -template void remove_at(Array& array, usize idx); -template bool reserve(Array& array, usize new_capacity); -template bool resize(Array& array, usize num); -template bool set_capacity(Array& array, usize new_capacity); -template ArrayHeader* get_header(Array& array); +template Array(Type) array_init (AllocatorInfo allocator); +template Array(Type) array_init_reserve(AllocatorInfo allocator, ssize capacity); +template bool append (Array(Type)* array, Array(Type) other); +template bool append (Array(Type)* array, Type value); +template bool append (Array(Type)* array, Type* items, usize item_num); +template bool append_at (Array(Type)* array, Type item, usize idx); +template bool append_at (Array(Type)* array, Type* items, usize item_num, usize idx); +template Type* back (Array(Type) array); +template void clear (Array(Type) array); +template bool fill (Array(Type) array, usize begin, usize end, Type value); +template void free (Array(Type)* array); +template bool grow (Array(Type)* array, usize min_capacity); +template usize num (Array(Type) array); +template void pop (Array(Type) array); +template void remove_at (Array(Type) array, usize idx); +template bool reserve (Array(Type)* array, usize new_capacity); +template bool resize (Array(Type)* array, usize num); +template bool set_capacity (Array(Type)* array, usize new_capacity); +template ArrayHeader* get_header (Array(Type) 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(Array& array, Type* entry) { return entry + 1; } +// template forceinline Type* begin(Array array) { return array; } +// template forceinline Type* end(Array array) { return array + get_header(array)->Num; } +// template forceinline Type* next(Array array, Type* entry) { return entry + 1; } struct ArrayHeader { AllocatorInfo Allocator; @@ -70,32 +70,52 @@ struct Array forceinline static Array init_reserve(AllocatorInfo allocator, ssize capacity) { return GEN_NS array_init_reserve(allocator, capacity); } forceinline static usize grow_formula(ssize value) { return GEN_NS array_grow_formula(value); } - forceinline bool append(Array other) { return GEN_NS append(*this, other); } - forceinline bool append(Type value) { return GEN_NS append(*this, value); } - forceinline bool append(Type* items, usize item_num) { return GEN_NS append(*this, items, item_num); } - forceinline bool append_at(Type item, usize idx) { return GEN_NS append_at(*this, item, idx); } - forceinline bool append_at(Type* items, usize item_num, usize idx) { return GEN_NS append_at(*this, items, item_num, idx); } - forceinline Type& back() { return GEN_NS back(*this); } - forceinline void clear() { GEN_NS clear(*this); } - forceinline bool fill(usize begin, usize end, Type value) { return GEN_NS fill(*this, begin, end, value); } - forceinline void free() { GEN_NS free(*this); } - forceinline ArrayHeader* get_header() { return GEN_NS get_header(*this); } - forceinline bool grow(usize min_capacity) { return GEN_NS grow(*this, min_capacity); } + forceinline bool append(Array other) { return GEN_NS append(this, other); } + forceinline bool append(Type value) { return GEN_NS append(this, value); } + forceinline bool append(Type* items, usize item_num) { return GEN_NS append(this, items, item_num); } + forceinline bool append_at(Type item, usize idx) { return GEN_NS append_at(this, item, idx); } + forceinline bool append_at(Type* items, usize item_num, usize idx) { return GEN_NS append_at(this, items, item_num, idx); } + forceinline Type* back() { return GEN_NS back(* this); } + forceinline void clear() { GEN_NS clear(* this); } + forceinline bool fill(usize begin, usize end, Type value) { return GEN_NS fill(* this, begin, end, value); } + forceinline void free() { GEN_NS free(this); } + forceinline ArrayHeader* get_header() { return GEN_NS get_header(* this); } + forceinline bool grow(usize min_capacity) { return GEN_NS grow(this, min_capacity); } forceinline usize num() { return GEN_NS num(*this); } - forceinline void pop() { GEN_NS pop(*this); } - forceinline void remove_at(usize idx) { GEN_NS remove_at(*this, idx); } - forceinline bool reserve(usize new_capacity) { return GEN_NS reserve(*this, new_capacity); } - forceinline bool resize(usize num) { return GEN_NS resize(*this, num); } - forceinline bool set_capacity(usize new_capacity) { return GEN_NS set_capacity(*this, new_capacity); } + forceinline void pop() { GEN_NS pop(* this); } + forceinline void remove_at(usize idx) { GEN_NS remove_at(* this, idx); } + forceinline bool reserve(usize new_capacity) { return GEN_NS reserve(this, new_capacity); } + forceinline bool resize(usize num) { return GEN_NS resize(this, num); } + forceinline bool set_capacity(usize new_capacity) { return GEN_NS set_capacity(this, new_capacity); } +#pragma endregion Member Mapping forceinline operator Type*() { return Data; } forceinline operator Type const*() const { return Data; } forceinline Type* begin() { return Data; } forceinline Type* end() { return Data + get_header()->Num; } -#pragma endregion Member Mapping + + forceinline Type& operator[](ssize index) { return Data[index]; } + forceinline Type const& operator[](ssize index) const { return Data[index]; } }; #endif +#if GEN_SUPPORT_CPP_REFERENCES +template bool append(Array& array, Array other) { return GEN_NS append( & array, other ); } +template bool append(Array& array, Type value) { return GEN_NS append( & array, value ); } +template bool append(Array& array, Type* items, usize item_num) { return GEN_NS append( & array, items, item_num ); } +template bool append_at(Array& array, Type item, usize idx) { return GEN_NS append_at( & array, item, idx ); } +template bool append_at(Array& array, Type* items, usize item_num, usize idx) { return GEN_NS append_at( & array, items, item_num, idx ); } +template void free(Array& array) { return GEN_NS free( & array ); } +template bool grow(Array& array, usize min_capacity) { return GEN_NS grow( & array, min_capacity); } +template bool reserve(Array& array, usize new_capacity) { return GEN_NS reserve( & array, new_capacity); } +template bool resize(Array& array, usize num) { return GEN_NS resize( & array, num); } +template bool set_capacity(Array& array, usize new_capacity) { return GEN_NS set_capacity( & array, new_capacity); } + +template forceinline Type* begin(Array& array) { return array; } +template forceinline Type* end(Array& array) { return array + get_header(array)->Num; } +template forceinline Type* next(Array& array, Type* entry) { return entry + 1; } +#endif + template inline Array array_init(AllocatorInfo allocator) { return array_init_reserve(allocator, array_grow_formula(0)); @@ -121,30 +141,30 @@ usize array_grow_formula(ssize value) { } template inline -bool append(Array& array, Array other) { +bool append(Array* array, Array other) { return append(array, other, num(other)); } template inline -bool append(Array& array, Type value) +bool append(Array* array, Type value) { - ArrayHeader* header = get_header(array); + ArrayHeader* header = get_header(* array); if (header->Num == header->Capacity) { if (!grow(array, header->Capacity)) return false; - header = get_header(array); + header = get_header(* array); } - array[header->Num] = value; + (*array)[ header->Num] = value; header->Num++; return true; } template inline -bool append(Array& array, Type* items, usize item_num) +bool append(Array* array, Type* items, usize item_num) { ArrayHeader* header = get_header(array); @@ -162,34 +182,37 @@ bool append(Array& array, Type* items, usize item_num) } template inline -bool append_at(Array& array, Type item, usize idx) +bool append_at(Array* array, Type item, usize idx) { - ArrayHeader* header = get_header(array); + ArrayHeader* header = get_header(* array); - if (idx >= header->Num) - idx = header->Num - 1; + ssize slot = idx; + if (slot >= header->Num) + slot = header->Num - 1; - if (idx < 0) - idx = 0; + if (slot < 0) + slot = 0; if (header->Capacity < header->Num + 1) { - if (!grow(array, header->Capacity + 1)) + if ( ! grow(array, header->Capacity + 1)) return false; - header = get_header(array); + header = get_header(* array); } - Type* target = array + idx; + Type* target = array->Data + slot; - mem_move(target + 1, target, (header->Num - idx) * sizeof(Type)); + mem_move(target + 1, target, (header->Num - slot) * sizeof(Type)); header->Num++; + header = get_header(* array); + return true; } template inline -bool append_at(Array& array, Type* items, usize item_num, usize idx) +bool append_at(Array* array, Type* items, usize item_num, usize idx) { ArrayHeader* header = get_header(array); @@ -200,7 +223,7 @@ bool append_at(Array& array, Type* items, usize item_num, usize idx) if (item_num > header->Capacity) { - if (!grow(array, header->Capacity + item_num)) + if (! grow(array, header->Capacity + item_num)) return false; header = get_header(array); @@ -217,19 +240,25 @@ 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[header->Num - 1]; +Type* back(Array* array) +{ + GEN_ASSERT(array != nullptr); + + ArrayHeader* header = get_header(* array); + if (header->Num <= 0) + return nullptr; + + return & (*array)[header->Num - 1]; } template inline -void clear(Array& array) { +void clear(Array array) { ArrayHeader* header = get_header(array); header->Num = 0; } template inline -bool fill(Array& array, usize begin, usize end, Type value) +bool fill(Array array, usize begin, usize end, Type value) { ArrayHeader* header = get_header(array); @@ -245,25 +274,25 @@ bool fill(Array& array, usize begin, usize end, Type value) } template inline -void free(Array& array) { - ArrayHeader* header = get_header(array); +void free(Array* array) { + GEN_ASSERT(array != nullptr); + ArrayHeader* header = get_header(* array); GEN_NS free(header->Allocator, header); - Type*& Data = rcast(Type*&, array); - Data = nullptr; + array->Data = nullptr; } -template inline -ArrayHeader* get_header(Array& array) { +template forceinline +ArrayHeader* get_header(Array array) { + Type* Data = array; + using NonConstType = TRemoveConst; - Type* Data = array; // This should do nothing in C but in C++ gets member Data struct. - return rcast(ArrayHeader*, const_cast(Data)) - 1; + return rcast(ArrayHeader*, const_cast(Data)) - 1; } - template inline -bool grow(Array& array, usize min_capacity) +bool grow(Array* array, usize min_capacity) { - ArrayHeader* header = get_header(array); - usize new_capacity = array_grow_formula(header->Capacity); + ArrayHeader* header = get_header(* array); + usize new_capacity = array_grow_formula(header->Capacity); if (new_capacity < min_capacity) new_capacity = min_capacity; @@ -272,19 +301,19 @@ bool grow(Array& array, usize min_capacity) } template inline -usize num(Array& array) { +usize num(Array array) { return get_header(array)->Num; } template inline -void pop(Array& array) { +void pop(Array array) { ArrayHeader* header = get_header(array); GEN_ASSERT(header->Num > 0); header->Num--; } template inline -void remove_at(Array& array, usize idx) +void remove_at(Array array, usize idx) { ArrayHeader* header = get_header(array); GEN_ASSERT(idx < header->Num); @@ -294,7 +323,7 @@ void remove_at(Array& array, usize idx) } template inline -bool reserve(Array& array, usize new_capacity) +bool reserve(Array* array, usize new_capacity) { ArrayHeader* header = get_header(array); @@ -305,14 +334,14 @@ bool reserve(Array& array, usize new_capacity) } template inline -bool resize(Array& array, usize num) +bool resize(Array* array, usize num) { - ArrayHeader* header = get_header(array); + ArrayHeader* header = get_header(* array); if (header->Capacity < num) { - if (!grow(array, num)) + if (! grow( array, num)) return false; - header = get_header(array); + header = get_header(* array); } header->Num = num; @@ -320,9 +349,9 @@ bool resize(Array& array, usize num) } template inline -bool set_capacity(Array& array, usize new_capacity) +bool set_capacity(Array* array, usize new_capacity) { - ArrayHeader* header = get_header(array); + ArrayHeader* header = get_header(* array); if (new_capacity == header->Capacity) return true; @@ -333,7 +362,7 @@ bool set_capacity(Array& array, usize new_capacity) return true; } - ssize size = sizeof(ArrayHeader) + sizeof(Type) * new_capacity; + ssize size = sizeof(ArrayHeader) + sizeof(Type) * new_capacity; ArrayHeader* new_header = rcast(ArrayHeader*, alloc(header->Allocator, size)); if (new_header == nullptr) @@ -345,32 +374,10 @@ bool set_capacity(Array& array, usize new_capacity) GEN_NS free(header->Allocator, header); - Type*& Data = rcast(Type*&, array); - Data = rcast(Type*, new_header + 1); + array->Data = rcast(Type*, new_header + 1); return true; } -#define array_init(Type, allocator) array_init(allocator) -#define array_init(Type, allocator) array_init(allocator) -#define array_init_reserve(Type, allocator, capacity) array_init_reserve(allocator, capacity) -#define array_append(Type, array, other) append(array, other) -#define array_append_value(Type, array, value) append(array, value) -#define array_append_items(Type, array, items, item_num) append(array, items, item_num) -#define array_append_at(Type, array, item, idx) append_at(array, item, idx) -#define array_append_items_at(Type, array, items, num, idx) append_at(array, items, num, idx) -#define array_back(Type, array) back(array) -#define array_clear(Type, array) clear(array) -#define array_fill(Type, array, begin, end, value) fill(array, begin, end, value) -#define array_free(Type, array) free(array) -#define array_grow(Type, array, min_capacity) grow(array, min_capacity) -#define array_num(Type, array) num(array) -#define array_pop(Type, array) pop(array) -#define array_remove_at(Type, array, idx) remove_at(array, idx) -#define array_reserve(Type, array, new_capacity) reserve(array, new_capacity) -#define array_resize(Type, array, num) resize(array, num) -#define array_set_capacity(Type, array, new_capacity) set_capacity(array, new_capacity) -#define array_get_header(array) get_header(array) - #pragma endregion Array // TODO(Ed) : This thing needs ALOT of work. @@ -453,7 +460,7 @@ HashTable hashtable_init_reserve(AllocatorInfo allocator, usize num) result.Hashes = array_init_reserve(allocator, num); get_header(result.Hashes)->Num = num; - resize(result.Hashes, num); + resize(& result.Hashes, num); fill(result.Hashes, 0, num, -1); result.Entries = array_init_reserve>(allocator, num); @@ -469,8 +476,8 @@ void clear(HashTable& table) { template inline void destroy(HashTable& table) { if (table.Hashes && get_header(table.Hashes)->Capacity) { - free(table.Hashes); - free(table.Entries); + free(& table.Hashes); + free(& table.Entries); } } @@ -621,7 +628,7 @@ ssize add_entry(HashTable& table, u64 key) { HashTableEntry entry = { key, -1 }; idx = num(table.Entries); - append(table.Entries, entry); + append( & table.Entries, entry); return idx; } diff --git a/project/dependencies/filesystem.cpp b/project/dependencies/filesystem.cpp index 931f9cd..683972b 100644 --- a/project/dependencies/filesystem.cpp +++ b/project/dependencies/filesystem.cpp @@ -612,7 +612,7 @@ GEN_FILE_WRITE_AT_PROC( _memory_file_write ) if ( get_header(arr)->Capacity < usize(new_cap) ) { - if ( ! grow( arr, ( s64 )( new_cap ) ) ) + if ( ! grow( & arr, ( s64 )( new_cap ) ) ) return false; d->buf = arr; } @@ -647,7 +647,7 @@ GEN_FILE_CLOSE_PROC( _memory_file_close ) if ( d->flags & EFileStream_CLONE_WRITABLE ) { Array arr = { d->buf }; - free(arr); + free(& arr); } free( allocator, d ); diff --git a/project/dependencies/parsing.cpp b/project/dependencies/parsing.cpp index 4ab0175..fbe44b1 100644 --- a/project/dependencies/parsing.cpp +++ b/project/dependencies/parsing.cpp @@ -41,7 +41,7 @@ u8 adt_destroy_branch( ADT_Node* node ) adt_destroy_branch( node->nodes + i ); } - free(node->nodes); + free(& node->nodes); } return 0; } @@ -287,10 +287,11 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index ) ADT_Node o = { 0 }; o.parent = parent; - if ( ! append_at( parent->nodes, o, index ) ) + if ( ! append_at( & parent->nodes, o, index ) ) return NULL; - return parent->nodes + index; + ADT_Node* node = & parent->nodes[index]; + return node; } ADT_Node* adt_alloc( ADT_Node* parent ) @@ -402,7 +403,9 @@ 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, get_header(parent->nodes)->Allocator ) ) + + ArrayHeader* node_header = get_header(parent->nodes); + if ( adt_set_arr( o, name, node_header->Allocator ) ) { adt_remove_node( o ); return NULL; @@ -951,7 +954,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b adt_append_arr( root, NULL ); } - append(root->nodes[ columnIndex ].nodes, rowItem ); + append( & root->nodes[ columnIndex ].nodes, rowItem ); if ( delimiter == delim ) { diff --git a/project/dependencies/parsing.hpp b/project/dependencies/parsing.hpp index a0a7c37..b0a721d 100644 --- a/project/dependencies/parsing.hpp +++ b/project/dependencies/parsing.hpp @@ -83,7 +83,7 @@ struct ADT_Node union { char const* string; - Array nodes; ///< zpl_array + Array(ADT_Node) nodes; ///< zpl_array struct { diff --git a/project/helpers/helper.hpp b/project/helpers/helper.hpp index 975d08d..5fa885c 100644 --- a/project/helpers/helper.hpp +++ b/project/helpers/helper.hpp @@ -23,9 +23,10 @@ CodeBody gen_ecode( char const* path ) String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); - for ( ADT_Node node : enum_strs ) + for ( ADT_Node& node : enum_strs ) { char const* code = node.string; + append_fmt( enum_entries, "%s,\n", code ); append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code ); }