From 94b8427b96252d93f5f56de131343222e25caf7f Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 1 Feb 2025 17:47:14 -0500 Subject: [PATCH] starting to offload MD namespace for repo to gen_c11 .refactor script and gen_cpp17 to namespace macros --- code/base/macros.h | 29 ++++++ code/base/memory.h | 38 -------- code/base/rarena.h | 25 +++--- code/base/zpl_memory.h | 115 ++++++++++++++++++++++++ code/mdesk/mdesk.h | 200 ++++++++++++++++++++--------------------- gen_c11/c11.refactor | 74 +++++++++++++++ 6 files changed, 329 insertions(+), 152 deletions(-) delete mode 100644 code/base/memory.h create mode 100644 code/base/zpl_memory.h create mode 100644 gen_c11/c11.refactor diff --git a/code/base/macros.h b/code/base/macros.h index 835b1dd..e662d0f 100644 --- a/code/base/macros.h +++ b/code/base/macros.h @@ -30,6 +30,24 @@ #define local_persist static #endif +#if MD_COMPILER_MSVC +# define thread_static __declspec(thread) +#elif MD_COMPILER_CLANG || MD_COMPILER_GCC +# define thread_static __thread +#endif + +//////////////////////////////// +//~ rjf: Branch Predictor Hints + +#if defined(__clang__) +# define expect(expr, val) __builtin_expect((expr), (val)) +#else +# define expect(expr, val) (expr) +#endif + +#define likely(expr) expect(expr,1) +#define unlikely(expr) expect(expr,0) + #if MD_COMPILER_CPP # ifndef ccast # define ccast( type, value ) ( const_cast< type >( (value) ) ) @@ -106,6 +124,17 @@ # define MD_PARAM_DEFAULT #endif +#if MD_COMPILER_C +#ifndef static_assert +#undef static_assert + #if MD_COMPILER_C && __STDC_VERSION__ >= 201112L + #define static_assert(condition, message) _Static_assert(condition, message) + #else + #define static_assert(condition, message) typedef char static_assertion_##__LINE__[(condition)?1:-1] + #endif +#endif +#endif + #if MD_DONT_USE_NAMESPACE || MD_COMPILER_C # if MD_COMPILER_C # define MD_NS diff --git a/code/base/memory.h b/code/base/memory.h deleted file mode 100644 index 55b5709..0000000 --- a/code/base/memory.h +++ /dev/null @@ -1,38 +0,0 @@ -#if MD_INTELLISENE_DIRECTIVES -#pragma once -#include "base_types.h" -#endif - -#define MD_KILOBYTES( x ) ( ( x ) * ( S64 )( 1024 ) ) -#define MD_MEGABYTES( x ) ( MD_KILOBYTES( x ) * ( S64 )( 1024 ) ) -#define MD_GIGABYTES( x ) ( MD_MEGABYTES( x ) * ( S64 )( 1024 ) ) -#define MD_TERABYTES( x ) ( MD_GIGABYTES( x ) * ( S64 )( 1024 ) ) - -#define MD__ONES ( scast( GEN_NS usize, - 1) / MD_U8_MAX ) -#define MD__HIGHS ( MD__ONES * ( MD_U8_MAX / 2 + 1 ) ) -#define MD__HAS_ZERO( x ) ( ( ( x ) - MD__ONES ) & ~( x ) & MD__HIGHS ) - -#define swap(a, b) \ -do \ -{ \ - typeof(a) tmp = a; \ - a = b; \ - b = tmp; \ -} \ -while (0) - -#if MD_COMPILER_MSVC || (MD_COMPILER_CLANG && MD_OS_WINDOWS) -# pragma section(".rdata$", read) -# define read_only __declspec(allocate(".rdata$")) -#elif (MD_COMPILER_CLANG && MD_OS_LINUX) -# define read_only __attribute__((section(".rodata"))) -#else -// NOTE(rjf): I don't know of a useful way to do this in GCC land. -// __attribute__((section(".rodata"))) looked promising, but it introduces a -// strange warning about malformed section attributes, and it doesn't look -// like writing to that section reliably produces access violations, strangely -// enough. (It does on Clang) -# define read_only -#endif - - diff --git a/code/base/rarena.h b/code/base/rarena.h index 7b212b8..73ff7c6 100644 --- a/code/base/rarena.h +++ b/code/base/rarena.h @@ -1,13 +1,16 @@ +#ifdef MD_INTELLISENSE_DIRECTIVES +#pragma once +#include "base_types.h" +#include "macros.h" +#endif + // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#ifndef BASE_ARENA_H -#define BASE_ARENA_H - //////////////////////////////// //~ rjf: Constants -#define ARENA_HEADER_SIZE 64 +#define MD_ARENA_HEADER_SIZE 64 //////////////////////////////// //~ rjf: Types @@ -41,10 +44,10 @@ struct Arena U64 cmt; U64 res; }; -StaticAssert(sizeof(Arena) <= ARENA_HEADER_SIZE, arena_header_size_check); +static_assert(sizeof(Arena) <= MD_ARENA_HEADER_SIZE, "sizeof(Arena) <= MD_ARENA_HEADER_SIZE"); -typedef struct Temp Temp; -struct Temp +typedef struct TempArena TempArena; +struct TempArena { Arena *arena; U64 pos; @@ -56,7 +59,7 @@ struct Temp //- rjf: arena creation/destruction internal Arena *arena_alloc_(ArenaParams *params); #define arena_alloc(...) arena_alloc_(&(ArenaParams){.reserve_size = MB(64), .commit_size = KB(64), __VA_ARGS__}) -internal void arena_release(Arena *arena); +internal void rarena_release(Arena *arena); //- rjf: arena push/pop/pos core functions internal void *arena_push(Arena *arena, U64 size, U64 align); @@ -68,13 +71,11 @@ internal void arena_clear(Arena *arena); internal void arena_pop(Arena *arena, U64 amt); //- rjf: temporary arena scopes -internal Temp temp_begin(Arena *arena); -internal void temp_end(Temp temp); +internal TempArena temp_arena_begin(Arena *arena); +internal void temp_arena_end(TempArena temp); //- rjf: push helper macros #define push_array_no_zero_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T)*(c), (align)) #define push_array_aligned(a, T, c, align) (T *)MemoryZero(push_array_no_zero_aligned(a, T, c, align), sizeof(T)*(c)) #define push_array_no_zero(a, T, c) push_array_no_zero_aligned(a, T, c, Max(8, AlignOf(T))) #define push_array(a, T, c) push_array_aligned(a, T, c, Max(8, AlignOf(T))) - -#endif // BASE_ARENA_H diff --git a/code/base/zpl_memory.h b/code/base/zpl_memory.h new file mode 100644 index 0000000..14dcd5b --- /dev/null +++ b/code/base/zpl_memory.h @@ -0,0 +1,115 @@ +#ifdef MD_INTELLISENSE_DIRECTIVES +#pragma once +#include "base_types.h" +#endif + +#define MD_KILOBYTES( x ) ( ( x ) * ( S64 )( 1024 ) ) +#define MD_MEGABYTES( x ) ( MD_KILOBYTES( x ) * ( S64 )( 1024 ) ) +#define MD_GIGABYTES( x ) ( MD_MEGABYTES( x ) * ( S64 )( 1024 ) ) +#define MD_TERABYTES( x ) ( MD_GIGABYTES( x ) * ( S64 )( 1024 ) ) + +#define MD__ONES ( scast( GEN_NS usize, - 1) / MD_U8_MAX ) +#define MD__HIGHS ( MD__ONES * ( MD_U8_MAX / 2 + 1 ) ) +#define MD__HAS_ZERO( x ) ( ( ( x ) - MD__ONES ) & ~( x ) & MD__HIGHS ) + +#define swap(a, b) \ +do \ +{ \ + typeof(a) tmp = a; \ + a = b; \ + b = tmp; \ +} \ +while (0) + +#if MD_COMPILER_MSVC || (MD_COMPILER_CLANG && MD_OS_WINDOWS) +# pragma section(".rdata$", read) +# define read_only __declspec(allocate(".rdata$")) +#elif (MD_COMPILER_CLANG && MD_OS_LINUX) +# define read_only __attribute__((section(".rodata"))) +#else +// NOTE(rjf): I don't know of a useful way to do this in GCC land. +// __attribute__((section(".rodata"))) looked promising, but it introduces a +// strange warning about malformed section attributes, and it doesn't look +// like writing to that section reliably produces access violations, strangely +// enough. (It does on Clang) +# define read_only +#endif + +enum AllocType : u8 +{ + EAllocType_ALLOC, + EAllocType_FREE, + EAllocType_FREE_ALL, + EAllocType_RESIZE, +}; + +typedef void*(AllocatorProc)( void* allocator_data, AllocType type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags ); + +struct AllocatorInfo +{ + AllocatorProc* proc; + void* data; +}; + +enum AllocFlag +{ + ALLOCATOR_FLAG_CLEAR_TO_ZERO = 0, +}; + +#ifndef MD_DEFAULT_MEMORY_ALIGNMENT +# define MD_DEFAULT_MEMORY_ALIGNMENT ( 2 * size_of( void* ) ) +#endif + +#ifndef MD_DEFAULT_ALLOCATOR_FLAGS +# define MD_DEFAULT_ALLOCATOR_FLAGS ( ALLOCATOR_FLAG_CLEAR_TO_ZERO ) +#endif + +//! Allocate memory with default alignment. +void* alloc( AllocatorInfo a, SSIZE size ); + +//! Allocate memory with specified alignment. +void* alloc_align( AllocatorInfo a, SSIZE size, SSIZE alignment ); + +//! Free allocated memory. +void allocator_free( AllocatorInfo a, void* ptr ); + +//! Free all memory allocated by an allocator. +void free_all( AllocatorInfo a ); + +//! Resize an allocated memory. +void* resize( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size ); + +//! Resize an allocated memory with specified alignment. +void* resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE alignment ); + +//! Allocate memory for an item. +#define alloc_item( allocator_, Type ) ( Type* )alloc( allocator_, size_of( Type ) ) + +//! Allocate memory for an array of items. +#define alloc_array( allocator_, Type, count ) ( Type* )alloc( allocator_, size_of( Type ) * ( count ) ) + +/* heap memory analysis tools */ +/* define GEN_HEAP_ANALYSIS to enable this feature */ +/* call zpl_heap_stats_init at the beginning of the entry point */ +/* you can call zpl_heap_stats_check near the end of the execution to validate any possible leaks */ +MD_API void heap_stats_init( void ); +MD_API SSIZE heap_stats_used_memory( void ); +MD_API SSIZE heap_stats_alloc_count( void ); +MD_API void heap_stats_check( void ); + +//! Allocate/Resize memory using default options. + +//! Use this if you don't need a "fancy" resize allocation +void* default_resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE alignment ); + +MD_API void* heap_allocator_proc( void* allocator_data, AllocType type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags ); + +//! The heap allocator backed by operating system's memory manager. +constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; } + +//! Helper to allocate memory using heap allocator. +#define malloc( sz ) alloc( heap(), sz ) + +//! Helper to free memory allocated by heap allocator. +#define mfree( ptr ) free( heap(), ptr ) + diff --git a/code/mdesk/mdesk.h b/code/mdesk/mdesk.h index b37958d..0e045f0 100644 --- a/code/mdesk/mdesk.h +++ b/code/mdesk/mdesk.h @@ -1,7 +1,9 @@ #if MD_INTELLISENSE_DIRECTIVES #pragma once -#include "base/string.h" +#include "base/base_types.h" #include "base/math.h" +#include "base/rarena.h" +#include "base/string.h" #endif // Copyright (c) 2024 Epic Games Tools @@ -10,158 +12,152 @@ //////////////////////////////// //~ rjf: Messages -typedef enum MD_MsgKind +typedef enum MsgKind { - MD_MsgKind_Null, - MD_MsgKind_Note, - MD_MsgKind_Warning, - MD_MsgKind_Error, - MD_MsgKind_FatalError, + MsgKind_Null, + MsgKind_Note, + MsgKind_Warning, + MsgKind_Error, + MsgKind_FatalError, } -MD_MsgKind; +MsgKind; -typedef struct MD_Msg MD_Msg; -struct MD_Msg +typedef struct Node Node; +typedef struct Msg Msg; +struct Msg { - MD_Msg *next; - struct MD_Node *node; - MD_MsgKind kind; + Msg* next; + Node* node; + MsgKind kind; String8 string; }; -typedef struct MD_MsgList MD_MsgList; -struct MD_MsgList +typedef struct MsgList MsgList; +struct MsgList { - MD_Msg *first; - MD_Msg *last; - U64 count; - MD_MsgKind worst_message_kind; + Msg* first; + Msg* last; + U64 count; + MsgKind worst_message_kind; }; //////////////////////////////// //~ rjf: Token Types -typedef U32 MD_TokenFlags; +typedef U32 TokenFlags; enum { // rjf: base kind info - MD_TokenFlag_Identifier = (1<<0), - MD_TokenFlag_Numeric = (1<<1), - MD_TokenFlag_StringLiteral = (1<<2), - MD_TokenFlag_Symbol = (1<<3), - MD_TokenFlag_Reserved = (1<<4), - MD_TokenFlag_Comment = (1<<5), - MD_TokenFlag_Whitespace = (1<<6), - MD_TokenFlag_Newline = (1<<7), + TokenFlag_Identifier = (1<<0), + TokenFlag_Numeric = (1<<1), + TokenFlag_StringLiteral = (1<<2), + TokenFlag_Symbol = (1<<3), + TokenFlag_Reserved = (1<<4), + TokenFlag_Comment = (1<<5), + TokenFlag_Whitespace = (1<<6), + TokenFlag_Newline = (1<<7), // rjf: decoration info - MD_TokenFlag_StringSingleQuote = (1<<8), - MD_TokenFlag_StringDoubleQuote = (1<<9), - MD_TokenFlag_StringTick = (1<<10), - MD_TokenFlag_StringTriplet = (1<<11), + TokenFlag_StringSingleQuote = (1<<8), + TokenFlag_StringDoubleQuote = (1<<9), + TokenFlag_StringTick = (1<<10), + TokenFlag_StringTriplet = (1<<11), // rjf: error info - MD_TokenFlag_BrokenComment = (1<<12), - MD_TokenFlag_BrokenStringLiteral = (1<<13), - MD_TokenFlag_BadCharacter = (1<<14), + TokenFlag_BrokenComment = (1<<12), + TokenFlag_BrokenStringLiteral = (1<<13), + TokenFlag_BadCharacter = (1<<14), }; -typedef U32 MD_TokenGroups; +typedef U32 TokenGroups; enum { - MD_TokenGroup_Comment = MD_TokenFlag_Comment, - MD_TokenGroup_Whitespace = (MD_TokenFlag_Whitespace| - MD_TokenFlag_Newline), - MD_TokenGroup_Irregular = (MD_TokenGroup_Comment| - MD_TokenGroup_Whitespace), - MD_TokenGroup_Regular = ~MD_TokenGroup_Irregular, - MD_TokenGroup_Label = (MD_TokenFlag_Identifier| - MD_TokenFlag_Numeric| - MD_TokenFlag_StringLiteral| - MD_TokenFlag_Symbol), - MD_TokenGroup_Error = (MD_TokenFlag_BrokenComment| - MD_TokenFlag_BrokenStringLiteral| - MD_TokenFlag_BadCharacter), + TokenGroup_Comment = TokenFlag_Comment, + TokenGroup_Whitespace = (TokenFlag_Whitespace| TokenFlag_Newline), + TokenGroup_Irregular = (TokenGroup_Comment | TokenGroup_Whitespace), + TokenGroup_Regular = ~TokenGroup_Irregular, + TokenGroup_Label = (TokenFlag_Identifier | TokenFlag_Numeric | TokenFlag_StringLiteral | TokenFlag_Symbol), + TokenGroup_Error = (TokenFlag_BrokenComment | TokenFlag_BrokenStringLiteral | TokenFlag_BadCharacter), }; -typedef struct MD_Token MD_Token; -struct MD_Token +typedef struct Token Token; +struct Token { Rng1U64 range; - MD_TokenFlags flags; + TokenFlags flags; }; -typedef struct MD_TokenChunkNode MD_TokenChunkNode; -struct MD_TokenChunkNode +typedef struct TokenChunkNode TokenChunkNode; +struct TokenChunkNode { - MD_TokenChunkNode *next; - MD_Token *v; + TokenChunkNode *next; + Token *v; U64 count; U64 cap; }; -typedef struct MD_TokenChunkList MD_TokenChunkList; -struct MD_TokenChunkList +typedef struct TokenChunkList TokenChunkList; +struct TokenChunkList { - MD_TokenChunkNode *first; - MD_TokenChunkNode *last; + TokenChunkNode* first; + TokenChunkNode* last; U64 chunk_count; U64 total_token_count; }; -typedef struct MD_TokenArray MD_TokenArray; -struct MD_TokenArray +typedef struct TokenArray TokenArray; +struct TokenArray { - MD_Token *v; - U64 count; + Token* v; + U64 count; }; //////////////////////////////// //~ rjf: Node Types -typedef enum MD_NodeKind +typedef enum NodeKind { - MD_NodeKind_Nil, - MD_NodeKind_File, - MD_NodeKind_ErrorMarker, - MD_NodeKind_Main, - MD_NodeKind_Tag, - MD_NodeKind_List, - MD_NodeKind_Reference, - MD_NodeKind_COUNT + NodeKind_Nil, + NodeKind_File, + NodeKind_ErrorMarker, + NodeKind_Main, + NodeKind_Tag, + NodeKind_List, + NodeKind_Reference, + NodeKind_COUNT } -MD_NodeKind; +NodeKind; -typedef U32 MD_NodeFlags; +typedef U32 NodeFlags; enum { - MD_NodeFlag_MaskSetDelimiters = (0x3F<<0), - MD_NodeFlag_HasParenLeft = (1<<0), - MD_NodeFlag_HasParenRight = (1<<1), - MD_NodeFlag_HasBracketLeft = (1<<2), - MD_NodeFlag_HasBracketRight = (1<<3), - MD_NodeFlag_HasBraceLeft = (1<<4), - MD_NodeFlag_HasBraceRight = (1<<5), + NodeFlag_MaskSetDelimiters = (0x3F<<0), + NodeFlag_HasParenLeft = (1<<0), + NodeFlag_HasParenRight = (1<<1), + NodeFlag_HasBracketLeft = (1<<2), + NodeFlag_HasBracketRight = (1<<3), + NodeFlag_HasBraceLeft = (1<<4), + NodeFlag_HasBraceRight = (1<<5), - MD_NodeFlag_MaskSeparators = (0xF<<6), - MD_NodeFlag_IsBeforeSemicolon = (1<<6), - MD_NodeFlag_IsAfterSemicolon = (1<<7), - MD_NodeFlag_IsBeforeComma = (1<<8), - MD_NodeFlag_IsAfterComma = (1<<9), + NodeFlag_MaskSeparators = (0xF<<6), + NodeFlag_IsBeforeSemicolon = (1<<6), + NodeFlag_IsAfterSemicolon = (1<<7), + NodeFlag_IsBeforeComma = (1<<8), + NodeFlag_IsAfterComma = (1<<9), - MD_NodeFlag_MaskStringDelimiters = (0xF<<10), - MD_NodeFlag_StringSingleQuote = (1<<10), - MD_NodeFlag_StringDoubleQuote = (1<<11), - MD_NodeFlag_StringTick = (1<<12), - MD_NodeFlag_StringTriplet = (1<<13), + NodeFlag_MaskStringDelimiters = (0xF<<10), + NodeFlag_StringSingleQuote = (1<<10), + NodeFlag_StringDoubleQuote = (1<<11), + NodeFlag_StringTick = (1<<12), + NodeFlag_StringTriplet = (1<<13), - MD_NodeFlag_MaskLabelKind = (0xF<<14), - MD_NodeFlag_Numeric = (1<<14), - MD_NodeFlag_Identifier = (1<<15), - MD_NodeFlag_StringLiteral = (1<<16), - MD_NodeFlag_Symbol = (1<<17), + NodeFlag_MaskLabelKind = (0xF<<14), + NodeFlag_Numeric = (1<<14), + NodeFlag_Identifier = (1<<15), + NodeFlag_StringLiteral = (1<<16), + NodeFlag_Symbol = (1<<17), }; -#define MD_NodeFlag_AfterFromBefore(f) ((f) << 1) +#define NodeFlag_AfterFromBefore(f) ((f) << 1) typedef struct MD_Node MD_Node; struct MD_Node @@ -249,18 +245,18 @@ internal void md_msg_list_concat_in_place(MD_MsgList *dst, MD_MsgList *to_push); //////////////////////////////// //~ rjf: Token Type Functions -internal MD_Token md_token_make(Rng1U64 range, MD_TokenFlags flags); +internal MD_Token md_token_make(Rng1U64 range, TokenFlags flags); internal B32 md_token_match(MD_Token a, MD_Token b); -internal String8List md_string_list_from_token_flags(Arena *arena, MD_TokenFlags flags); +internal String8List md_string_list_from_token_flags(Arena *arena, TokenFlags flags); internal void md_token_chunk_list_push(Arena *arena, MD_TokenChunkList *list, U64 cap, MD_Token token); internal MD_TokenArray md_token_array_from_chunk_list(Arena *arena, MD_TokenChunkList *chunks); -internal String8 md_content_string_from_token_flags_str8(MD_TokenFlags flags, String8 string); +internal String8 md_content_string_from_token_flags_str8(TokenFlags flags, String8 string); //////////////////////////////// //~ rjf: Node Type Functions //- rjf: flag conversions -internal MD_NodeFlags md_node_flags_from_token_flags(MD_TokenFlags flags); +internal MD_NodeFlags md_node_flags_from_token_flags(TokenFlags flags); //- rjf: nil internal B32 md_node_is_nil(MD_Node *node); diff --git a/gen_c11/c11.refactor b/gen_c11/c11.refactor new file mode 100644 index 0000000..dd8f204 --- /dev/null +++ b/gen_c11/c11.refactor @@ -0,0 +1,74 @@ + __VERSION 1 + +// not : Ignore +// include : #includes +// word : Alphanumeric or underscore +// namespace : Prefix search and replace (c-namspaces). +// regex : Unavailable in __VERSION 1. + +// Precedence (highest to lowest): +// word, namespace, regex + +// Metadesk namespaces +// namespace MD_, new_namespace_ +// namespace md_, new_namespace_ + +// base module + +word U8, MD_U8 +word U16, MD_U16 +word U32, MD_U32 +word U64, MD_U64 +word S8, MD_S8 +word S16, MD_S16 +word S32, MD_S32 +word S64, MD_S64 +word S128, MD_S128 + +word USIZE, MD_USIZE +word SSIZE, MD_SSIZE + +word SPTR, MD_SPTR +word UPTR, MD_UPTR + +word F32, MD_F32 +word F64, MD_F64 + +word B8, MD_B8 +word B16, MD_B16 +word B32, MD_B32 + +word swap, md_swap + +word Rng1U64, MD_Rng1U64 + +word String8, MD_String8 + +// metadesk module + +// word MsgKind, MD_MsgKind +// word MsgKind_Null, MD_MsgKind_Null +// word MsgKind_Note, MD_MsgKind_Note +// word MsgKind_Warning, MD_MsgKind_Warning +// word MsgKind_Error, MD_MsgKind_Error +// word MsgKind_FatalError, MD_MsgKind_FatalError +namespace MsgKind, MD_MsgKind + +word Msg, MD_Msg +word MsgList, MD_MsgList + +word TokenFlags, MD_MsgFlags +namespace TokenFlag, MD_TokenFlag +word TokenGroups, MD_TokenGroups +namespace TokenGroup, MD_TokenGroup +word Token, MD_Token +word TokenChunkNode, MD_TokenChunkNode +word TokenChunkList, MD_TokenChunkList +word TokenArray, MD_TokenArray + +namespace NodeKind, MD_NodeKind +word Node, MD_Node + +// metagen module + +