diff --git a/attempt_1/duffle.amd64.win32.h b/attempt_1/duffle.amd64.win32.h index 7416cfb..eeb0198 100644 --- a/attempt_1/duffle.amd64.win32.h +++ b/attempt_1/duffle.amd64.win32.h @@ -608,6 +608,10 @@ WinAPI void* ms_get_stock_object(S4 i) asm("GetStockObject"); WinAPI void* ms_create_font_a(S4 cHeight, S4 cWidth, S4 cEscapement, S4 cOrientation, S4 cWeight, U4 bItalic, U4 bUnderline, U4 bStrikeOut, U4 iCharSet, U4 iOutPrecision, U4 iClipPrecision, U4 iQuality, U4 iPitchAndFamily, char const* pszFaceName) asm("CreateFontA"); WinAPI void* ms_select_object(void* hdc, void* h) asm("SelectObject"); WinAPI S4 ms_rectangle(void* hdc, S4 left, S4 top, S4 right, S4 bottom) asm("Rectangle"); +WinAPI S4 ms_set_bk_mode(void* hdc, S4 mode) asm("SetBkMode"); +WinAPI void* ms_create_solid_brush(U4 color) asm("CreateSolidBrush"); +WinAPI S4 ms_delete_object(void* ho) asm("DeleteObject"); +WinAPI S2 ms_get_async_key_state(S4 vKey) asm("GetAsyncKeyState"); #define MS_MEM_COMMIT 0x00001000 #define MS_MEM_RESERVE 0x00002000 diff --git a/attempt_1/main.c b/attempt_1/main.c index 2d395e3..849a999 100644 --- a/attempt_1/main.c +++ b/attempt_1/main.c @@ -6,14 +6,16 @@ #include "duffle.amd64.win32.h" // --- Semantic Tags (Using X-Macros & Enum_) --- +// Colors translated from Cozy-and-WIndy: +// 0x00bbggrr Win32 format typedef Enum_(U4, STag) { #define Tag_Entries() \ - X(Define, "Define", 0x003333FF, ":") /* RED */ \ - X(Call, "Call", 0x0033FF33, "~") /* GREEN */ \ - X(Data, "Data", 0x00FFFF33, "$") /* CYAN */ \ - X(Imm, "Imm", 0x0033FFFF, "^") /* YELLOW */ \ - X(Comment, "Comment", 0x00888888, ".") /* DIM */ \ - X(Format, "Format", 0x00444444, " ") /* INVISIBLE/FORMAT */ + 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 */ #define X(n, s, c, p) tmpl(STag, n), Tag_Entries() @@ -287,6 +289,8 @@ IA_ void compile_and_run_tape(void) { #define MS_VK_PRIOR 0x21 #define MS_VK_NEXT 0x22 +#define MS_VK_SHIFT 0x10 + // --- Window Procedure --- S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { U8 tape_count = tape_arena.used / sizeof(U4); @@ -294,12 +298,14 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { switch (msg) { case MS_WM_CHAR: { + if (editor_mode != MODE_EDIT) return 0; + U4 t = tape_ptr[cursor_idx]; U4 tag = UNPACK_TAG(t); U4 val = UNPACK_VAL(t); U1 c = (U1)wparam; - // Skip control characters in WM_CHAR (handled in KEYDOWN) + // Skip control characters and the 'E' that triggered the mode if (c < 32) break; if (tag == STag_Data) { @@ -340,7 +346,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { if (wparam == 0x45 && editor_mode == MODE_NAV) { // 'E' editor_mode = MODE_EDIT; ms_invalidate_rect(hwnd, NULL, true); - return 0; + return 0; // Consume the keypress so it doesn't trigger WM_CHAR } if (wparam == 0x1B && editor_mode == MODE_EDIT) { // ESC editor_mode = MODE_NAV; @@ -415,34 +421,48 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { 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 and move cursor left, shifting BOTH arenas + // 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) { + if (cursor_idx > 0) { + delete_idx = cursor_idx - 1; + cursor_idx--; + } else return 0; + } + if (tape_count > 0) { U8*r anno_ptr = C_(U8*r, anno_arena.start); - for (U8 i = cursor_idx; i < tape_count - 1; i++) { + for (U8 i = delete_idx; i < tape_count - 1; i++) { tape_ptr[i] = tape_ptr[i+1]; anno_ptr[i] = anno_ptr[i+1]; } tape_arena.used -= sizeof(U4); anno_arena.used -= sizeof(U8); - if (cursor_idx > 0) cursor_idx--; } } else if (wparam == MS_VK_SPACE || wparam == MS_VK_RETURN) { - // Insert New Token (Pre-append at cursor), shifting BOTH arenas + // 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++; + if (tape_arena.used + sizeof(U4) <= tape_arena.capacity && anno_arena.used + sizeof(U8) <= anno_arena.capacity) { U8*r anno_ptr = C_(U8*r, anno_arena.start); - for (U8 i = tape_count; i > cursor_idx; i--) { + for (U8 i = tape_count; i > insert_idx; i--) { tape_ptr[i] = tape_ptr[i-1]; anno_ptr[i] = anno_ptr[i-1]; } if (wparam == MS_VK_RETURN) { - tape_ptr[cursor_idx] = PACK_TOKEN(STag_Format, 0xA); // Newline - anno_ptr[cursor_idx] = 0; - cursor_idx++; // Move past newline + tape_ptr[insert_idx] = PACK_TOKEN(STag_Format, 0xA); + anno_ptr[insert_idx] = 0; } else { - tape_ptr[cursor_idx] = PACK_TOKEN(STag_Comment, ID2(' ',' ')); - anno_ptr[cursor_idx] = 0; - cursor_idx++; // Move past space + tape_ptr[insert_idx] = PACK_TOKEN(STag_Comment, ID2(' ',' ')); + anno_ptr[insert_idx] = 0; } + if (is_shift) cursor_idx++; tape_arena.used += sizeof(U4); anno_arena.used += sizeof(U8); } @@ -463,7 +483,15 @@ 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_color(hdc, 0x001E1E1E); + ms_set_bk_mode(hdc, 1); // TRANSPARENT text background + + void* hBgBrush = ms_create_solid_brush(0x00222222); + ms_select_object(hdc, hBgBrush); + ms_rectangle(hdc, -1, -1, 3000, 3000); + + void* hBrushEdit = ms_create_solid_brush(0x008E563B); + void* hBrushNav = ms_create_solid_brush(0x00262F3B); + S4 start_x = 40, start_y = 60, spacing_x = 110, spacing_y = 35; S4 x = start_x, y = start_y; @@ -479,8 +507,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { S4 render_y = y - scroll_y_offset; if (i == cursor_idx && render_y >= 30 && render_y < 500) { - void* hBrush = ms_get_stock_object(editor_mode == MODE_EDIT ? 0 : 2); // WHITE_BRUSH : GRAY_BRUSH - ms_select_object(hdc, hBrush); + ms_select_object(hdc, editor_mode == MODE_EDIT ? hBrushEdit : hBrushNav); ms_rectangle(hdc, x - 5, render_y - 2, x + 95, render_y + 22); } @@ -496,16 +523,16 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { x = start_x; y += spacing_y; } else { - U4 color = tag_colors[tag]; - const char* prefix = tag_prefixes[tag]; - - ms_set_text_color(hdc, color); - if (editor_mode == MODE_EDIT && i == cursor_idx) { - ms_set_text_color(hdc, 0x00000000); // Black text on white cursor - } - - char val_str[9]; - if (tag == STag_Data) { + U4 color = tag_colors[tag]; + const char* prefix = tag_prefixes[tag]; + + 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); + } + + char val_str[9]; if (tag == STag_Data) { u64_to_hex(val, val_str, 6); val_str[6] = '\0'; } else { @@ -541,66 +568,69 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { } // 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); + void* hHudBrush = ms_create_solid_brush(0x00141E23); + ms_select_object(hdc, hHudBrush); + ms_rectangle(hdc, -1, 500, 3000, 3000); + ms_rectangle(hdc, -1, -1, 3000, 40); 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); - u64_to_hex(code_arena.used, jit_str + 32, 3); - ms_text_out_a(hdc, 40, 520, jit_str, 41); + 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, 0x0094BAA1); // Number green + ms_text_out_a(hdc, 40, 550, state_str, 29); - 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]); - const char* tag_name = tag_names[cur_tag]; - U4 cur_color = tag_colors[cur_tag]; - - char semantics_str[64] = "Current Tag: "; - U4 name_len = 0; - while (tag_name[name_len]) { - semantics_str[13 + name_len] = tag_name[name_len]; - name_len++; - } - semantics_str[13 + name_len] = '\0'; - - ms_set_text_color(hdc, cur_color); - ms_text_out_a(hdc, 40, 580, semantics_str, 13 + name_len); - } - - ms_set_text_color(hdc, 0x00FFFFFF); - 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, 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 0 && cursor_idx < tape_count) { + U4 cur_tag = UNPACK_TAG(tape_ptr[cursor_idx]); + const char* tag_name = tag_names[cur_tag]; + U4 cur_color = tag_colors[cur_tag]; + + char semantics_str[64] = "Current Tag: "; + U4 name_len = 0; + while (tag_name[name_len]) { + semantics_str[13 + name_len] = tag_name[name_len]; + name_len++; + } + semantics_str[13 + name_len] = '\0'; + + ms_set_text_color(hdc, cur_color); + ms_text_out_a(hdc, 40, 580, semantics_str, 13 + name_len); + } + + ms_set_text_color(hdc, 0x00C8C8C8); + 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, 0x00D6A454); // Soft blue + 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