From fd132c6efc7c35f4364833fe326536d74f29c6b2 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 20 Feb 2026 22:10:29 -0500 Subject: [PATCH] progress --- GEMINI.md | 1 + attempt_1/attempt_1.md | 7 +- attempt_1/main.c | 376 +++++++++++----------- references/Architectural_Consolidation.md | 3 +- 4 files changed, 201 insertions(+), 186 deletions(-) diff --git a/GEMINI.md b/GEMINI.md index 9e2265a..b06ab54 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -6,6 +6,7 @@ DO NOT EVER make a shell script unless told to. DO NOT EVER make a readme or a f The user will often screenshot various aspects of the development with ShareX, which will be available in the current months directory: 'C:\Users\Ed\scoop\apps\sharex\current\ShareX\Screenshots\2026-02' You may read fromt his and the user will let you know (by last modified) which of the last screenshots are the most relevant. Otherwise they manually paste relevant content in the './gallery' directory. Do not use the .gitignore as a reference for WHAT YOU SHOULD IGNORE. THAT IS STRICT FOR THE GIT REPO, NOT FOR INFERENCING FILE RELEVANCE. +If a task is very heavy, use sub-agents (such as a codebase/docs/references investiagor, code editor, specifc pattern or nuance analyzer, etc). ## Coding Conventions diff --git a/attempt_1/attempt_1.md b/attempt_1/attempt_1.md index 9673646..c82d3c8 100644 --- a/attempt_1/attempt_1.md +++ b/attempt_1/attempt_1.md @@ -36,8 +36,11 @@ The application presents a visual grid of 32-bit tokens and allows the user to n ## What's Missing (TODO) * **Saving/Loading:** The tape and annotation arenas are purely in-memory and are lost when the program closes. -* **Expanded Instruction Set:** The JIT only knows a handful of primitives (`SWAP`, `MULT`, `ADD`, `FETCH`, `STORE`, `DEC`, `RET_IF_ZERO`, `PRINT`). It has no support for floating point, stack manipulation for C FFI, or more complex branches. -* **Robust Dictionary:** The current dictionary is a simple array that is rebuilt on every compile. It doesn't handle collisions, scoping, or namespaces. +* **Expanded Instruction Set:** The JIT only knows a handful of primitives (`SWAP`, `MULT`, `ADD`, `FETCH`, `STORE`, `DEC`, `RET_IF_ZERO`, `PRINT`). It has no support for floating point or more complex branches. +* **The FFI Bridge:** The system needs a macro (like Onat's `CCALL`) to align the `RSP` stack to 16 bytes and map the 2-register data stack/globals into the Windows C-ABI (`RCX`, `RDX`, `R8`, `R9`) to call WinAPI safely from the JIT. +* **Implicit Definition Boundaries (Magenta Pipe):** Definitions should not need explicit `begin`/`end`. A definition token should implicitly cause the JIT to emit a `RET` to close the prior block, and an `xchg rax, rdx` to rotate the stack for the new block. +* **x68 Instruction Padding:** The JIT currently emits variable-length instructions (`emit8`). It needs to pad every logical block/instruction to exact 32-bit multiples using ignored prefixes or NOPs to perfectly align with the visual token grid. +* **O(1) Dictionary & Visual Linking:** The current dictionary is a simple string-matched array rebuilt on compile. It needs to transition to a true "visual linker" where visual tokens store the absolute source memory indices, resolving locations instantly at edit-time. * **Annotation Editing:** Typing into an annotation just appends characters. A proper text-editing cursor within the token is needed. ## References Utilized diff --git a/attempt_1/main.c b/attempt_1/main.c index 7b7e6d7..9351d6e 100644 --- a/attempt_1/main.c +++ b/attempt_1/main.c @@ -1,16 +1,13 @@ #include "duffle.amd64.win32.h" // --- Semantic Tags (Using X-Macros & Enum_) --- -// Colors translated from Cozy-and-WIndy: -// 0x00bbggrr Win32 format - #define Tag_Entries() \ - X(Define, "Define", 0x0018AEFF, ":") /* Orange-ish (Language.Type) */ \ - X(Call, "Call", 0x00D6A454, "~") /* Soft Blue (Language.Class) */ \ - X(Data, "Data", 0x0094BAA1, "$") /* Muted Green (Language.Number) */ \ - X(Imm, "Imm", 0x004AA4C2, "^") /* Sand/Yellow (Language.Keyword) */ \ - X(Comment, "Comment", 0x00AAAAAA, ".") /* Grey (Language.Comment) */ \ - X(Format, "Format", 0x003A2F3B, " ") /* Current Line BG for invisibles */ + X(Define, "Define", 0x0018AEFF, ":") \ + X(Call, "Call", 0x00D6A454, "~") \ + X(Data, "Data", 0x0094BAA1, "$") \ + X(Imm, "Imm", 0x004AA4C2, "^") \ + X(Comment, "Comment", 0x00AAAAAA, ".") \ + X(Format, "Format", 0x003A2F3B, " ") typedef Enum_(U4, STag) { #define X(n, s, c, p) tmpl(STag, n), @@ -34,55 +31,61 @@ global const char* tag_names[] = { #undef X }; -// Token Packing: 28 bits payload | 4 bits tag #define pack_token(tag, val) ((u4_(tag) << 28) | (u4_(val) & 0x0FFFFFFF)) #define unpack_tag(token) ( ((token) >> 28) & 0x0F) #define unpack_val(token) ( (token) & 0x0FFFFFFF) -// 2-Character Mapped Dictionary Helper -#define id2(a, b) ((u4_(a) << 8) | u4_(b)) - #define TOKENS_PER_ROW 8 #define MODE_NAV 0 #define MODE_EDIT 1 -// The Tape Drive (Using FArena from duffle) global FArena tape_arena; global FArena anno_arena; global U8 cursor_idx = 0; global U4 editor_mode = MODE_NAV; global U4 mode_switch_now = false; -// Executable Code Arena (The JIT) global FArena code_arena; -// VM State: 2-Reg Stack + Global Memory -global U8 vm_rax = 0; // Top -global U8 vm_rdx = 0; // Next +global U8 vm_rax = 0; +global U8 vm_rdx = 0; global U8 vm_globals[16] = {0}; -// Execution Mode & Logging global B4 run_full = false; global U8 log_buffer[16] = {0}; global U4 log_count = 0; - -// UI State global S4 scroll_y_offset = 0; void ms_builtin_print(U8 val) { - if (log_count < 16) { - log_buffer[log_count++] = val; - } + if (log_count < 16) log_buffer[log_count++] = val; } -// Dictionary -typedef struct { - U4 val; - U4 offset; -} DictEntry; -global DictEntry dict[256]; -global U8 dict_count = 0; +// Visual Linker & O(1) Dictionary +global U4 tape_to_code_offset[65536] = {0}; + +#define PRIM_SWAP 1 +#define PRIM_MULT 2 +#define PRIM_ADD 3 +#define PRIM_FETCH 4 +#define PRIM_DEC 5 +#define PRIM_STORE 6 +#define PRIM_RET_Z 7 +#define PRIM_RET 8 +#define PRIM_PRINT 9 + +global const char* prim_names[] = { + "", + "SWAP ", + "MULT ", + "ADD ", + "FETCH ", + "DEC ", + "STORE ", + "RET_IF_Z", + "RETURN ", + "PRINT " +}; IA_ void scatter(U4 token, const char* anno_str) { if (tape_arena.used + sizeof(U4) <= tape_arena.capacity && anno_arena.used + sizeof(U8) <= anno_arena.capacity) { @@ -93,96 +96,138 @@ IA_ void scatter(U4 token, const char* anno_str) { aptr[0] = 0; if (anno_str) { char* dest = (char*)aptr; - int i = 0; while(i < 8 && anno_str[i]) { - dest[i] = anno_str[i]; - i ++; - } + int i = 0; while(i < 8 && anno_str[i]) { dest[i] = anno_str[i]; i ++; } } anno_arena.used += sizeof(U8); } } -// --- Minimal x86-64 Emitter --- internal void emit8(U1 b) { if (code_arena.used + 1 <= code_arena.capacity) { - U1*r ptr = u1_r(code_arena.start + code_arena.used); - ptr[0] = b; + u1_r(code_arena.start + code_arena.used)[0] = b; code_arena.used += 1; } } internal void emit32(U4 val) { if (code_arena.used + 4 <= code_arena.capacity) { - U4*r ptr = u4_r(code_arena.start + code_arena.used); - ptr[0] = val; + u4_r(code_arena.start + code_arena.used)[0] = val; code_arena.used += 4; } } +internal void pad32(void) { + while ((code_arena.used % 4) != 0) emit8(0x90); +} + +internal void relink_tape(void) { + U8 tape_count = tape_arena.used / sizeof(U4); + U4*r tape_ptr = u4_r(tape_arena.start); + U8*r anno_ptr = u8_r(anno_arena.start); + + for (U8 i = 0; i < tape_count; i++) { + U4 t = tape_ptr[i]; + U4 tag = unpack_tag(t); + if (tag == STag_Call || tag == STag_Imm) { + char* ref_name = (char*)&anno_ptr[i]; + + U4 new_val = 0; + for (int p = 1; p <= 9; p++) { + int match = 1; + for (int c = 0; c < 8; c++) { + char c1 = ref_name[c] ? ref_name[c] : ' '; + char c2 = prim_names[p][c] ? prim_names[p][c] : ' '; + if (c1 != c2) { match = 0; break; } + } + if (match) { new_val = p; break; } + } + + if (new_val == 0) { + for (U8 j = 0; j < tape_count; j++) { + if (unpack_tag(tape_ptr[j]) == STag_Define) { + char* def_name = (char*)&anno_ptr[j]; + int match = 1; + for (int c = 0; c < 8; c++) { + char c1 = ref_name[c] ? ref_name[c] : ' '; + char c2 = def_name[c] ? def_name[c] : ' '; + if (c1 != c2) { match = 0; break; } + } + if (match) { new_val = j; break; } + } + } + } + tape_ptr[i] = pack_token(tag, new_val); + } + } +} + internal void compile_action(U4 val) { - if (val == id2('S','W')) { // SWAP: xchg rax, rdx + if (val == PRIM_SWAP) { emit8(0x48); emit8(0x87); emit8(0xC2); + pad32(); return; - } else if (val == id2('M','*')) { // MULT: imul rax, rdx + } else if (val == PRIM_MULT) { emit8(0x48); emit8(0x0F); emit8(0xAF); emit8(0xC2); + pad32(); return; - } else if (val == id2('+',' ')) { // ADD: add rax, rdx + } else if (val == PRIM_ADD) { emit8(0x48); emit8(0x01); emit8(0xD0); + pad32(); return; - } else if (val == id2('@',' ')) { // FETCH: mov rax, QWORD PTR [rcx + rax*8] + } else if (val == PRIM_FETCH) { emit8(0x48); emit8(0x8B); emit8(0x04); emit8(0xC1); + pad32(); return; - } else if (val == id2('-','1')) { // DEC: dec rax + } else if (val == PRIM_DEC) { emit8(0x48); emit8(0xFF); emit8(0xC8); + pad32(); return; - } else if (val == id2('!',' ')) { // STORE: mov QWORD PTR [rcx + rax*8], rdx + } else if (val == PRIM_STORE) { emit8(0x48); emit8(0x89); emit8(0x14); emit8(0xC1); + pad32(); return; - } else if (val == id2('R','0')) { // RET_IF_ZERO: test rax, rax; jnz +1; ret - emit8(0x48); emit8(0x85); emit8(0xC0); // test rax, rax - emit8(0x75); emit8(0x01); // jnz skip_ret (+1 byte) - emit8(0xC3); // ret + } else if (val == PRIM_RET_Z) { + emit8(0x48); emit8(0x85); emit8(0xC0); + emit8(0x75); emit8(0x01); + emit8(0xC3); + pad32(); return; - } else if (val == id2('R','E')) { // RET + } else if (val == PRIM_RET) { emit8(0xC3); + pad32(); return; - } else if (val == id2('P','R')) { // PRINT: call ms_builtin_print - emit8(0x51); // push rcx - emit8(0x52); // push rdx - emit8(0x48); emit8(0x83); emit8(0xEC); emit8(0x20); // sub rsp, 32 - emit8(0x48); emit8(0x89); emit8(0xC1); // mov rcx, rax - emit8(0x49); emit8(0xB8); // mov r8, imm64 + } else if (val == PRIM_PRINT) { + emit8(0x51); emit8(0x52); + emit8(0x48); emit8(0x83); emit8(0xEC); emit8(0x20); + emit8(0x48); emit8(0x89); emit8(0xC1); + emit8(0x49); emit8(0xB8); U8 addr = u8_(& ms_builtin_print); emit32(u4_(addr & 0xFFFFFFFF)); emit32(u4_(addr >> 32)); - emit8(0x41); emit8(0xFF); emit8(0xD0); // call r8 - emit8(0x48); emit8(0x83); emit8(0xC4); emit8(0x20); // add rsp, 32 - emit8(0x5A); // pop rdx - emit8(0x59); // pop rcx + emit8(0x41); emit8(0xFF); emit8(0xD0); + emit8(0x48); emit8(0x83); emit8(0xC4); emit8(0x20); + emit8(0x5A); emit8(0x59); + pad32(); return; } - // Dictionary Resolver (Call User Word) - for (U8 entry = 0; entry < dict_count; entry++) { - if (dict[entry].val == val) { - U4 target = dict[entry].offset; - U4 current = code_arena.used; - S4 rel32 = s4_(target) - s4_(current + 5); - emit8(0xE8); // CALL rel32 - emit32(u4_(rel32)); - return; - } + + if (val > 0) { + U4 target = tape_to_code_offset[val]; + pad32(); + S4 rel32 = s4_(target) - s4_(code_arena.used + 5); + emit8(0xE8); + emit32(u4_(rel32)); + pad32(); } } IA_ void compile_and_run_tape(void) { farena_reset(& code_arena); - dict_count = 0; log_count = 0; - // Prologue: Load VM state from globals[14] and [15] - emit8(0x48); emit8(0x8B); emit8(0x41); emit8(0x70); // mov rax, [rcx+112] - emit8(0x48); emit8(0x8B); emit8(0x51); emit8(0x78); // mov rdx, [rcx+120] + emit8(0x48); emit8(0x8B); emit8(0x41); emit8(0x70); + emit8(0x48); emit8(0x8B); emit8(0x51); emit8(0x78); U4*r tape_ptr = u4_r(tape_arena.start); B4 in_def = false; @@ -195,35 +240,36 @@ IA_ void compile_and_run_tape(void) if (tag == STag_Define) { if (in_def == false) { - emit8(0xE9); // JMP rel32 (Skip over definition body) + pad32(); + emit8(0xE9); def_jmp_offset = code_arena.used; emit32(0); + pad32(); in_def = true; + } else { + emit8(0xC3); + pad32(); } - if (dict_count < 256) { - dict[dict_count].val = val; - dict[dict_count].offset = code_arena.used; - dict_count++; - } + + tape_to_code_offset[i] = code_arena.used; + + emit8(0x48); emit8(0x87); emit8(0xC2); + pad32(); } else if (tag == STag_Call) { compile_action(val); - if (val == id2('R','E') && in_def) { - // End of definition block, patch the jump - U4 current = code_arena.used; - u4_r(code_arena.start + def_jmp_offset)[0] = current - (def_jmp_offset + 4); - in_def = false; - } } else if (tag == STag_Data) { - emit8(0x48); emit8(0x89); emit8(0xC2); // mov rdx, rax - emit8(0x48); emit8(0xC7); emit8(0xC0); emit32(val); // mov rax, imm32 + emit8(0x48); emit8(0x89); emit8(0xC2); + emit8(0x48); emit8(0xC7); emit8(0xC0); emit32(val); + pad32(); } else if (tag == STag_Imm) { if (in_def) { - // If we execute something, we jump out of def block first + emit8(0xC3); + pad32(); U4 current = code_arena.used; u4_r(code_arena.start + def_jmp_offset)[0] = current - (def_jmp_offset + 4); in_def = false; @@ -233,27 +279,24 @@ IA_ void compile_and_run_tape(void) } if (in_def) { - // If we hit cursor inside a definition, patch jump so it doesn't crash on execution + emit8(0xC3); + pad32(); U4 current = code_arena.used; u4_r(code_arena.start + def_jmp_offset)[0] = current - (def_jmp_offset + 4); } - // Epilogue: Save VM state back to globals - emit8(0x48); emit8(0x89); emit8(0x41); emit8(0x70); // mov [rcx+112], rax - emit8(0x48); emit8(0x89); emit8(0x51); emit8(0x78); // mov [rcx+120], rdx - emit8(0xC3); // ret + emit8(0x48); emit8(0x89); emit8(0x41); emit8(0x70); + emit8(0x48); emit8(0x89); emit8(0x51); emit8(0x78); + emit8(0xC3); - // Cast code arena to function pointer and CALL it! typedef void JIT_Func(U8* globals_ptr); JIT_Func* func = (JIT_Func*)code_arena.start; func(vm_globals); - // Read state for UI vm_rax = vm_globals[14]; vm_rdx = vm_globals[15]; } -// --- Window Procedure --- S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { U8 tape_count = tape_arena.used / sizeof(U4); @@ -267,12 +310,10 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) U4 val = unpack_val(t); U1 c = u1_(wparam); - // Skip control characters and the 'E' that triggered the mode bool should_skip = c < 32 || (c == 'e' && mode_switch_now); if (should_skip) { mode_switch_now = false; return 0; } if (tag == STag_Data) { - // Hex input U4 digit = 16; if (c >= '0' && c <= '9') digit = c - '0'; if (c >= 'a' && c <= 'f') digit = c - 'a' + 10; @@ -290,28 +331,22 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) if (len < 8) { anno_str[len] = (char)c; for (int i = len + 1; i < 8; i++) anno_str[i] = '\0'; - // Update the 2-char token ID from the first 2 chars - char c1 = anno_str[0] ? anno_str[0] : ' '; - char c2 = anno_str[1] ? anno_str[1] : ' '; - val = id2(c1, c2); - tape_ptr[cursor_idx] = pack_token(tag, val); } } vm_rax = 0; vm_rdx = 0; mem_zero(u8_(vm_globals), sizeof(vm_globals)); + relink_tape(); compile_and_run_tape(); ms_invalidate_rect(hwnd, nullptr, true); return 0; } case MS_WM_KEYDOWN: { - if (wparam == 0x45 && editor_mode == MODE_NAV) { // 'E' + if (wparam == 0x45 && editor_mode == MODE_NAV) { editor_mode = MODE_EDIT; mode_switch_now = true; ms_invalidate_rect(hwnd, nullptr, true); return 0; - // ~~Consume the keypress so it doesn't trigger WM_CHAR~~ - // NOTE(Ed): Still triggers WM_CHAR we need to track when we just entered edit mode and that must be consumed. } - if (wparam == 0x1B && editor_mode == MODE_EDIT) { // ESC + if (wparam == 0x1B && editor_mode == MODE_EDIT) { editor_mode = MODE_NAV; ms_invalidate_rect(hwnd, nullptr, true); return 0; @@ -332,16 +367,14 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) while (len < 8 && anno_str[len] != '\0' && anno_str[len] != ' ') len ++; if (len > 0) { anno_str[len - 1] = '\0'; - char c1 = anno_str[0] ? anno_str[0] : ' '; - char c2 = anno_str[1] ? anno_str[1] : ' '; - tape_ptr[cursor_idx] = pack_token(tag, id2(c1, c2)); } } vm_rax = 0; vm_rdx = 0; mem_zero(u8_(vm_globals), sizeof(vm_globals)); + relink_tape(); compile_and_run_tape(); ms_invalidate_rect(hwnd, nullptr, true); } - return 0; // Block navigation keys in Edit Mode + return 0; } if (wparam == MS_VK_RIGHT && cursor_idx < tape_count - 1) cursor_idx ++; @@ -365,7 +398,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) U8 next_line_start = cursor_idx; while (next_line_start < tape_count && unpack_tag(tape_ptr[next_line_start]) != STag_Format) next_line_start ++; if (next_line_start < tape_count) { - next_line_start ++; // Skip the newline + next_line_start ++; U8 next_line_end = next_line_start; while (next_line_end < tape_count && unpack_tag(tape_ptr[next_line_end]) != STag_Format) next_line_end ++; U8 next_line_len = next_line_end - next_line_start; @@ -378,15 +411,12 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) if (wparam == MS_VK_F5) { run_full = !run_full; } if (wparam == MS_VK_TAB) { - // Cycle Color Tag U4 t = tape_ptr[cursor_idx]; U4 tag = (unpack_tag(t) + 1) % STag_Count; tape_ptr[cursor_idx] = pack_token(tag, unpack_val(t)); } else if (wparam == MS_VK_BACK) { - // Delete Token - // Shift: delete AT cursor | Regular: delete TO THE LEFT U8 delete_idx = cursor_idx; B4 is_shift = (ms_get_async_key_state(MS_VK_SHIFT) & 0x8000) != 0; if (is_shift == false) { @@ -407,8 +437,6 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) } } else if (wparam == MS_VK_SPACE || wparam == MS_VK_RETURN) { - // Insert New Token - // Shift: insert AFTER cursor | Regular: insert BEFORE cursor B4 is_shift = (ms_get_async_key_state(MS_VK_SHIFT) & 0x8000) != 0; U8 insert_idx = cursor_idx; if (is_shift) insert_idx ++; @@ -423,7 +451,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) tape_ptr[insert_idx] = pack_token(STag_Format, 0xA); anno_ptr[insert_idx] = 0; } else { - tape_ptr[insert_idx] = pack_token(STag_Comment, id2(' ',' ')); + tape_ptr[insert_idx] = pack_token(STag_Comment, 0); anno_ptr[insert_idx] = 0; } if (is_shift) cursor_idx ++; @@ -432,10 +460,10 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) } } - // Interaction: Reset VM and compile vm_rax = 0; vm_rdx = 0; mem_zero(u8_(vm_globals), sizeof(vm_globals)); + relink_tape(); compile_and_run_tape(); ms_invalidate_rect(hwnd, nullptr, true); @@ -447,7 +475,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) void* hFont = ms_create_font_a(20, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Consolas"); void* hOldFont = ms_select_object(hdc, hFont); - ms_set_bk_mode(hdc, 1); // TRANSPARENT text background + ms_set_bk_mode(hdc, 1); void* hBgBrush = ms_create_solid_brush(0x00222222); ms_select_object(hdc, hBgBrush); @@ -462,7 +490,6 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) U4*r tape_ptr = u4_r(tape_arena.start); U8*r anno_ptr = u8_r(anno_arena.start); - // Render Tokens for (U8 i = 0; i < tape_count; i++) { if (x >= start_x + (TOKENS_PER_ROW * spacing_x)) { @@ -492,7 +519,6 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) ms_set_text_color(hdc, color); if (editor_mode == MODE_EDIT && i == cursor_idx) { - // Better visibility in Edit Mode: White text on White-ish cursor ms_set_text_color(hdc, 0x001E1E1E); } @@ -503,19 +529,11 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) } else { - // Extract annotation string char* a_str = (char*) & anno; - if (a_str[0] == '\0') { - // Fallback to 2-character ID - val_str[0] = (char)((val >> 8) & 0xFF); - val_str[1] = (char)(val & 0xFF); - val_str[2] = ' '; val_str[3] = ' '; val_str[4] = ' '; val_str[5] = ' '; - val_str[6] = '\0'; - } - else { - mem_copy(u8_(val_str), u8_(a_str), 8); - val_str[8] = '\0'; + for(int c=0; c<8; c++) { + val_str[c] = a_str[c] ? a_str[c] : ' '; } + val_str[8] = '\0'; } char out_buf[12]; out_buf[0] = prefix[0]; @@ -536,7 +554,6 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) } } - // Draw a solid background behind the HUD to cover scrolling text void* hHudBrush = ms_create_solid_brush(0x00141E23); ms_select_object(hdc, hHudBrush); ms_rectangle(hdc, -1, 500, 3000, 3000); @@ -545,7 +562,6 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) ms_set_text_color(hdc, 0x00AAAAAA); ms_text_out_a(hdc, 40, 10, "x86-64 Machine Code Emitter | 2-Reg Stack | [F5] Toggle Run Mode | [PgUp/PgDn] Scroll", 85); - // Render VM State ms_set_text_color(hdc, 0x00FFFFFF); char jit_str[64] = "Mode: Incremental | JIT Size: 0x000 bytes"; if (run_full) mem_copy(u8_(jit_str + 6), u8_("Full "), 11); @@ -555,10 +571,9 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) char state_str[64] = "RAX: 00000000 | RDX: 00000000"; u64_to_hex(vm_rax, state_str + 5, 8); u64_to_hex(vm_rdx, state_str + 21, 8); - ms_set_text_color(hdc, 0x0094BAA1); // Number green + ms_set_text_color(hdc, 0x0094BAA1); ms_text_out_a(hdc, 40, 550, state_str, 29); - // HUD: Display Current Token Meaning if (tape_count > 0 && cursor_idx < tape_count) { U4 cur_tag = unpack_tag(tape_ptr[cursor_idx]); const char* tag_name = tag_names [cur_tag]; @@ -580,11 +595,10 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) char glob_str[32] = "[0]: 00000000"; glob_str[1] = '0' + i; u64_to_hex(vm_globals[i], glob_str + 5, 8); - ms_set_text_color(hdc, 0x00D6A454); // Soft blue + ms_set_text_color(hdc, 0x00D6A454); ms_text_out_a(hdc, 400, 550 + (i * 25), glob_str, 13); } - // Print Log ms_set_text_color(hdc, 0x00C8C8C8); ms_text_out_a(hdc, 750, 520, "Print Log:", 10); for (int i = 0; i