diff --git a/attempt_1/main.c b/attempt_1/main.c index c6bac6a..86cd567 100644 --- a/attempt_1/main.c +++ b/attempt_1/main.c @@ -64,6 +64,20 @@ global U8 vm_rax = 0; // Top global U8 vm_rdx = 0; // Next 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; + } +} + // Dictionary typedef struct { U4 val; @@ -144,6 +158,20 @@ internal void compile_action(U4 val) { } else if (val == ID2('R','E')) { // RET emit8(0xC3); 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 + 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 + return; } // Dictionary Resolver (Call User Word) @@ -162,6 +190,7 @@ internal void compile_action(U4 val) { 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] @@ -171,7 +200,9 @@ IA_ void compile_and_run_tape(void) { B4 in_def = false; U4 def_jmp_offset = 0; - for (U8 i = 0; i <= cursor_idx; i++) { + U8 end_idx = run_full ? (tape_arena.used / sizeof(U4)) : (cursor_idx + 1); + + for (U8 i = 0; i < end_idx; i++) { U4 tag = UNPACK_TAG(tape_ptr[i]); U4 val = UNPACK_VAL(tape_ptr[i]); @@ -235,6 +266,9 @@ IA_ void compile_and_run_tape(void) { #define MS_VK_BACK 0x08 #define MS_VK_TAB 0x09 #define MS_VK_SPACE 0x20 +#define MS_VK_F5 0x74 +#define MS_VK_PRIOR 0x21 +#define MS_VK_NEXT 0x22 // --- Window Procedure --- S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { @@ -303,6 +337,10 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { } } + if (wparam == MS_VK_PRIOR) { scroll_y_offset -= 100; if (scroll_y_offset < 0) scroll_y_offset = 0; } + if (wparam == MS_VK_NEXT) { scroll_y_offset += 100; } + if (wparam == MS_VK_F5) { run_full = !run_full; } + if (wparam == MS_VK_TAB) { // Cycle Color Tag U4 t = tape_ptr[cursor_idx]; @@ -334,7 +372,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { } } - // Interaction: Reset VM and compile up to cursor + // Interaction: Reset VM and compile vm_rax = 0; vm_rdx = 0; mem_zero(u8_(vm_globals), sizeof(vm_globals)); @@ -361,53 +399,81 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { x = start_x; y += spacing_y; } - if (i == cursor_idx) { + S4 render_y = y - scroll_y_offset; + + if (i == cursor_idx && render_y >= 30 && render_y < 500) { void* hBrush = ms_get_stock_object(2); // GRAY_BRUSH ms_select_object(hdc, hBrush); - ms_rectangle(hdc, x - 5, y - 2, x + 95, y + 22); + ms_rectangle(hdc, x - 5, render_y - 2, x + 95, render_y + 22); } - U4 t = tape_ptr[i]; - U4 tag = UNPACK_TAG(t); - U4 val = UNPACK_VAL(t); + if (render_y >= 30 && render_y < 500) { + U4 t = tape_ptr[i]; + U4 tag = UNPACK_TAG(t); + U4 val = UNPACK_VAL(t); - if (tag == tmpl(STag, Format) && val == 0xA) { - ms_set_text_color(hdc, 0x00444444); - ms_text_out_a(hdc, x, y, " \\n ", 6); + if (tag == tmpl(STag, Format) && val == 0xA) { + ms_set_text_color(hdc, 0x00444444); + ms_text_out_a(hdc, x, render_y, " \\n ", 6); + x = start_x; + y += spacing_y; + } else { + U4 color = tag_colors[tag]; + const char* prefix = tag_prefixes[tag]; + + ms_set_text_color(hdc, color); + + char val_str[9]; + if (tag == tmpl(STag, Data)) { + u64_to_hex(val, val_str, 6); + val_str[6] = '\0'; + } else { + // Decode 2-character dictionary 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'; + } + + char out_buf[10]; + out_buf[0] = prefix[0]; + out_buf[1] = ' '; + mem_copy(u8_(out_buf + 2), u8_(val_str), 6); + out_buf[8] = '\0'; + + ms_text_out_a(hdc, x, render_y, out_buf, 8); + x += spacing_x; + } + } else if (UNPACK_TAG(tape_ptr[i]) == tmpl(STag, Format) && UNPACK_VAL(tape_ptr[i]) == 0xA) { x = start_x; y += spacing_y; } else { - U4 color = tag_colors[tag]; - const char* prefix = tag_prefixes[tag]; - - ms_set_text_color(hdc, color); - - char val_str[9]; - if (tag == tmpl(STag, Data)) { - u64_to_hex(val, val_str, 6); - val_str[6] = '\0'; - } else { - // Decode 2-character dictionary 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'; - } - - char out_buf[10]; - out_buf[0] = prefix[0]; - out_buf[1] = ' '; - mem_copy(u8_(out_buf + 2), u8_(val_str), 6); - out_buf[8] = '\0'; - - ms_text_out_a(hdc, x, y, out_buf, 8); x += spacing_x; } } + // Draw a solid background behind the HUD to cover scrolling text + void* hBlackBrush = ms_get_stock_object(4); // BLACK_BRUSH + ms_select_object(hdc, hBlackBrush); + ms_rectangle(hdc, 0, 500, 1100, 750); + ms_rectangle(hdc, 0, 0, 1100, 40); + ms_set_text_color(hdc, 0x00AAAAAA); - ms_text_out_a(hdc, 40, 20, "x86-64 Machine Code Emitter | 2-Reg Stack + Global Tape | Factorial", 68); + 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); + u64_to_hex(code_arena.used, jit_str + 32, 3); + ms_text_out_a(hdc, 40, 520, jit_str, 41); + + 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, 0x0033FF33); + 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]); @@ -423,29 +489,27 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { semantics_str[13 + name_len] = '\0'; ms_set_text_color(hdc, cur_color); - ms_text_out_a(hdc, 40, 540, semantics_str, 13 + name_len); + ms_text_out_a(hdc, 40, 580, semantics_str, 13 + name_len); } - - // Render VM State - ms_set_text_color(hdc, 0x00FFFFFF); - char jit_str[32] = "JIT Size: 0x000 bytes"; - u64_to_hex(code_arena.used, jit_str + 12, 3); - ms_text_out_a(hdc, 40, 480, jit_str, 21); - - 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, 0x0033FF33); - ms_text_out_a(hdc, 40, 510, state_str, 29); ms_set_text_color(hdc, 0x00FFFFFF); - ms_text_out_a(hdc, 400, 480, "Global Memory (Contiguous Array):", 33); + ms_text_out_a(hdc, 400, 520, "Global Memory (Contiguous Array):", 33); for (int i=0; i<4; i++) { 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, 0x00FFFF33); - ms_text_out_a(hdc, 400, 510 + (i * 25), glob_str, 13); + ms_text_out_a(hdc, 400, 550 + (i * 25), glob_str, 13); + } + + // Print Log + ms_set_text_color(hdc, 0x00FFFFFF); + ms_text_out_a(hdc, 750, 520, "Print Log:", 10); + for (int i=0; i