From 578fa33605fa542c8873a6af796ce6b065fd4481 Mon Sep 17 00:00:00 2001 From: krzosa Date: Mon, 30 Dec 2024 16:09:02 +0100 Subject: [PATCH] core_log --- build_file.c | 4 +- src/app/app.meta.c | 4 +- src/app/app_wasm.c | 91 +++++++------- src/core/core.c | 7 ++ src/core/core.h | 4 +- src/core/core_defines.h | 39 +++--- src/core/core_intrin.c | 68 ++++++----- src/core/core_intrin.h | 22 ++-- src/core/core_lexer.c | 62 ++++++---- src/core/core_lexer.h | 9 +- src/core/core_log.c | 85 +++++++++---- src/core/core_log.h | 203 +++++++++++++++++++++++++++++-- src/core/core_math.c | 53 ++++---- src/core/core_platform_defines.h | 10 +- src/core/core_string.c | 4 +- src/core/core_string.h | 8 +- src/core/core_type_info.c | 20 +-- src/core/core_type_info.h | 17 ++- src/core_test/core_test_entry.c | 3 +- src/meta/parser.c | 22 ++-- src/meta/serialize.c | 18 +-- 21 files changed, 494 insertions(+), 259 deletions(-) diff --git a/build_file.c b/build_file.c index 5e8831c..30b85c7 100644 --- a/build_file.c +++ b/build_file.c @@ -16,9 +16,9 @@ int main(int argc, char **argv) { meta_app(arena); bool run_server = false; - bool core_test_target = true; + bool core_test_target = false; bool wasm_target = true; - bool win32_target = false; + bool win32_target = true; if (run_server) { os_systemf("start /D ..\\package ..\\package\\run_server.bat"); diff --git a/src/app/app.meta.c b/src/app/app.meta.c index 2e0802a..0ddf2e4 100644 --- a/src/app/app.meta.c +++ b/src/app/app.meta.c @@ -3,7 +3,7 @@ void meta_app(ma_arena_t *arena) { sb8_t *c = sb8_serial_begin(arena); - ast_t *keys = parse_table(arena, __FILE__, CODE( + ast_t *keys = parse_table(arena, __FILE__, S8_CODE( // javascript filter out | name | js1 | js2 | jf | windows1 | windows2 | | null | XXX | XXX | 1 | XXX | XXX | @@ -136,7 +136,7 @@ void meta_app(ma_arena_t *arena) { } { - ast_t *decls = parse_decls(arena, __FILE__, CODE( + ast_t *decls = parse_decls(arena, __FILE__, S8_CODE( typedef enum { app_mouse_button_null, app_mouse_button_left, diff --git a/src/app/app_wasm.c b/src/app/app_wasm.c index 4a90be6..944f992 100644 --- a/src/app/app_wasm.c +++ b/src/app/app_wasm.c @@ -1,62 +1,63 @@ -#define WASM_EXPORT __attribute__((visibility("default"))) +#define glb_wasm_export __attribute__((visibility("default"))) +#define fn_wasm_export __attribute__((visibility("default"))) +#define fn_wasm_import -f64 wasm_parse_float(isize str, i32 len); -void wasm_write_to_console(isize str, i32 len); -void wasm_draw_text(isize str, i32 len, f64 x, f64 y, isize font_str, i32 font_len, i32 font_size, f32 r, f32 g, f32 b, f32 a); -void wasm_draw_rect(f64 x, f64 y, f64 w, f64 h, f32 r, f32 g, f32 b, f32 a); -f64 wasm_measure_text(isize str, i32 len, isize font_str, i32 font_len, i32 font_size); -f64 wasm_get_font_height(isize font_str, i32 font_len, i32 font_size); -void wasm_set_clip(f64 x, f64 y, f64 w, f64 h); +fn_wasm_import f64 wasm_parse_float(isize str, i32 len); +fn_wasm_import void wasm_write_to_console(isize str, i32 len); +fn_wasm_import void wasm_draw_text(isize str, i32 len, f64 x, f64 y, isize font_str, i32 font_len, i32 font_size, f32 r, f32 g, f32 b, f32 a); +fn_wasm_import void wasm_draw_rect(f64 x, f64 y, f64 w, f64 h, f32 r, f32 g, f32 b, f32 a); +fn_wasm_import f64 wasm_measure_text(isize str, i32 len, isize font_str, i32 font_len, i32 font_size); +fn_wasm_import f64 wasm_get_font_height(isize font_str, i32 font_len, i32 font_size); +fn_wasm_import void wasm_set_clip(f64 x, f64 y, f64 w, f64 h); -void app_update(ma_arena_t *perm_arena, app_event_t *events, i32 event_count); +glb_wasm_export char wasm_temp_buff1[128] = {[127] = 0x13}; +glb_wasm_export i32 wasm_temp_buff1_len = 127; +glb_wasm_export char wasm_temp_buff2[128] = {[127] = 0x13}; +glb_wasm_export i32 wasm_temp_buff2_len = 127; -extern char __heap_base; -ma_arena_t wasm_perm_arena; +extern char __heap_base; +glb ma_arena_t wasm_perm_arena; +glb char *font_face = "fira"; +glb i32 font_face_len = 4; +glb f64 wasm_dpr; +glb ma_arena_t *wasm_input_text_arena; +glb STACK(app_event_t, 64) wasm_events; +glb b32 wasm_event_failed_to_queue; +glb f64 wasm_last_time = 0; -WASM_EXPORT char wasm_temp_buff1[128] = {[127] = 0x13}; -WASM_EXPORT i32 wasm_temp_buff1_len = 127; -WASM_EXPORT char wasm_temp_buff2[128] = {[127] = 0x13}; -WASM_EXPORT i32 wasm_temp_buff2_len = 127; +fn void app_update(ma_arena_t *perm_arena, app_event_t *events, i32 event_count); -char *font_face = "fira"; -i32 font_face_len = 4; - -f64 wasm_dpr; -ma_arena_t *wasm_input_text_arena; -STACK(app_event_t, 64) wasm_events; -b32 wasm_event_failed_to_queue; -f64 wasm_last_time = 0; - -void write_to_console(s8_t string) { - wasm_write_to_console((isize)string.str, (i32)string.len); +fn void puts(const char *string) { + wasm_write_to_console((isize)string, (i32)str_len((char *)string)); } -f64 f64_from_s8(s8_t string) { - return wasm_parse_float((isize)string.str, (i32)string.len); +fn double strtod(const char *str, char **end_unused) { + assertf(end_unused == NULL, "second parameter should be null!!"); + return wasm_parse_float((isize)str, str_len((char *)str)); } -void set_clip(r2f64_t rect) { +fn void set_clip(r2f64_t rect) { wasm_set_clip(wasm_dpr * rect.min.x, wasm_dpr * rect.min.y, wasm_dpr * (rect.max.x - rect.min.x), wasm_dpr * (rect.max.y - rect.min.y)); } -f64 get_font_height(void) { +fn f64 get_font_height(void) { return wasm_get_font_height((isize) font_face, font_face_len, 20*wasm_dpr) / wasm_dpr; } -f64 measure_text_ex(char *str, i32 len) { +fn f64 measure_text_ex(char *str, i32 len) { return wasm_measure_text((isize)str, len, (isize) font_face, font_face_len, 20*wasm_dpr) / wasm_dpr; } -f64 measure_text(char *str) { +fn f64 measure_text(char *str) { return measure_text_ex(str, str_len(str)); } -void draw_text(v2f64_t pos, v4f32_t color, s8_t string) { +fn void draw_text(v2f64_t pos, v4f32_t color, s8_t string) { wasm_draw_text((isize)string.str, string.len, wasm_dpr * pos.x, wasm_dpr * pos.y, (isize) font_face, font_face_len, 20*wasm_dpr, color.r * 255.f, color.g * 255.f, color.b * 255.f, color.a); } -void draw_textf(v2f64_t pos, char *str, ...) { +fn void draw_textf(v2f64_t pos, char *str, ...) { char buff[1024]; va_list args; va_start(args, str); @@ -66,11 +67,11 @@ void draw_textf(v2f64_t pos, char *str, ...) { wasm_draw_text((isize)buff, len, wasm_dpr * pos.x, wasm_dpr * pos.y, (isize) font_face, font_face_len, 20*wasm_dpr, 0, 0, 0, 1); } -void draw_rect(r2f64_t rect, v4f32_t color) { +fn void draw_rect(r2f64_t rect, v4f32_t color) { wasm_draw_rect(wasm_dpr * rect.min.x, wasm_dpr * rect.min.y, wasm_dpr * (rect.max.x - rect.min.x), wasm_dpr * (rect.max.y - rect.min.y), color.r * 255.f, color.g * 255.f, color.b * 255.f, color.a); } -void wasm_add_event(app_event_t event) { +fn void wasm_add_event(app_event_t event) { if (wasm_events.len < lengthof(wasm_events.data)) { STACK_PUSH(wasm_events, event); } else if (wasm_event_failed_to_queue == false) { @@ -79,7 +80,7 @@ void wasm_add_event(app_event_t event) { } } -WASM_EXPORT void wasm_mouse_move(f64 x, f64 y, b32 ctrl, b32 shift, b32 alt, b32 meta) { +fn_wasm_export void wasm_mouse_move(f64 x, f64 y, b32 ctrl, b32 shift, b32 alt, b32 meta) { wasm_add_event((app_event_t){ .kind = app_event_kind_mouse_move, .mouse_pos = {x, y}, @@ -90,7 +91,7 @@ WASM_EXPORT void wasm_mouse_move(f64 x, f64 y, b32 ctrl, b32 shift, b32 alt, b32 }); } -WASM_EXPORT void wasm_mouse_down(f64 x, f64 y, i32 button, b32 ctrl, b32 shift, b32 alt, b32 meta) { +fn_wasm_export void wasm_mouse_down(f64 x, f64 y, i32 button, b32 ctrl, b32 shift, b32 alt, b32 meta) { button += 1; assert(button >= app_mouse_button_left && button <= app_mouse_button_right); wasm_add_event((app_event_t){ @@ -104,7 +105,7 @@ WASM_EXPORT void wasm_mouse_down(f64 x, f64 y, i32 button, b32 ctrl, b32 shift, }); } -WASM_EXPORT void wasm_mouse_up(f64 x, f64 y, i32 button, b32 ctrl, b32 shift, b32 alt, b32 meta) { +fn_wasm_export void wasm_mouse_up(f64 x, f64 y, i32 button, b32 ctrl, b32 shift, b32 alt, b32 meta) { button += 1; assert(button >= app_mouse_button_left && button <= app_mouse_button_right); wasm_add_event((app_event_t){ @@ -118,7 +119,7 @@ WASM_EXPORT void wasm_mouse_up(f64 x, f64 y, i32 button, b32 ctrl, b32 shift, b3 }); } -WASM_EXPORT void wasm_mouse_wheel(f64 delta_x, f64 delta_y, f64 delta_z, b32 ctrl, b32 shift, b32 alt, b32 meta) { +fn_wasm_export void wasm_mouse_wheel(f64 delta_x, f64 delta_y, f64 delta_z, b32 ctrl, b32 shift, b32 alt, b32 meta) { wasm_add_event((app_event_t){ .kind = app_event_kind_mouse_wheel, .mouse_wheel_delta = {delta_x, delta_y, delta_z}, @@ -129,7 +130,7 @@ WASM_EXPORT void wasm_mouse_wheel(f64 delta_x, f64 delta_y, f64 delta_z, b32 ctr }); } -WASM_EXPORT void wasm_key_down(char *key, b32 ctrl, b32 shift, b32 alt, b32 meta) { +fn_wasm_export void wasm_key_down(char *key, b32 ctrl, b32 shift, b32 alt, b32 meta) { assert(wasm_temp_buff1[127] == 0x13); // make sure we didn't overwrite memory in JS assert(wasm_temp_buff2[127] == 0x13); s8_t key8 = s8_from_char(key); @@ -162,7 +163,7 @@ WASM_EXPORT void wasm_key_down(char *key, b32 ctrl, b32 shift, b32 alt, b32 meta }); } -WASM_EXPORT void wasm_key_up(char *key, b32 ctrl, b32 shift, b32 alt, b32 meta) { +fn_wasm_export void wasm_key_up(char *key, b32 ctrl, b32 shift, b32 alt, b32 meta) { assert(wasm_temp_buff1[127] == 0x13); // make sure we didn't overwrite memory in JS assert(wasm_temp_buff2[127] == 0x13); s8_t key8 = s8_from_char(key); @@ -180,7 +181,7 @@ WASM_EXPORT void wasm_key_up(char *key, b32 ctrl, b32 shift, b32 alt, b32 meta) } } -WASM_EXPORT void wasm_update(f64 time, f64 width, f64 height, f64 dpr) { +fn_wasm_export void wasm_update(f64 time, f64 width, f64 height, f64 dpr) { f64 delta_time = (time - wasm_last_time); for (i32 i = 0; i < wasm_events.len; i += 1) { wasm_events.data[i].dpr = dpr; @@ -197,7 +198,7 @@ WASM_EXPORT void wasm_update(f64 time, f64 width, f64 height, f64 dpr) { ma_set0(wasm_input_text_arena); } -WASM_EXPORT void wasm_init(void) { +fn_wasm_export void wasm_init(void) { isize page_size = kib(64); isize page_count = __builtin_wasm_memory_size(0); u8 *memory = (u8 *)&__heap_base; @@ -205,5 +206,5 @@ WASM_EXPORT void wasm_init(void) { wasm_perm_arena.data = memory; wasm_perm_arena.commit = wasm_perm_arena.reserve = memory_size; wasm_input_text_arena = ma_push_arena(&wasm_perm_arena, kib(1)); - debugexf("on_init, __builtin_wasm_memory_size(0) = %d(%d)", page_count, memory_size); + debugf("on_init, __builtin_wasm_memory_size(0) = %d(%d)", page_count, memory_size); } \ No newline at end of file diff --git a/src/core/core.c b/src/core/core.c index 9730afc..6283de3 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -4,6 +4,7 @@ #include #endif + #if PLATFORM_ADDRESS_SANITIZER #include #endif @@ -16,11 +17,17 @@ #define MA_ASAN_UNPOISON_MEMORY_REGION(addr, size) ASAN_UNPOISON_MEMORY_REGION(addr, size) #endif +#if PLATFORM_WASM +double strtod(const char *str, char **end_unused); +void puts(const char *str); +#endif + #if PLATFORM_CL #include #include #include #include +#include #endif #include "core_intrin.c" diff --git a/src/core/core.h b/src/core/core.h index 71d67f3..e5de7ce 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -8,6 +8,6 @@ #include "core_string.h" #include "core_lexer.h" #include "core_math.h" -#include "core_intrin.h" +#include "core_log.h" #include "core_type_info.h" -#include "core_log.h" \ No newline at end of file +#include "core_intrin.h" \ No newline at end of file diff --git a/src/core/core_defines.h b/src/core/core_defines.h index d6e164a..05db35e 100644 --- a/src/core/core_defines.h +++ b/src/core/core_defines.h @@ -29,6 +29,11 @@ typedef double f64; #define glb #define locl +#define U64_TO_F64(x) (((union { f64 f; u64 i; }) { .i = (x) }).f) +#define U32_TO_F32(x) (((union { f32 f; u32 i; }) { .i = (x) }).f) +#define F64_TO_U64(x) (((union { f64 f; u64 i; }) { .f = (x) }).i) +#define F32_TO_U32(x) (((union { f32 f; u32 i; }) { .f = (x) }).i) + #define MIN(x,y) ((x) > (y) ? (y) : (x)) #define MAX(x,y) ((x) > (y) ? (x) : (y)) @@ -58,34 +63,13 @@ typedef double f64; #define PASTE(a, b) PASTE_(a, b) #define SWAP(t, a, b) do { t PASTE(temp__, __LINE__) = a; a = b; b = PASTE(temp__, __LINE__); } while(0) #define CODE(...) #__VA_ARGS__ -#define S8_CODE(...) s8_lit(#__VA_ARGS__) -#if PLATFORM_CL +#ifndef FILE_AND_LINE_GCC_FORMAT #define FILE_AND_LINE __FILE__"("STRINGIFY(__LINE__)")" #else #define FILE_AND_LINE __FILE__":"STRINGIFY(__LINE__) #endif -#if PLATFORM_CL -#define debug__break() __debugbreak() -#else -#define debug__break() __builtin_trap() -#endif -#define debug_break() (debug__break(), 0) - -#if PLATFORM_ASSERT -#define assert(x) (!(x) && debug_break()) - -#define assertf(x, ...) do {\ - debugf(__VA_ARGS__);\ - assert(x);\ -} while(0) - -#else -#define assert(x) ((void)(x)) -#define assertf(x,...) ((void)(x)) -#endif - #if PLATFORM_WASM #define THREAD_LOCAL #elif PLATFORM_GCC | PLATFORM_CLANG @@ -96,6 +80,17 @@ typedef double f64; #define THREAD_LOCAL _Thread_local #endif +typedef struct date_t date_t; +struct date_t { + u16 ms; + u16 sec; + u16 min; + u16 hour; + u16 day; + u16 month; + u16 year; +}; + // Single linked list Queue #define SLLQ_APPEND_MOD(f, l, n, next) \ do { \ diff --git a/src/core/core_intrin.c b/src/core/core_intrin.c index 2b43151..c554f98 100644 --- a/src/core/core_intrin.c +++ b/src/core/core_intrin.c @@ -79,42 +79,46 @@ b32 vmem_release(void *p) { return true; } b32 vmem_decommit(void *p, usize size) { return true; } #endif -#if PLATFORM_WASM -f64 f64_from_s8(s8_t string); -void write_to_console(s8_t string); -#else fn f64 f64_from_s8(s8_t string) { - return strtod(string.str, NULL); -} -#endif - -fn void core_log_message(s8_t string) { -#if PLATFORM_WINDOWS ma_temp_t scratch = ma_begin_scratch(); - s8_t copy = s8_copy(scratch.arena, string); - OutputDebugStringA(copy.str); + s8_t num_string = s8_copy(scratch.arena, string); + f64 result = strtod(num_string.str, NULL); ma_end_scratch(scratch); + return result; +} - printf("%.*s", (int)string.len, string.str); - fflush(stdout); -#elif PLATFORM_WASM - write_to_console(string); -#else - printf("%.*s", (int)string.len, string.str); - fflush(stdout); +fn void core_print_message(s8_t string) { + ma_temp_t scratch = ma_begin_scratch(); + s8_t copy = s8_printf(scratch.arena, "%S\n", string); +#if PLATFORM_WINDOWS + OutputDebugStringA(copy.str); #endif + puts(copy.str); + ma_end_scratch(scratch); } -fn void core_panic(void) { - if (core_desc.on_exit) core_desc.on_exit(); - SWITCH_PLATFORM_WINDOWS_WASM_ELSE( - ExitProcess(1), - debug_break(), - exit(1) - ); -} - -fn void core_on_exit(void) { - debugf("program panicked! exiting..."); -} - +fn date_t date_now(void) { + date_t result = {0}; +#if PLATFORM_WASM +#elif PLATFORM_WINDOWS + SYSTEMTIME lt; + GetLocalTime(<); + result.ms = lt.wMilliseconds; + result.sec = lt.wSecond; + result.min = lt.wMinute; + result.hour = lt.wHour; + result.day = lt.wDay; + result.month = lt.wMonth; + result.year = lt.wYear; +#else + time_t time = time(NULL); + struct tm *lt = localtime(&time); + result.sec = lt->tm_sec; + result.min = lt->tm_min; + result.hour = lt->tm_hour; + result.day = lt->tm_mday; + result.month = lt->tm_month; + result.year = lt->tm_year; +#endif + return result; +} \ No newline at end of file diff --git a/src/core/core_intrin.h b/src/core/core_intrin.h index 164d458..6fcb752 100644 --- a/src/core/core_intrin.h +++ b/src/core/core_intrin.h @@ -1,11 +1,8 @@ typedef struct core_desc_t core_desc_t; struct core_desc_t { - void (*print)(s8_t string); - void (*panic)(void); - void (*on_exit)(void); - ma_arena_t scratch[3]; - b32 break_on_panic; + + logger_t log; }; fn void memory_copy(void *dst, void *src, usize n); @@ -32,15 +29,12 @@ fn f64 f64_round(f64 x); fn f64 f64_mod(f64 a, f64 b); fn f32 f32_mod(f32 a, f32 b); -// -// defaults -fn void core_on_exit(void); -fn void core_panic(void); -fn void core_log_message(s8_t string); +fn void default_log_proc(log_event_t ev); THREAD_LOCAL core_desc_t core_desc = { - .print = core_log_message, - .panic = core_panic, - .on_exit = core_on_exit, - .break_on_panic = true, + .log = { + .break_on_fatal = true, + .log_proc = default_log_proc, + .flags = log_flag_all, + } }; diff --git a/src/core/core_lexer.c b/src/core/core_lexer.c index cce5fad..a6a5449 100644 --- a/src/core/core_lexer.c +++ b/src/core/core_lexer.c @@ -1,17 +1,18 @@ -fn void lex_panicf(lex_t *token, const char *str, ...) { - ma_temp_t scratch = ma_begin_scratch(); - S8_FMT(scratch.arena, str, str8); - panicf("%s(%d:%d): error: %S", token->file_name, token->line, token->column, str8); - ma_end_scratch(scratch); -} +const i32 module_lex = 1; -fn lexer_t lex_make(char *begin, char *file_name) { - lexer_t result = {.at = begin, .file_name = file_name}; +#define lex_error(TOKEN, STRING) do {\ + errorf(module_lex, STRING);\ + TOKEN->kind = lex_kind_error;\ + TOKEN->string = s8_lit(STRING);\ +} while (0) + +fn lexer_t lex_make(s8_t stream, char *file_name) { + lexer_t result = {.at = stream.str, .end = stream.str + stream.len, .file_name = file_name}; return result; } fn void lex_advance(lexer_t *lex) { - if (lex->at[0] == 0) return; + if (lex->at >= lex->end) return; if (lex->at[0] == '\n') { lex->column = 0; lex->line += 1; } lex->column += 1; lex->at += 1; @@ -39,7 +40,8 @@ fn void lex_eat_number(lexer_t *lex, lex_t *token) { if (lex_match(lex, '.')) { if (token->kind == lex_kind_real) { - lex_panicf(token, "multiple '.' periods in floating point number literal"); + lex_error(token, "multiple '.' periods in floating point number literal"); + return; } token->kind = lex_kind_real; continue; @@ -81,24 +83,25 @@ fn void lex_eat_string(lexer_t *lex, lex_t *token) { } if (lex->at[0] == 0) { - lex_panicf(token, "unclosed string"); + lex_error(token, "unclosed string"); + return; } lex_advance(lex); } } -#define LEX_CASE3(C1, K1, C2, K2, C3, K3)\ -case C1: {\ - token->kind = K1;\ - if (lex_match(lex, C2)) {\ - lex_advance(lex);\ - token->kind = K2;\ - } else if (lex_match(lex, C3)) {\ - lex_advance(lex);\ - token->kind = K3;\ - }\ -} break +#define LEX_CASE3(C1, K1, C2, K2, C3, K3) \ + case C1: { \ + token->kind = K1; \ + if (lex_match(lex, C2)) { \ + lex_advance(lex); \ + token->kind = K2; \ + } else if (lex_match(lex, C3)) { \ + lex_advance(lex); \ + token->kind = K3; \ + } \ + } break fn void lex_token_ex(lexer_t *lex, lex_t *token) { lex_eat_whitespace(lex); @@ -142,7 +145,7 @@ fn void lex_token_ex(lexer_t *lex, lex_t *token) { break; } if (lex->at[0] == 0) { - lex_panicf(token, "Unclosed block comment"); + lex_error(token, "unclosed block comment"); return; } lex_advance(lex); @@ -208,7 +211,7 @@ fn void lex_token_ex(lexer_t *lex, lex_t *token) { } break; default: { - lex_panicf(token, "found invalid character in the token stream (%d)", token->str[0]); + lex_error(token, "found invalid character in the token stream"); } } @@ -231,7 +234,7 @@ fn lex_t lex_token(lexer_t *lex) { } // @todo: use s8_t instead -fn lex_array_t lex_tokens(ma_arena_t *arena, char *file_name, char *stream) { +fn lex_array_t lex_tokens(ma_arena_t *arena, char *file_name, s8_t stream) { usize align = arena->align; arena->align = 0; @@ -298,9 +301,16 @@ fn lex_t *parser_matchi(parser_t *par, s8_t str) { } } +fn void parser_panicf(lex_t *token, const char *str, ...) { + ma_temp_t scratch = ma_begin_scratch(); + S8_FMT(scratch.arena, str, str8); + fatalf("%s(%d:%d): error: %S", token->file_name, token->line, token->column, str8); + ma_end_scratch(scratch); +} + fn lex_t *parser_expect(parser_t *par, lex_kind_t kind) { lex_t *token = parser_match(par, kind); - if (!token) lex_panicf(par->at, "expected token kind: %S, got instead: %S", lex_kind_to_s8(kind), lex_kind_to_s8(par->at->kind)); + if (!token) parser_panicf(par->at, "expected token kind: %S, got instead: %S", lex_kind_to_s8(kind), lex_kind_to_s8(par->at->kind)); return token; } diff --git a/src/core/core_lexer.h b/src/core/core_lexer.h index dea1586..bc65443 100644 --- a/src/core/core_lexer.h +++ b/src/core/core_lexer.h @@ -2,6 +2,7 @@ typedef enum lex_kind_t lex_kind_t; enum lex_kind_t { #define LEX_KIND_XLIST\ X(eof, "end of file", "---")\ + X(error, "error", "---")\ X(integer, "integer", "---")\ X(real, "real", "---")\ X(ident, "identifier", "---")\ @@ -56,7 +57,6 @@ enum lex_kind_t { X(arrow, "'->' arrow", "->")\ X(question, "'?' question mark", "?")\ - #define X(KIND, STR, SIMPLE) lex_kind_##KIND, LEX_KIND_XLIST #undef X @@ -98,6 +98,7 @@ struct lex_t { typedef struct lexer_t lexer_t; struct lexer_t { char *at; + char *end; char *file_name; i32 line; i32 column; @@ -109,10 +110,7 @@ struct lex_array_t { i32 len; }; -// @todo: use s8 -fn void lex_panicf(lex_t *token, const char *str, ...); -fn lex_array_t lex_tokens(ma_arena_t *arena, char *file_name, char *stream); - +fn lex_array_t lex_tokens(ma_arena_t *arena, char *filename, s8_t stream); fn s8_t lex_kind_to_simple_s8(lex_kind_t kind); fn s8_t lex_kind_to_s8(lex_kind_t kind); @@ -128,6 +126,7 @@ fn lex_t *parser_next(parser_t *par); fn lex_t *parser_match(parser_t *par, lex_kind_t kind); fn lex_t *parser_matchi(parser_t *par, s8_t str); fn lex_t *parser_expect(parser_t *par, lex_kind_t kind); +fn void parser_panicf(lex_t *token, const char *str, ...); fn void parser_eat_until(parser_t *par, lex_kind_t kind); fn void parser_eat_including(parser_t *par, lex_kind_t kind); diff --git a/src/core/core_log.c b/src/core/core_log.c index 5656279..8e6dbd8 100644 --- a/src/core/core_log.c +++ b/src/core/core_log.c @@ -1,30 +1,69 @@ -void panicf(const char *_str, ...) { - ma_temp_t scratch = ma_begin_scratch(); - S8_FMT(scratch.arena, _str, str8); - core_desc.print(str8); - core_desc.print(s8_lit("\n")); - if (core_desc.break_on_panic) { - #if PLATFORM_WINDOWS - if (IsDebuggerPresent()) - #endif - debug_break(); - } else { - core_desc.panic(); +fn s8_t log_level_str(log_level_t level) { + switch(level) { + case log_level_debug: return s8_lit("DEBUG"); + case log_level_info: return s8_lit("INFO"); + case log_level_warning: return s8_lit("WARN"); + case log_level_error: return s8_lit("ERROR"); + case log_level_fatal: return s8_lit("FATAL"); + default: return s8_lit("INVALID"); } +} + +fn void log_base(i32 module, log_level_t level, s8_t file_and_line, s8_t string) { + core_desc.log.log_proc((log_event_t){module, level, file_and_line, string}); +} + +fn void log_basef(i32 module, log_level_t level, s8_t file_and_line, const char *str, ...) { + ma_temp_t scratch = ma_begin_scratch(); + S8_FMT(scratch.arena, str, str8); + log_base(module, level, file_and_line, str8); ma_end_scratch(scratch); } -void debugexf(const char *_str, ...) { +fn void default_log_proc(log_event_t ev) { ma_temp_t scratch = ma_begin_scratch(); - S8_FMT(scratch.arena, _str, str); - core_desc.print(str); - ma_end_scratch(scratch); -} + sb8_t *sb = sb8_serial_begin(scratch.arena); + if (core_desc.log.flags & log_flag_module_id) { + sb8_printf(sb, "[%d] ", ev.module); + } + if (core_desc.log.flags & log_flag_level) { + sb8_printf(sb, "%-5S ", log_level_str(ev.level)); + } + date_t date = {0}; + { + b32 bdate = (core_desc.log.flags & log_flag_date); + b32 btime = (core_desc.log.flags & log_flag_time); + if (bdate || btime) { + date = date_now(); + } + if (bdate) { + sb8_printf(sb, "%04u.%02u.%02u ", date.year, date.month, date.day); + } + if (btime) { + sb8_printf(sb, "%02u:%02u:%02u ", date.hour, date.min, date.sec); + } + } + if (core_desc.log.flags & log_flag_file_path) { + sb8_printf(sb, "%-40S ", ev.file_and_line); + } -void debugf(const char *_str, ...) { - ma_temp_t scratch = ma_begin_scratch(); - S8_FMT(scratch.arena, _str, str); - core_desc.print(str); - core_desc.print(s8_lit("\n")); + sb8_printf(sb, " %S", ev.string); + s8_t result = sb8_serial_end(sb); + core_print_message(result); ma_end_scratch(scratch); -} \ No newline at end of file + + if (ev.level == log_level_fatal) { + if (core_desc.log.break_on_fatal) { +#if PLATFORM_WINDOWS + if (IsDebuggerPresent()) +#endif + debug_break(); + } else { + SWITCH_PLATFORM_WINDOWS_WASM_ELSE( + ExitProcess(1), + debug_break(), + exit(1) + ); + } + } +} diff --git a/src/core/core_log.h b/src/core/core_log.h index a5a2b7f..6e1f0f9 100644 --- a/src/core/core_log.h +++ b/src/core/core_log.h @@ -1,12 +1,195 @@ /* -** [ ] investigate: how to design api! (minimal platform code) -** [ ] ryan and allen do some kind of log data structure, is that worth anything? -** [ ] how programming languages do it? -** [ ] probably want to log stuff without it being in my face all the time -** [ ] want to warn user without quiting with option of silencing -** (use case: lexing error but don't care) -** [ ] wasm doesn't handle console logging without new line XD +** design: +** two modes of working: +** optional immediate dump to console +** optional store and retrieval data structure +** +** [ ] console +** [ ] silence very particular messages (use case: user tries to tokenize c code, +** cares only about particular decls, +** does not want to see error flood) +** [ ] graphical integrated into application +** [ ] little counter of unread warnings/errors, somewhere in the corner, that you can click on +** [ ] hierarchy which you can traverse, dive into things which interest you +** [ ] support for very arbitrary logs: "log_triangle", which would show debug points on screen +** +** +** */ -void debugf(const char *string, ...); -void debugexf(const char *string, ...); -void panicf(const char *string, ...); +const i32 module_null = 0; + +typedef enum { + log_flag_null = 0, + log_flag_level = 1, + log_flag_date = 2, + log_flag_time = 4, + log_flag_file_path = 8, + log_flag_module_id = 16, + log_flag_all = log_flag_level | log_flag_date | log_flag_time | log_flag_file_path | log_flag_module_id, +} log_flag_t; + +typedef enum { // AFTER_CHANGING: modify type_info and log_level_str + log_level_debug, + log_level_info, + log_level_warning, + log_level_error, + log_level_fatal, +} log_level_t; + +typedef struct log_event_t log_event_t; +struct log_event_t { + i32 module; + log_level_t level; + s8_t file_and_line; + s8_t string; +}; + +typedef struct logger_t logger_t; +struct logger_t { + void (*log_proc)(log_event_t); + void *user_data; + log_flag_t flags; + b32 break_on_fatal; +}; + +fn void log_base(i32 module, log_level_t level, s8_t file_and_line, s8_t string); +fn void log_basef(i32 module, log_level_t level, s8_t file_and_line, const char *str, ...); +fn s8_t log_level_str(log_level_t level); + +#define debugf(...) log_basef(module_null, log_level_debug, S8_FILE_AND_LINE, __VA_ARGS__) +#define errorf(MODULE, ...) log_basef(MODULE, log_level_error, S8_FILE_AND_LINE, __VA_ARGS__) +#define fatalf(...) (log_basef(module_null, log_level_fatal, S8_FILE_AND_LINE, __VA_ARGS__), 0) + +#define assert(x) (!(x) && fatalf("condition doesn't hold: " #x)) +#define assertf(x, ...) (!(x) && fatalf("condition doesn't hold: " __VA_ARGS__)) + +#if PLATFORM_CL +#define debug__break() __debugbreak() +#else +#define debug__break() __builtin_trap() +#endif +#define debug_break() (debug__break(), 0) + + +/* + +Seems like there are 2 logging categories: +1. Logging in a graphical program where you have control over how logs are displayed +2. Logging in a console program where you dump shit into conso + + +DESIGN ANALYSIS + +/////////////////////////////// +// rxi log.c api: +// > 22:54:32 INFO src/memes/memes.c:65: message + +log_trace(const char *fmt, ...); +log_debug(const char *fmt, ...); +log_info(const char *fmt, ...); +log_warn(const char *fmt, ...); +log_error(const char *fmt, ...); +log_fatal(const char *fmt, ...); + + +log_set_quiet(bool enable) +log_set_level(level) +log_add_fp(file, level) +log_add_callback(func, user_data, level) +log_set_lock(lock_func, void *user_data) + +/////////////////////////////// +// odin log package + +Logger_Proc :: #type proc(data: rawptr, level: Level, + text: string, options: Options, location := #caller_location); + +Logger :: struct { + procedure: Logger_Proc, + data: rawptr, + lowest_level: Level, + options: Logger_Options, +} + +Option :: enum { + Level, + Date, + Time, + Short_File_Path, + Long_File_Path, + Line, + Procedure, + Terminal_Color +} + +Logger_Level :: enum { + Debug = 0, + Info = 10, + Warning = 20, + Error = 30, + Fatal = 40, +} + +debugf() +infof() +warnf() +errorf() +fatalf() + +panic() +panicf() + +assert() +assertf() + +/////////////////////////////// +// raddebugger log + +Log { arena, LogScope *top_scope } (stack of LogScopes) +LogScope { LogScope *next, pos in arena to pop, StringList[LogMsgKinds] } +LogScopeResult { String[LogMsgKinds] } + + +internal Log *log_alloc(void); +internal void log_release(Log *log); +internal void log_select( + +internal void log_scope_begin(void); +internal LogScopeResult log_scope_end(Arena *are + + +#define log_info(s) log_msg(LogMsgKind_Info, (s)) +#define log_infof(fmt, ...) log_msgf(LogMsgKind_Info, (fmt), __VA_ARGS__) +#define log_user_error(s) log_msg(LogMsgKind_UserError, (s)) +#define log_user_errorf(fmt, ...) log_msgf(LogMsgKind_UserError, (fmt), __VA_ARGS__) + +#define LogInfoNamedBlock(s) DeferLoop(log_infof("%S:\n{\n", (s)), log_infof("}\n")) +#define LogInfoNamedBlockF(fmt, ...) DeferLoop((log_infof(fmt, __VA_ARGS__), log_infof(":\n{\n")), log_infof("}\n")) + +{ + log_scope_begin(); + + log_infof("user2ctrl_msg:{kind:\"%S\"}\n", ctrl_string_from_msg_kind(msg->kind)); + LogInfoNamedBlockF("dmn_event") + { + log_infof("kind: %S\n", dmn_event_kind_string_table[ev->kind]); + log_infof("exception_kind: %S\n", dmn_exception_kind_string_table[ev->exception_kind]); + log_infof("process: [%I64u]\n", ev->process.u64[0]); + log_infof("thread: [%I64u]\n", ev->thread.u64[0]); + log_infof("module: [%I64u]\n", ev->module.u64[0]); + log_infof("arch: %S\n", string_from_arch(ev->arch)); + log_infof("address: 0x%I64x\n", ev->address); + log_infof("string: \"%S\"\n", ev->string); + log_infof("ip_vaddr: 0x%I64x\n", ev->instruction_pointer); + } + + + LogScopeResult log = log_scope_end(scratch.arena); + ctrl_thread__flush_info_log(log.strings[LogMsgKind_Info]); + if(log.strings[LogMsgKind_UserError].size != 0) + { + Show to user + } +} + +*/ \ No newline at end of file diff --git a/src/core/core_math.c b/src/core/core_math.c index d8ba317..026cab0 100644 --- a/src/core/core_math.c +++ b/src/core/core_math.c @@ -98,20 +98,13 @@ v4f32_t v4f32_lerp(v4f32_t a, v4f32_t b, f32 t) { return (v4f32_t){f32_lerp(a.x, a.y, t), f32_lerp(a.y, b.y, t), f32_lerp(a.z, b.z, t), f32_lerp(a.w, b.w, t)}; } -#if PLATFORM_CL -#pragma warning(disable: 4116) -#endif - -#define U64ToF64(x) (((union { f64 d; u64 i; }) { .i = (x) }).d) -#define U32ToF32(x) (((union { f32 f; u32 i; }) { .i = (x) }).f) - f64 _Sine(f64 x) { // Calculates sin(x) for x in [0, pi/4]. f64 x2 = x * x; - return x * (U64ToF64(0x3FF0000000000000) + x2 * (U64ToF64(0xBFC5555555555540) + x2 * (U64ToF64(0x3F8111111110ED80) + x2 * (U64ToF64(0xBF2A01A019AE6000) - + x2 * (U64ToF64(0x3EC71DE349280000) + x2 * (U64ToF64(0xBE5AE5DC48000000) + x2 * U64ToF64(0x3DE5D68200000000))))))); + return x * (U64_TO_F64(0x3FF0000000000000) + x2 * (U64_TO_F64(0xBFC5555555555540) + x2 * (U64_TO_F64(0x3F8111111110ED80) + x2 * (U64_TO_F64(0xBF2A01A019AE6000) + + x2 * (U64_TO_F64(0x3EC71DE349280000) + x2 * (U64_TO_F64(0xBE5AE5DC48000000) + x2 * U64_TO_F64(0x3DE5D68200000000))))))); } f32 _SineFloat(f32 x) { @@ -119,7 +112,7 @@ f32 _SineFloat(f32 x) { f32 x2 = x * x; - return x * (U32ToF32(0x3F800000) + x2 * (U32ToF32(0xBE2AAAA0) + x2 * (U32ToF32(0x3C0882C0) + x2 * U32ToF32(0xB94C6000)))); + return x * (U32_TO_F32(0x3F800000) + x2 * (U32_TO_F32(0xBE2AAAA0) + x2 * (U32_TO_F32(0x3C0882C0) + x2 * U32_TO_F32(0xB94C6000)))); } f64 _ArcSine(f64 x) { @@ -127,10 +120,10 @@ f64 _ArcSine(f64 x) { f64 x2 = x * x; - return x * (U64ToF64(0x3FEFFFFFFFFFFFE6) + x2 * (U64ToF64(0x3FC555555555FE00) + x2 * (U64ToF64(0x3FB333333292DF90) + x2 * (U64ToF64(0x3FA6DB6DFD3693A0) - + x2 * (U64ToF64(0x3F9F1C608DE51900) + x2 * (U64ToF64(0x3F96EA0659B9A080) + x2 * (U64ToF64(0x3F91B4ABF1029100) - + x2 * (U64ToF64(0x3F8DA8DAF31ECD00) + x2 * (U64ToF64(0x3F81C01FD5000C00) + x2 * (U64ToF64(0x3F94BDA038CF6B00) - + x2 * (U64ToF64(0xBF8E849CA75B1E00) + x2 * U64ToF64(0x3FA146C2D37F2C60)))))))))))); + return x * (U64_TO_F64(0x3FEFFFFFFFFFFFE6) + x2 * (U64_TO_F64(0x3FC555555555FE00) + x2 * (U64_TO_F64(0x3FB333333292DF90) + x2 * (U64_TO_F64(0x3FA6DB6DFD3693A0) + + x2 * (U64_TO_F64(0x3F9F1C608DE51900) + x2 * (U64_TO_F64(0x3F96EA0659B9A080) + x2 * (U64_TO_F64(0x3F91B4ABF1029100) + + x2 * (U64_TO_F64(0x3F8DA8DAF31ECD00) + x2 * (U64_TO_F64(0x3F81C01FD5000C00) + x2 * (U64_TO_F64(0x3F94BDA038CF6B00) + + x2 * (U64_TO_F64(0xBF8E849CA75B1E00) + x2 * U64_TO_F64(0x3FA146C2D37F2C60)))))))))))); } f32 _ArcSineFloat(f32 x) { @@ -138,7 +131,7 @@ f32 _ArcSineFloat(f32 x) { f32 x2 = x * x; - return x * (U32ToF32(0x3F800004) + x2 * (U32ToF32(0x3E2AA130) + x2 * (U32ToF32(0x3D9B2C28) + x2 * (U32ToF32(0x3D1C1800) + x2 * U32ToF32(0x3D5A97C0))))); + return x * (U32_TO_F32(0x3F800004) + x2 * (U32_TO_F32(0x3E2AA130) + x2 * (U32_TO_F32(0x3D9B2C28) + x2 * (U32_TO_F32(0x3D1C1800) + x2 * U32_TO_F32(0x3D5A97C0))))); } f64 _ArcTangent(f64 x) { @@ -146,10 +139,10 @@ f64 _ArcTangent(f64 x) { f64 x2 = x * x; - return x * (U64ToF64(0x3FEFFFFFFFFFFFF8) + x2 * (U64ToF64(0xBFD5555555553B44) + x2 * (U64ToF64(0x3FC9999999803988) + x2 * (U64ToF64(0xBFC249248C882E80) - + x2 * (U64ToF64(0x3FBC71C5A4E4C220) + x2 * (U64ToF64(0xBFB745B3B75243F0) + x2 * (U64ToF64(0x3FB3AFAE9A2939E0) - + x2 * (U64ToF64(0xBFB1030C4A4A1B90) + x2 * (U64ToF64(0x3FAD6F65C35579A0) + x2 * (U64ToF64(0xBFA805BCFDAFEDC0) - + x2 * (U64ToF64(0x3F9FC6B5E115F2C0) + x2 * U64ToF64(0xBF87DCA5AB25BF80)))))))))))); + return x * (U64_TO_F64(0x3FEFFFFFFFFFFFF8) + x2 * (U64_TO_F64(0xBFD5555555553B44) + x2 * (U64_TO_F64(0x3FC9999999803988) + x2 * (U64_TO_F64(0xBFC249248C882E80) + + x2 * (U64_TO_F64(0x3FBC71C5A4E4C220) + x2 * (U64_TO_F64(0xBFB745B3B75243F0) + x2 * (U64_TO_F64(0x3FB3AFAE9A2939E0) + + x2 * (U64_TO_F64(0xBFB1030C4A4A1B90) + x2 * (U64_TO_F64(0x3FAD6F65C35579A0) + x2 * (U64_TO_F64(0xBFA805BCFDAFEDC0) + + x2 * (U64_TO_F64(0x3F9FC6B5E115F2C0) + x2 * U64_TO_F64(0xBF87DCA5AB25BF80)))))))))))); } f32 _ArcTangentFloat(f32 x) { @@ -157,7 +150,7 @@ f32 _ArcTangentFloat(f32 x) { f32 x2 = x * x; - return x * (U32ToF32(0x3F7FFFF8) + x2 * (U32ToF32(0xBEAAA53C) + x2 * (U32ToF32(0x3E4BC990) + x2 * (U32ToF32(0xBE084A60) + x2 * U32ToF32(0x3D8864B0))))); + return x * (U32_TO_F32(0x3F7FFFF8) + x2 * (U32_TO_F32(0xBEAAA53C) + x2 * (U32_TO_F32(0x3E4BC990) + x2 * (U32_TO_F32(0xBE084A60) + x2 * U32_TO_F32(0x3D8864B0))))); } f64 _Cosine(f64 x) { @@ -165,8 +158,8 @@ f64 _Cosine(f64 x) { f64 x2 = x * x; - return U64ToF64(0x3FF0000000000000) + x2 * (U64ToF64(0xBFDFFFFFFFFFFFA0) + x2 * (U64ToF64(0x3FA555555554F7C0) + x2 * (U64ToF64(0xBF56C16C16475C00) - + x2 * (U64ToF64(0x3EFA019F87490000) + x2 * (U64ToF64(0xBE927DF66B000000) + x2 * U64ToF64(0x3E21B949E0000000)))))); + return U64_TO_F64(0x3FF0000000000000) + x2 * (U64_TO_F64(0xBFDFFFFFFFFFFFA0) + x2 * (U64_TO_F64(0x3FA555555554F7C0) + x2 * (U64_TO_F64(0xBF56C16C16475C00) + + x2 * (U64_TO_F64(0x3EFA019F87490000) + x2 * (U64_TO_F64(0xBE927DF66B000000) + x2 * U64_TO_F64(0x3E21B949E0000000)))))); } f32 _CosineFloat(f32 x) { @@ -174,7 +167,7 @@ f32 _CosineFloat(f32 x) { f32 x2 = x * x; - return U32ToF32(0x3F800000) + x2 * (U32ToF32(0xBEFFFFDA) + x2 * (U32ToF32(0x3D2A9F60) + x2 * U32ToF32(0xBAB22C00))); + return U32_TO_F32(0x3F800000) + x2 * (U32_TO_F32(0xBEFFFFDA) + x2 * (U32_TO_F32(0x3D2A9F60) + x2 * U32_TO_F32(0xBAB22C00))); } f64 _Tangent(f64 x) { @@ -182,11 +175,11 @@ f64 _Tangent(f64 x) { f64 x2 = x * x; - return x * (U64ToF64(0x3FEFFFFFFFFFFFE8) + x2 * (U64ToF64(0x3FD5555555558000) + x2 * (U64ToF64(0x3FC1111110FACF90) + x2 * (U64ToF64(0x3FABA1BA266BFD20) - + x2 * (U64ToF64(0x3F9664F30E56E580) + x2 * (U64ToF64(0x3F822703B08BDC00) + x2 * (U64ToF64(0x3F6D698D2E4A4C00) - + x2 * (U64ToF64(0x3F57FF4F23EA4400) + x2 * (U64ToF64(0x3F424F3BEC845800) + x2 * (U64ToF64(0x3F34C78CA9F61000) - + x2 * (U64ToF64(0xBF042089F8510000) + x2 * (U64ToF64(0x3F29D7372D3A8000) + x2 * (U64ToF64(0xBF19D1C5EF6F0000) - + x2 * (U64ToF64(0x3F0980BDF11E8000))))))))))))))); + return x * (U64_TO_F64(0x3FEFFFFFFFFFFFE8) + x2 * (U64_TO_F64(0x3FD5555555558000) + x2 * (U64_TO_F64(0x3FC1111110FACF90) + x2 * (U64_TO_F64(0x3FABA1BA266BFD20) + + x2 * (U64_TO_F64(0x3F9664F30E56E580) + x2 * (U64_TO_F64(0x3F822703B08BDC00) + x2 * (U64_TO_F64(0x3F6D698D2E4A4C00) + + x2 * (U64_TO_F64(0x3F57FF4F23EA4400) + x2 * (U64_TO_F64(0x3F424F3BEC845800) + x2 * (U64_TO_F64(0x3F34C78CA9F61000) + + x2 * (U64_TO_F64(0xBF042089F8510000) + x2 * (U64_TO_F64(0x3F29D7372D3A8000) + x2 * (U64_TO_F64(0xBF19D1C5EF6F0000) + + x2 * (U64_TO_F64(0x3F0980BDF11E8000))))))))))))))); } f32 _TangentFloat(f32 x) { @@ -194,8 +187,8 @@ f32 _TangentFloat(f32 x) { f32 x2 = x * x; - return x * (U32ToF32(0x3F800001) + x2 * (U32ToF32(0x3EAAA9AA) + x2 * (U32ToF32(0x3E08ABA8) + x2 * (U32ToF32(0x3D58EC90) - + x2 * (U32ToF32(0x3CD24840) + x2 * (U32ToF32(0x3AC3CA00) + x2 * U32ToF32(0x3C272F00))))))); + return x * (U32_TO_F32(0x3F800001) + x2 * (U32_TO_F32(0x3EAAA9AA) + x2 * (U32_TO_F32(0x3E08ABA8) + x2 * (U32_TO_F32(0x3D58EC90) + + x2 * (U32_TO_F32(0x3CD24840) + x2 * (U32_TO_F32(0x3AC3CA00) + x2 * U32_TO_F32(0x3C272F00))))))); } diff --git a/src/core/core_platform_defines.h b/src/core/core_platform_defines.h index a507553..c5d0128 100644 --- a/src/core/core_platform_defines.h +++ b/src/core/core_platform_defines.h @@ -60,10 +60,6 @@ #define PLATFORM_TCC 0 #endif -#ifndef PLATFORM_ASSERT -#define PLATFORM_ASSERT 1 -#endif - #ifndef PLATFORM_ADDRESS_SANITIZER #define PLATFORM_ADDRESS_SANITIZER 0 #endif @@ -76,5 +72,7 @@ #define SWITCH_PLATFORM_WINDOWS_WASM_ELSE(WINDOWS, WASM, ELSE) ELSE #endif -#define IF_PLATFORM_WINDOWS(x) SWITCH_PLATFORM_WINDOWS_WASM_ELSE(x, ((void)0), ((void)0)) -#define IF_PLATFORM_NOT_WINDOWS(x) SWITCH_PLATFORM_WINDOWS_WASM_ELSE(((void)0), x, x) + +#if PLATFORM_CL +#pragma warning(disable: 4116) +#endif diff --git a/src/core/core_string.c b/src/core/core_string.c index 24c50df..e4e8a21 100644 --- a/src/core/core_string.c +++ b/src/core/core_string.c @@ -371,7 +371,7 @@ fn s8_t s8_vfmt(ma_arena_t *ma, const char *str, va_list args1) { return res; } -fn s8_t s8_fmt(ma_arena_t *ma, const char *str, ...) { +fn s8_t s8_printf(ma_arena_t *ma, const char *str, ...) { S8_FMT(ma, str, result); return result; } @@ -477,7 +477,7 @@ fn u64 u64_from_s8(s8_t s, u64 base) { for (i64 i = 0; i < s.len; i++) { u64 num = u64_from_hexchar(s.str[i]); if (num >= base) { - panicf("invalid number"); + fatalf("failed to convert string into number, didn't expect: %c", s.str[i]); break; } acc *= base; diff --git a/src/core/core_string.h b/src/core/core_string.h index 7a23c36..274cf15 100644 --- a/src/core/core_string.h +++ b/src/core/core_string.h @@ -112,11 +112,11 @@ fn s8_t s8_normalize_path(ma_arena_t *ma, s8_t s); fn s8_t s8_to_lower_case(ma_arena_t *ma, s8_t s); fn s8_t s8_to_upper_case(ma_arena_t *ma, s8_t s); fn s8_t s8_vfmt(ma_arena_t *ma, const char *str, va_list args1); -fn s8_t s8_fmt(ma_arena_t *ma, const char *str, ...); +fn s8_t s8_printf(ma_arena_t *ma, const char *str, ...); // // string builder -#define sb8_serial_begin(arena) &(sb8_t){.arena = arena} +#define sb8_serial_begin(ARENA) &(sb8_t){.arena = ARENA} #define sb8_serial_end(sb) sb8_merge(sb) fn s8_t sb8_printf(sb8_t *sb, const char *str, ...); @@ -134,6 +134,10 @@ fn int64_t sb8_char_size(sb8_t *sb); fn u64 u64_from_hexchar(char c); fn u64 u64_from_s8(s8_t s, u64 base); +#define S8_CODE(...) s8_lit(#__VA_ARGS__) +#define S8_FILE s8_lit(__FILE__) +#define S8_FILE_AND_LINE s8_lit(FILE_AND_LINE) + #define S8_FMT(ma, str, result) \ va_list args1; \ va_start(args1, str); \ diff --git a/src/core/core_type_info.c b/src/core/core_type_info.c index d0c59da..810b394 100644 --- a/src/core/core_type_info.c +++ b/src/core/core_type_info.c @@ -1,4 +1,4 @@ -fn s8_t ti_enum_value_to_name(type_t *type, i64 value) { +fn s8_t ti_enum_value_to_name(i64 value, type_t *type) { assert(type->kind == type_kind_enum); for (i32 i = 0; i < type->count; i += 1) { type_member_t *it = type->members + i; @@ -9,7 +9,7 @@ fn s8_t ti_enum_value_to_name(type_t *type, i64 value) { return s8_lit("invalid"); } -fn i64 ti_enum_name_to_value(type_t *type, s8_t name) { +fn i64 ti_enum_name_to_value(s8_t name, type_t *type) { assert(type->kind == type_kind_enum); for (i32 i = 0; i < type->count; i += 1) { type_member_t *it = type->members + i; @@ -20,7 +20,7 @@ fn i64 ti_enum_name_to_value(type_t *type, s8_t name) { return -1; } -fn type_member_t *ti_get_member(type_t *type, s8_t name) { +fn type_member_t *ti_get_member(s8_t name, type_t *type) { for (i32 i = 0; i < type->count; i += 1) { type_member_t *it = type->members + i; if (s8_equal(it->name, name)) { @@ -149,9 +149,9 @@ fn void ti__serial_data_ex(sb8_t *sb, void *p, type_t *type) { } else if (type->size == 8) { value = *(i64 *)p; } else { - panicf("invalid size of enum: %d", type->size); + fatalf("invalid size of enum: %d", type->size); } - s8_t s = ti_enum_value_to_name(type, value); + s8_t s = ti_enum_value_to_name(value, type); sb8_append(sb, s); return; } @@ -191,7 +191,7 @@ fn void ti__serial_data_ex(sb8_t *sb, void *p, type_t *type) { return; } - panicf("can't serialize: unhandled type"); + fatalf("can't serialize: unhandled type"); } fn s8_t ti__serial_data(ma_arena_t *arena, void *p, type_t *type) { @@ -321,9 +321,9 @@ fn void ti__deserial_data_ex(ma_arena_t *arena, parser_t *par, void *p, type_t * if (type->kind == type_kind_enum) { lex_t *token = parser_expect(par, lex_kind_ident); - i64 value = ti_enum_name_to_value(type, token->string); + i64 value = ti_enum_name_to_value(token->string, type); if (value == -1) { - panicf("invalid enum value: %S", token->string); + fatalf("invalid enum value: %S", token->string); } if (type->size == 1) { *(i8 *)p = (i8)value; @@ -334,7 +334,7 @@ fn void ti__deserial_data_ex(ma_arena_t *arena, parser_t *par, void *p, type_t * } else if (type->size == 8) { *(i64 *)p = (i64)value; } else { - panicf("invalid size of enum: %d", type->size); + fatalf("invalid size of enum: %d", type->size); } return; } @@ -394,7 +394,7 @@ fn void ti__deserial_data_ex(ma_arena_t *arena, parser_t *par, void *p, type_t * fn void *ti__deserial_data(ma_arena_t *arena, s8_t data, type_t *type) { void *p = ma_push_size(arena, type->size); ma_temp_t scratch = ma_begin_scratch(); - lex_array_t tokens = lex_tokens(scratch.arena, "data serializing", data.str); + lex_array_t tokens = lex_tokens(scratch.arena, "data serializing", data); parser_t *par = parser_make(scratch.arena, tokens.data); ti__deserial_data_ex(arena, par, p, type); ma_end_scratch(scratch); diff --git a/src/core/core_type_info.h b/src/core/core_type_info.h index 12dbe86..00dfb92 100644 --- a/src/core/core_type_info.h +++ b/src/core/core_type_info.h @@ -58,13 +58,13 @@ fn s8_t ti__serial_data(ma_arena_t *arena, void *p, type_t *type); // // utilities -fn s8_t ti_enum_value_to_name(type_t *type, i64 value); -fn i64 ti_enum_name_to_value(type_t *type, s8_t name); -fn type_member_t *ti_get_member(type_t *type, s8_t name); +fn s8_t ti_enum_value_to_name(i64 value, type_t *type); +fn i64 ti_enum_name_to_value(s8_t name, type_t *type); +fn type_member_t *ti_get_member(s8_t name, type_t *type); // // core type info data -#define type(X) &type__##X +#define type(X) (&type__##X) #define DEFINE_ENUM(x) type_t type__##x = {type_kind_enum, s8_const_lit(#x), sizeof(x), .members = members__##x, .count = lengthof(members__##x)} #define DEFINE_STRUCT(x) type_t type__##x = {type_kind_struct, s8_const_lit(#x), sizeof(x), .members = members__##x, .count = lengthof(members__##x)} #define POINTER(x) (type_t){type_kind_pointer, s8_const_lit(#x "*"), sizeof(void *), .base = &type__##x} @@ -337,3 +337,12 @@ glb type_member_t members__lex_suffix_t[] = { #undef X }; DEFINE_ENUM(lex_suffix_t); + +glb type_member_t members__log_level_t[] = { + {.name = s8_const_lit("log_level_debug"), .value = log_level_debug}, + {.name = s8_const_lit("log_level_info"), .value = log_level_info}, + {.name = s8_const_lit("log_level_warning"), .value = log_level_warning}, + {.name = s8_const_lit("log_level_error"), .value = log_level_error}, + {.name = s8_const_lit("log_level_fatal"), .value = log_level_fatal}, +}; +DEFINE_ENUM(log_level_t); \ No newline at end of file diff --git a/src/core_test/core_test_entry.c b/src/core_test/core_test_entry.c index 4be3ab0..6c52132 100644 --- a/src/core_test/core_test_entry.c +++ b/src/core_test/core_test_entry.c @@ -83,7 +83,7 @@ void test_s8(void) { } { - s8_t s = s8_fmt(arena, "%d%Sv%s", 32, s8_lit("|"), ">"); + s8_t s = s8_printf(arena, "%d%Sv%s", 32, s8_lit("|"), ">"); assert(s8_equal(s, s8_lit("32|v>"))); } @@ -108,7 +108,6 @@ int main(int argc, char **argv) { printf("PLATFORM_GCC = %d\n", PLATFORM_GCC); printf("PLATFORM_CL = %d\n", PLATFORM_CL); printf("PLATFORM_TCC = %d\n", PLATFORM_TCC); - printf("PLATFORM_ASSERT = %d\n", PLATFORM_ASSERT); test_s8(); diff --git a/src/meta/parser.c b/src/meta/parser.c index 737e444..595338c 100644 --- a/src/meta/parser.c +++ b/src/meta/parser.c @@ -84,7 +84,7 @@ ast_t *parse_lit_expr(parser_t *par) { parser_expect(par, lex_kind_close_paren); return result; } else { - lex_panicf(token, "got invalid token of kind: %S while parsing expression", lex_kind_to_s8(token->kind)); + parser_panicf(token, "got invalid token of kind: %S while parsing expression", lex_kind_to_s8(token->kind)); return 0; } } @@ -130,7 +130,7 @@ ast_t *parse_expr(parser_t *par) { return expr; } -ast_t *parse_expr_str(ma_arena_t *arena, char *file_name, char *stream) { +ast_t *parse_expr_str(ma_arena_t *arena, char *file_name, s8_t stream) { lex_array_t tokens = lex_tokens(arena, file_name, stream); parser_t *par = parser_make(arena, tokens.data); ast_t *result = parse_expr(par); @@ -153,18 +153,18 @@ i64 eval_const_expr(ast_t *expr) { case lex_kind_modulo: return left % right; case lex_kind_and: return left && right; case lex_kind_or: return left || right; - default: lex_panicf(expr->pos, "unhandled binary operator: %S", lex_kind_to_s8(expr->integer)); + default: parser_panicf(expr->pos, "unhandled binary operator: %S", lex_kind_to_s8(expr->integer)); } } else { ma_temp_t scratch = ma_begin_scratch(); - lex_panicf(expr->pos, "unhandled ast in const expression evaluation: %S", s8_serial_ast_flag_t(scratch.arena, expr->flags)); + parser_panicf(expr->pos, "unhandled ast in const expression evaluation: %S", s8_serial_ast_flag_t(scratch.arena, expr->flags)); ma_end_scratch(scratch); } return 0; } #define test_expr(x) do {\ - lex_array_t tokens = lex_tokens(scratch.arena, "parser_test", #x);\ + lex_array_t tokens = lex_tokens(scratch.arena, "parser_test", s8_lit(#x));\ parser_t *par = parser_make(scratch.arena, tokens.data);\ ast_t *expr = parse_expr(par);\ assert(expr != NULL);\ @@ -194,7 +194,7 @@ ast_t *parse_struct_mem(parser_t *par, s8_t *name) { while (parser_match(par, lex_kind_multiply)) { ast_t *pointer = create_ast(par, par->at, set_bit(ast_flag_type_pointer) | set_bit(ast_flag_string)); ast_append(pointer, type); - pointer->string = s8_fmt(par->arena, "%S*", type->string); + pointer->string = s8_printf(par->arena, "%S*", type->string); type = pointer; } @@ -207,9 +207,9 @@ ast_t *parse_struct_mem(parser_t *par, s8_t *name) { if (num) { array->flags |= set_bit(ast_flag_integer); array->integer = (int)num->integer; - array->string = s8_fmt(par->arena, "%S[%d]", type->string, (int)array->integer); + array->string = s8_printf(par->arena, "%S[%d]", type->string, (int)array->integer); } else { - array->string = s8_fmt(par->arena, "%S[]", type->string); + array->string = s8_printf(par->arena, "%S[]", type->string); } parser_expect(par, lex_kind_close_bracket); type = array; @@ -218,7 +218,7 @@ ast_t *parse_struct_mem(parser_t *par, s8_t *name) { return type; } -ast_t *parse_decls(ma_arena_t *arena, char *file, char *code) { +ast_t *parse_decls(ma_arena_t *arena, char *file, s8_t code) { lex_array_t tokens = lex_tokens(arena, file, code); parser_t *par = parser_make(arena, tokens.data); ast_t *result = create_ast(par, par->at, set_bit(ast_flag_string)); @@ -271,7 +271,7 @@ ast_t *parse_decls(ma_arena_t *arena, char *file, char *code) { return result; } -ast_t *parse_table(ma_arena_t *arena, char *file, char *code) { +ast_t *parse_table(ma_arena_t *arena, char *file, s8_t code) { lex_array_t tokens = lex_tokens(arena, file, code); parser_t *par = parser_make(arena, tokens.data); ast_t *table = create_ast(par, par->at, 0); @@ -299,7 +299,7 @@ ast_t *parse_table(ma_arena_t *arena, char *file, char *code) { } else if (parser_match(par, lex_kind_bit_or) || parser_match(par, lex_kind_eof)) { break; } else { - lex_panicf(par->at, "invalid token: %S", lex_kind_to_s8(par->at->kind)); + parser_panicf(par->at, "invalid token: %S", lex_kind_to_s8(par->at->kind)); } } } diff --git a/src/meta/serialize.c b/src/meta/serialize.c index aa93461..50db61e 100644 --- a/src/meta/serialize.c +++ b/src/meta/serialize.c @@ -3,12 +3,12 @@ s8_t s8_ast_to_cvar(ma_arena_t *arena, ast_t *ast, s8_t *name) { return ast->string; } else if (ast->flags & set_bit(ast_flag_type_pointer)) { s8_t base = s8_ast_to_cvar(arena, ast->first, name); - return s8_fmt(arena, "%S*", base); + return s8_printf(arena, "%S*", base); } else if (ast->flags & set_bit(ast_flag_type_array)) { if (ast->flags & set_bit(ast_flag_integer)) { - *name = s8_fmt(arena, "%S[%d]", *name, ast->integer); + *name = s8_printf(arena, "%S[%d]", *name, ast->integer); } else { - *name = s8_fmt(arena, "%S[%d]", *name, ast->integer); + *name = s8_printf(arena, "%S[%d]", *name, ast->integer); } s8_t base = s8_ast_to_cvar(arena, ast->first, name); @@ -86,15 +86,15 @@ s8_t s8_serial_ast_to_code(ma_arena_t *arena, ast_t *n) { s8_t s8_serial_ast_type_to_type_info(ma_arena_t *arena, ast_t *n) { if (n->flags & set_bit(ast_flag_type_name)) { - return s8_fmt(arena, "type__%S", n->string); + return s8_printf(arena, "type__%S", n->string); } else if (n->flags & set_bit(ast_flag_type_pointer)) { s8_t base = s8_serial_ast_type_to_type_info(arena, n->first); - return s8_fmt(arena, "(type_t){type_kind_pointer, s8_const_lit(\"%S\"), sizeof(void *), .base = &%S}", n->string, base); + return s8_printf(arena, "(type_t){type_kind_pointer, s8_const_lit(\"%S\"), sizeof(void *), .base = &%S}", n->string, base); } else if (n->flags & set_bit(ast_flag_type_array)) { s8_t base = s8_serial_ast_type_to_type_info(arena, n->first); - return s8_fmt(arena, "(type_t){type_kind_array, s8_const_lit(\"%S\"), sizeof(%S), %d, .base = &%S}", n->string, n->string, (int)n->integer, base); + return s8_printf(arena, "(type_t){type_kind_array, s8_const_lit(\"%S\"), sizeof(%S), %d, .base = &%S}", n->string, n->string, (int)n->integer, base); } else { - lex_panicf(n->pos, "expected type"); + parser_panicf(n->pos, "expected type"); } return (s8_t){0}; } @@ -182,7 +182,7 @@ void sb8_serial_table_enum(sb8_t *c, sb8_t *h, ast_t *table, s8_t decl) { int name_idx = row_findi(table->first, "name"); int value_idx = row_findi(table->first, "value"); - s8_t name_t = s8_fmt(c->arena, "%S_t", decl); + s8_t name_t = s8_printf(c->arena, "%S_t", decl); sb8_printf(h, "typedef enum {\n"); for (ast_t *row = table->first->next; row; row = row->next) { @@ -219,6 +219,6 @@ void sb8_serial_table_enum(sb8_t *c, sb8_t *h, ast_t *table, s8_t decl) { #define gen_h(arena) _gen_filename(arena, s8_lit(__FILE__), s8_lit("h")) s8_t _gen_filename(ma_arena_t *arena, s8_t lit_file, s8_t ext) { s8_t file_noext = s8_chop_last_period(s8_chop_last_period(lit_file)); - s8_t file = s8_fmt(arena, "%S.gen.%S", file_noext, ext); + s8_t file = s8_printf(arena, "%S.gen.%S", file_noext, ext); return file; } \ No newline at end of file