From b4055d806755209e3a177db6f9feb31b8c197863 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 20 Feb 2026 16:29:32 -0500 Subject: [PATCH] progress --- attempt_1/main.c | 260 +++++++++++++++++++++++++++++++---------------- 1 file changed, 175 insertions(+), 85 deletions(-) diff --git a/attempt_1/main.c b/attempt_1/main.c index 86cd567..2d395e3 100644 --- a/attempt_1/main.c +++ b/attempt_1/main.c @@ -52,9 +52,14 @@ global const char* tag_names[] = { #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; // Executable Code Arena (The JIT) global FArena code_arena; @@ -101,11 +106,23 @@ void* memcpy(void* dest, const void* src, U8 count) { } #pragma clang optimize on -IA_ void scatter(U4 token) { - if (tape_arena.used + sizeof(U4) <= tape_arena.capacity) { +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) { U4*r ptr = C_(U4*r, tape_arena.start + tape_arena.used); ptr[0] = token; tape_arena.used += sizeof(U4); + + U8*r aptr = C_(U8*r, anno_arena.start + anno_arena.used); + 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++; + } + } + anno_arena.used += sizeof(U8); } } @@ -285,7 +302,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { // Skip control characters in WM_CHAR (handled in KEYDOWN) if (c < 32) break; - if (tag == tmpl(STag, Data)) { + if (tag == STag_Data) { // Hex input U4 digit = 16; if (c >= '0' && c <= '9') digit = c - '0'; @@ -295,10 +312,23 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { val = ((val << 4) | digit) & 0x0FFFFFFF; tape_ptr[cursor_idx] = PACK_TOKEN(tag, val); } - } else { - // 2-Char String input (Shift left and insert new char) - val = ((val << 8) | c) & 0xFFFF; - tape_ptr[cursor_idx] = PACK_TOKEN(tag, val); + } else if (tag != STag_Format) { + U8*r anno_ptr = C_(U8*r, anno_arena.start); + char* anno_str = (char*)&anno_ptr[cursor_idx]; + + int len = 0; + while (len < 8 && anno_str[len] != '\0' && anno_str[len] != ' ') len++; + + 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)); @@ -307,31 +337,69 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { return 0; } case MS_WM_KEYDOWN: { + if (wparam == 0x45 && editor_mode == MODE_NAV) { // 'E' + editor_mode = MODE_EDIT; + ms_invalidate_rect(hwnd, NULL, true); + return 0; + } + if (wparam == 0x1B && editor_mode == MODE_EDIT) { // ESC + editor_mode = MODE_NAV; + ms_invalidate_rect(hwnd, NULL, true); + return 0; + } + + if (editor_mode == MODE_EDIT) { + if (wparam == MS_VK_BACK) { + U4 t = tape_ptr[cursor_idx]; + U4 tag = UNPACK_TAG(t); + U4 val = UNPACK_VAL(t); + if (tag == STag_Data) { + val = val >> 4; + tape_ptr[cursor_idx] = PACK_TOKEN(tag, val); + } else if (tag != STag_Format) { + U8*r anno_ptr = C_(U8*r, anno_arena.start); + char* anno_str = (char*)&anno_ptr[cursor_idx]; + int len = 0; + 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)); + compile_and_run_tape(); + ms_invalidate_rect(hwnd, NULL, true); + } + return 0; // Block navigation keys in Edit Mode + } + if (wparam == MS_VK_RIGHT && cursor_idx < tape_count - 1) cursor_idx++; if (wparam == MS_VK_LEFT && cursor_idx > 0) cursor_idx--; if (wparam == MS_VK_UP) { U8 line_start = cursor_idx; - while (line_start > 0 && UNPACK_TAG(tape_ptr[line_start - 1]) != tmpl(STag, Format)) line_start--; + while (line_start > 0 && UNPACK_TAG(tape_ptr[line_start - 1]) != STag_Format) line_start--; if (line_start > 0) { U8 col = cursor_idx - line_start; U8 prev_line_start = line_start - 1; - while (prev_line_start > 0 && UNPACK_TAG(tape_ptr[prev_line_start - 1]) != tmpl(STag, Format)) prev_line_start--; + while (prev_line_start > 0 && UNPACK_TAG(tape_ptr[prev_line_start - 1]) != STag_Format) prev_line_start--; U8 prev_line_len = (line_start - 1) - prev_line_start; cursor_idx = prev_line_start + (col < prev_line_len ? col : prev_line_len); } } if (wparam == MS_VK_DOWN) { U8 line_start = cursor_idx; - while (line_start > 0 && UNPACK_TAG(tape_ptr[line_start - 1]) != tmpl(STag, Format)) line_start--; + while (line_start > 0 && UNPACK_TAG(tape_ptr[line_start - 1]) != STag_Format) line_start--; U8 col = cursor_idx - line_start; U8 next_line_start = cursor_idx; - while (next_line_start < tape_count && UNPACK_TAG(tape_ptr[next_line_start]) != tmpl(STag, Format)) next_line_start++; + 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 U8 next_line_end = next_line_start; - while (next_line_end < tape_count && UNPACK_TAG(tape_ptr[next_line_end]) != tmpl(STag, Format)) next_line_end++; + 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; cursor_idx = next_line_start + (col < next_line_len ? col : next_line_len); } @@ -347,28 +415,36 @@ 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 + // Delete Token and move cursor left, shifting BOTH arenas if (tape_count > 0) { + U8*r anno_ptr = C_(U8*r, anno_arena.start); for (U8 i = cursor_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) - if (tape_arena.used + sizeof(U4) <= tape_arena.capacity) { + // Insert New Token (Pre-append at cursor), shifting BOTH arenas + 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--) { 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(tmpl(STag, Format), 0xA); // Newline + tape_ptr[cursor_idx] = PACK_TOKEN(STag_Format, 0xA); // Newline + anno_ptr[cursor_idx] = 0; cursor_idx++; // Move past newline } else { - tape_ptr[cursor_idx] = PACK_TOKEN(tmpl(STag, Comment), ID2(' ',' ')); + tape_ptr[cursor_idx] = PACK_TOKEN(STag_Comment, ID2(' ',' ')); + anno_ptr[cursor_idx] = 0; cursor_idx++; // Move past space } tape_arena.used += sizeof(U4); + anno_arena.used += sizeof(U8); } } @@ -392,6 +468,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { S4 x = start_x, y = start_y; U4*r tape_ptr = C_(U4*r, tape_arena.start); + U8*r anno_ptr = C_(U8*r, anno_arena.start); // Render Tokens for (U8 i = 0; i < tape_count; i++) { @@ -402,7 +479,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(2); // GRAY_BRUSH + void* hBrush = ms_get_stock_object(editor_mode == MODE_EDIT ? 0 : 2); // WHITE_BRUSH : GRAY_BRUSH ms_select_object(hdc, hBrush); ms_rectangle(hdc, x - 5, render_y - 2, x + 95, render_y + 22); } @@ -411,8 +488,9 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { U4 t = tape_ptr[i]; U4 tag = UNPACK_TAG(t); U4 val = UNPACK_VAL(t); + U8 anno = anno_ptr[i]; - if (tag == tmpl(STag, Format) && val == 0xA) { + if (tag == STag_Format && val == 0xA) { ms_set_text_color(hdc, 0x00444444); ms_text_out_a(hdc, x, render_y, " \\n ", 6); x = start_x; @@ -420,44 +498,54 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { } 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 == tmpl(STag, Data)) { + if (tag == 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'; + // 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'; + } } - - char out_buf[10]; + + char out_buf[12]; out_buf[0] = prefix[0]; out_buf[1] = ' '; - mem_copy(u8_(out_buf + 2), u8_(val_str), 6); - out_buf[8] = '\0'; + mem_copy(u8_(out_buf + 2), u8_(val_str), 8); + out_buf[10] = '\0'; - ms_text_out_a(hdc, x, render_y, out_buf, 8); + ms_text_out_a(hdc, x, render_y, out_buf, 10); x += spacing_x; } - } else if (UNPACK_TAG(tape_ptr[i]) == tmpl(STag, Format) && UNPACK_VAL(tape_ptr[i]) == 0xA) { + } else if (UNPACK_TAG(tape_ptr[i]) == STag_Format && UNPACK_VAL(tape_ptr[i]) == 0xA) { x = start_x; y += spacing_y; } else { 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, 10, "x86-64 Machine Code Emitter | 2-Reg Stack | [F5] Toggle Run Mode | [PgUp/PgDn] Scroll", 85); @@ -473,7 +561,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { 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]); @@ -491,7 +579,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { 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++) { @@ -501,7 +589,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { 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); @@ -511,7 +599,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { ms_set_text_color(hdc, 0x00FF33FF); ms_text_out_a(hdc, 750, 550 + (i * 25), log_str, 8); } - + ms_select_object(hdc, hOldFont); ms_end_paint(hwnd, &ps); return 0; @@ -524,60 +612,62 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { int main(void) { // 1. Initialize Memory Arenas using WinAPI + FArena Slice tape_mem = slice_ut_(u8_(ms_virtual_alloc(NULL, 64 * 1024, MS_MEM_COMMIT | MS_MEM_RESERVE, MS_PAGE_READWRITE)), 64 * 1024); + Slice anno_mem = slice_ut_(u8_(ms_virtual_alloc(NULL, 64 * 1024, MS_MEM_COMMIT | MS_MEM_RESERVE, MS_PAGE_READWRITE)), 64 * 1024); Slice code_mem = slice_ut_(u8_(ms_virtual_alloc(NULL, 64 * 1024, MS_MEM_COMMIT | MS_MEM_RESERVE, MS_PAGE_EXECUTE_READWRITE)), 64 * 1024); - if (!tape_mem.ptr || !code_mem.ptr) ms_exit_process(1); + if (!tape_mem.ptr || !anno_mem.ptr || !code_mem.ptr) ms_exit_process(1); farena_init(&tape_arena, tape_mem); + farena_init(&anno_arena, anno_mem); farena_init(&code_arena, code_mem); - - // Bootstrap Robust Sample: Factorial State Machine - scatter(PACK_TOKEN(tmpl(STag, Comment), ID2('I','N'))); // .IN - scatter(PACK_TOKEN(tmpl(STag, Data), 5)); // $5 - scatter(PACK_TOKEN(tmpl(STag, Data), 0)); // $0 (Addr) - scatter(PACK_TOKEN(tmpl(STag, Imm), ID2('!',' '))); // ^! - scatter(PACK_TOKEN(tmpl(STag, Data), 1)); // $1 - scatter(PACK_TOKEN(tmpl(STag, Data), 1)); // $1 (Addr) - scatter(PACK_TOKEN(tmpl(STag, Imm), ID2('!',' '))); // ^! - - scatter(PACK_TOKEN(tmpl(STag, Format), 0xA)); // Newline + // Bootstrap Robust Sample: Factorial State Machine + scatter(PACK_TOKEN(STag_Comment, ID2('I','N')), "INIT "); // .IN + scatter(PACK_TOKEN(STag_Data, 5), 0); // $5 + scatter(PACK_TOKEN(STag_Data, 0), 0); // $0 (Addr) + scatter(PACK_TOKEN(STag_Imm, ID2('!',' ')), "STORE "); // ^! + + scatter(PACK_TOKEN(STag_Data, 1), 0); // $1 + scatter(PACK_TOKEN(STag_Data, 1), 0); // $1 (Addr) + scatter(PACK_TOKEN(STag_Imm, ID2('!',' ')), "STORE "); // ^! + + scatter(PACK_TOKEN(STag_Format, 0xA), 0); // Newline // Define the FS (Factorial Step) word in memory - scatter(PACK_TOKEN(tmpl(STag, Define), ID2('F','S'))); - scatter(PACK_TOKEN(tmpl(STag, Data), 0)); - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('@',' '))); - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('R','0'))); - scatter(PACK_TOKEN(tmpl(STag, Format), 0xA)); // Newline - - scatter(PACK_TOKEN(tmpl(STag, Data), 1)); - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('@',' '))); - scatter(PACK_TOKEN(tmpl(STag, Data), 0)); - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('@',' '))); - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('M','*'))); - scatter(PACK_TOKEN(tmpl(STag, Data), 1)); - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('!',' '))); - scatter(PACK_TOKEN(tmpl(STag, Format), 0xA)); // Newline - - scatter(PACK_TOKEN(tmpl(STag, Data), 0)); - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('@',' '))); - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('-','1'))); - scatter(PACK_TOKEN(tmpl(STag, Data), 0)); - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('!',' '))); - - scatter(PACK_TOKEN(tmpl(STag, Data), 1)); - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('@',' '))); - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('P','R'))); // Print Accumulator! - - scatter(PACK_TOKEN(tmpl(STag, Call), ID2('R','E'))); // Return! - - scatter(PACK_TOKEN(tmpl(STag, Format), 0xA)); // Newline - + scatter(PACK_TOKEN(STag_Define, ID2('F','S')), "F_STEP "); + scatter(PACK_TOKEN(STag_Data, 0), 0); + scatter(PACK_TOKEN(STag_Call, ID2('@',' ')), "FETCH "); + scatter(PACK_TOKEN(STag_Call, ID2('R','0')), "RET_IF_Z"); + scatter(PACK_TOKEN(STag_Format, 0xA), 0); // Newline + + scatter(PACK_TOKEN(STag_Data, 1), 0); + scatter(PACK_TOKEN(STag_Call, ID2('@',' ')), "FETCH "); + scatter(PACK_TOKEN(STag_Data, 0), 0); + scatter(PACK_TOKEN(STag_Call, ID2('@',' ')), "FETCH "); + scatter(PACK_TOKEN(STag_Call, ID2('M','*')), "MULT "); + scatter(PACK_TOKEN(STag_Data, 1), 0); + scatter(PACK_TOKEN(STag_Call, ID2('!',' ')), "STORE "); + scatter(PACK_TOKEN(STag_Format, 0xA), 0); // Newline + + scatter(PACK_TOKEN(STag_Data, 0), 0); + scatter(PACK_TOKEN(STag_Call, ID2('@',' ')), "FETCH "); + scatter(PACK_TOKEN(STag_Call, ID2('-','1')), "DEC "); + scatter(PACK_TOKEN(STag_Data, 0), 0); + scatter(PACK_TOKEN(STag_Call, ID2('!',' ')), "STORE "); + + scatter(PACK_TOKEN(STag_Data, 1), 0); + scatter(PACK_TOKEN(STag_Call, ID2('@',' ')), "FETCH "); + scatter(PACK_TOKEN(STag_Call, ID2('P','R')), "PRINT "); // Print Accumulator! + + scatter(PACK_TOKEN(STag_Call, ID2('R','E')), "RETURN "); // Return! + + scatter(PACK_TOKEN(STag_Format, 0xA), 0); // Newline + // Call it - scatter(PACK_TOKEN(tmpl(STag, Imm), ID2('F','S'))); // ^FS - scatter(PACK_TOKEN(tmpl(STag, Imm), ID2('F','S'))); - scatter(PACK_TOKEN(tmpl(STag, Imm), ID2('F','S'))); - scatter(PACK_TOKEN(tmpl(STag, Imm), ID2('F','S'))); - scatter(PACK_TOKEN(tmpl(STag, Imm), ID2('F','S'))); + scatter(PACK_TOKEN(STag_Imm, ID2('F','S')), "F_STEP "); // ^FS + scatter(PACK_TOKEN(STag_Imm, ID2('F','S')), "F_STEP "); + scatter(PACK_TOKEN(STag_Imm, ID2('F','S')), "F_STEP "); + scatter(PACK_TOKEN(STag_Imm, ID2('F','S')), "F_STEP "); + scatter(PACK_TOKEN(STag_Imm, ID2('F','S')), "F_STEP "); MS_WNDCLASSA wc; mem_fill(u8_(& wc), 0, sizeof(wc));