diff --git a/base/components/interface.cpp b/base/components/interface.cpp index 7d65eda..cfc67ee 100644 --- a/base/components/interface.cpp +++ b/base/components/interface.cpp @@ -71,6 +71,14 @@ void* fallback_allocator_proc( void* allocator_data, AllocType type, ssize size, return nullptr; } +internal +void fallback_logger(LogEntry entry) +{ + GEN_ASSERT(entry.msg.Len > 0); + GEN_ASSERT(entry.msg.Ptr); + log_fmt("%S: %S", loglevel_to_str(entry.level), entry.msg); +} + internal void define_constants() { @@ -292,6 +300,10 @@ void init(Context* ctx) ctx->InitSize_MacrosTable = kilobytes(8); } + if (ctx->Logger == nullptr) { + ctx->Logger = & fallback_logger; + } + // Override the current context (user has to put it back if unwanted). _ctx = ctx; @@ -307,7 +319,7 @@ void init(Context* ctx) } // Setup the code pool and code entries arena. { - Pool code_pool = pool_init( ctx->Allocator_Pool, ctx->CodePool_NumBlocks, sizeof(AST) ); + Pool code_pool = pool_init( ctx->Allocator_Pool, ctx->CodePool_NumBlocks, size_of(AST) ); if ( code_pool.PhysicalStart == nullptr ) GEN_FATAL( "gen::init: Failed to initialize the code pool" ); array_append( ctx->CodePools, code_pool ); diff --git a/base/components/interface.hpp b/base/components/interface.hpp index da0a1b3..0f58ba4 100644 --- a/base/components/interface.hpp +++ b/base/components/interface.hpp @@ -15,23 +15,34 @@ \▓▓▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ */ -#if 0 enum LogLevel : u32 { - Info, - Warning, - Panic, + LL_Null, + LL_Note, + LL_Warning, + LL_Error, + LL_Fatal, + LL_UnderlyingType = GEN_U32_MAX, }; +Str loglevel_to_str(LogLevel level) +{ + local_persist + Str lookup[] = { + txt("Info"), + txt("Warning"), + txt("Panic"), + }; + return lookup[level]; +} + struct LogEntry { - Str msg; - u32 line_num; - void* data; + Str msg; + LogLevel level; }; -typedef void LoggerCallback(LogEntry entry); -#endif +typedef void LoggerProc(LogEntry entry); // Note(Ed): This is subject to heavily change // with upcoming changes to the library's fallback (default) allocations strategy; @@ -70,6 +81,10 @@ struct Context // TODO(Ed): Symbol Table // Keep track of all resolved symbols (naemspaced identifiers) +// Logging + + LoggerProc* Logger; + // Parser // Used by the lexer to persistently treat all these identifiers as preprocessor defines. @@ -107,6 +122,45 @@ struct Context // An implicit context interface will be provided instead as wrapper procedures as convience. GEN_API extern Context* _ctx; +// By default this library will either crash or exit if an error is detected while generating codes. +// Even if set to not use GEN_FATAL, GEN_FATAL will still be used for memory failures as the library is unusable when they occur. +#ifdef GEN_DONT_USE_FATAL + #define log_failure log_fmt +#else + #define log_failure GEN_FATAL +#endif + +// TODO(Ed): Swap all usage of this with logger_fmt (then rename logger_fmt to log_fmt) +inline +ssize log_fmt(char const* fmt, ...) +{ + ssize res; + va_list va; + + va_start(va, fmt); + res = c_str_fmt_out_va(fmt, va); + va_end(va); + + return res; +} + +inline +void logger_fmt(Context* ctx, LogLevel level, char const* fmt, ...) +{ + local_persist thread_local + PrintF_Buffer buf = struct_init(PrintF_Buffer, {0}); + + va_list va; + va_start(va, fmt); + ssize res = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) -1; + va_end(va); + + StrBuilder msg = strbuilder_make_length(ctx->Allocator_Temp, buf, res); + + LogEntry entry = { strbuilder_to_str(msg), level }; + ctx->Logger(entry); +} + // Initialize the library. There first ctx initialized must exist for lifetime of other contextes that come after as its the one that GEN_API void init(Context* ctx); @@ -117,7 +171,7 @@ GEN_API void deinit(Context* ctx); // Retrieves the active context (not usually needed, but here in case...) GEN_API Context* get_context(); -// Clears the allocations, but doesn't free the memoery, then calls init() again. +// Clears the allocations, but doesn't free the memory, then calls init() again. // Ease of use. GEN_API void reset(Context* ctx); @@ -398,7 +452,7 @@ GEN_API ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list v //! Do not use directly. Use the token_fmt macro instead. Str token_fmt_impl( ssize, ... ); -GEN_API Code untyped_str( Str content); +GEN_API Code untyped_str ( Str content); GEN_API Code untyped_fmt ( char const* fmt, ... ); GEN_API Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... ); diff --git a/base/components/types.hpp b/base/components/types.hpp index 18762ea..e64a706 100644 --- a/base/components/types.hpp +++ b/base/components/types.hpp @@ -19,16 +19,6 @@ */ -using LogFailType = ssize(*)(char const*, ...); - -// By default this library will either crash or exit if an error is detected while generating codes. -// Even if set to not use GEN_FATAL, GEN_FATAL will still be used for memory failures as the library is unusable when they occur. -#ifdef GEN_DONT_USE_FATAL - #define log_failure log_fmt -#else - #define log_failure GEN_FATAL -#endif - enum AccessSpec : u32 { AccessSpec_Default, diff --git a/base/dependencies/filesystem.hpp b/base/dependencies/filesystem.hpp index 9d3676a..c9026b0 100644 --- a/base/dependencies/filesystem.hpp +++ b/base/dependencies/filesystem.hpp @@ -187,7 +187,7 @@ struct FileContents { AllocatorInfo allocator; void* data; - ssize size; + ssize size; }; constexpr b32 file_zero_terminate = true; diff --git a/base/dependencies/macros.hpp b/base/dependencies/macros.hpp index b6cd161..ec2106c 100644 --- a/base/dependencies/macros.hpp +++ b/base/dependencies/macros.hpp @@ -298,10 +298,20 @@ # define GEN_PARAM_DEFAULT #endif -#if GEN_COMPILER_CPP - #define struct_init(type, value) {value} -#else - #define struct_init(type, value) {value} +#ifndef struct_init +# if GEN_COMPILER_CPP +# define struct_init(type, value) value +# else +# define struct_init(type, value) (type) value +# endif +#endif + +#ifndef struct_zero +# if GEN_COMPILER_CPP +# define struct_zero(type) {} +# else +# define struct_zero(type) (type) {0} +# endif #endif #if 0 diff --git a/base/dependencies/memory.hpp b/base/dependencies/memory.hpp index 70e5508..2a7713d 100644 --- a/base/dependencies/memory.hpp +++ b/base/dependencies/memory.hpp @@ -134,12 +134,6 @@ GEN_API void* heap_allocator_proc( void* allocator_data, AllocType type, ssize s //! 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 ) allocator_free( heap(), ptr ) - struct VirtualMemory { void* data; @@ -185,6 +179,8 @@ void arena_check (Arena* arena); void arena_free (Arena* arena); ssize arena_size_remaining(Arena* arena, ssize alignment); +// TODO(Ed): Add arena_pos, arena_pop, and arena_pop_to + struct Arena { AllocatorInfo Backing; diff --git a/base/dependencies/printing.hpp b/base/dependencies/printing.hpp index 5ddc20e..2550254 100644 --- a/base/dependencies/printing.hpp +++ b/base/dependencies/printing.hpp @@ -26,17 +26,4 @@ GEN_API ssize c_str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va ); constexpr char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; -inline -ssize log_fmt(char const* fmt, ...) -{ - ssize res; - va_list va; - - va_start(va, fmt); - res = c_str_fmt_out_va(fmt, va); - va_end(va); - - return res; -} - #pragma endregion Printing