This commit is contained in:
2026-02-20 16:12:17 -05:00
parent 7b738e037c
commit e1a97ae669
2 changed files with 119 additions and 50 deletions

View File

@@ -64,6 +64,20 @@ global U8 vm_rax = 0; // Top
global U8 vm_rdx = 0; // Next global U8 vm_rdx = 0; // Next
global U8 vm_globals[16] = {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;
}
}
// Dictionary // Dictionary
typedef struct { typedef struct {
U4 val; U4 val;
@@ -144,6 +158,20 @@ internal void compile_action(U4 val) {
} else if (val == ID2('R','E')) { // RET } else if (val == ID2('R','E')) { // RET
emit8(0xC3); emit8(0xC3);
return; 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) // Dictionary Resolver (Call User Word)
@@ -162,6 +190,7 @@ internal void compile_action(U4 val) {
IA_ void compile_and_run_tape(void) { IA_ void compile_and_run_tape(void) {
farena_reset(&code_arena); farena_reset(&code_arena);
dict_count = 0; dict_count = 0;
log_count = 0;
// Prologue: Load VM state from globals[14] and [15] // 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(0x41); emit8(0x70); // mov rax, [rcx+112]
@@ -171,7 +200,9 @@ IA_ void compile_and_run_tape(void) {
B4 in_def = false; B4 in_def = false;
U4 def_jmp_offset = 0; 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 tag = UNPACK_TAG(tape_ptr[i]);
U4 val = UNPACK_VAL(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_BACK 0x08
#define MS_VK_TAB 0x09 #define MS_VK_TAB 0x09
#define MS_VK_SPACE 0x20 #define MS_VK_SPACE 0x20
#define MS_VK_F5 0x74
#define MS_VK_PRIOR 0x21
#define MS_VK_NEXT 0x22
// --- Window Procedure --- // --- Window Procedure ---
S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam) { 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) { if (wparam == MS_VK_TAB) {
// Cycle Color Tag // Cycle Color Tag
U4 t = tape_ptr[cursor_idx]; 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; vm_rax = 0; vm_rdx = 0;
mem_zero(u8_(vm_globals), sizeof(vm_globals)); 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; 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 void* hBrush = ms_get_stock_object(2); // GRAY_BRUSH
ms_select_object(hdc, hBrush); 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]; if (render_y >= 30 && render_y < 500) {
U4 tag = UNPACK_TAG(t); U4 t = tape_ptr[i];
U4 val = UNPACK_VAL(t); U4 tag = UNPACK_TAG(t);
U4 val = UNPACK_VAL(t);
if (tag == tmpl(STag, Format) && val == 0xA) { if (tag == tmpl(STag, Format) && val == 0xA) {
ms_set_text_color(hdc, 0x00444444); ms_set_text_color(hdc, 0x00444444);
ms_text_out_a(hdc, x, y, " \\n ", 6); 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; x = start_x;
y += spacing_y; y += spacing_y;
} else { } 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; 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_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 // HUD: Display Current Token Meaning
if (tape_count > 0 && cursor_idx < tape_count) { if (tape_count > 0 && cursor_idx < tape_count) {
U4 cur_tag = UNPACK_TAG(tape_ptr[cursor_idx]); 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'; semantics_str[13 + name_len] = '\0';
ms_set_text_color(hdc, cur_color); 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_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++) { for (int i=0; i<4; i++) {
char glob_str[32] = "[0]: 00000000"; char glob_str[32] = "[0]: 00000000";
glob_str[1] = '0' + i; glob_str[1] = '0' + i;
u64_to_hex(vm_globals[i], glob_str + 5, 8); u64_to_hex(vm_globals[i], glob_str + 5, 8);
ms_set_text_color(hdc, 0x00FFFF33); 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<log_count && i<4; i++) {
char log_str[32] = "00000000";
u64_to_hex(log_buffer[i], log_str, 8);
ms_set_text_color(hdc, 0x00FF33FF);
ms_text_out_a(hdc, 750, 550 + (i * 25), log_str, 8);
} }
ms_select_object(hdc, hOldFont); ms_select_object(hdc, hOldFont);
@@ -499,6 +563,11 @@ int main(void) {
scatter(PACK_TOKEN(tmpl(STag, Call), ID2('-','1'))); scatter(PACK_TOKEN(tmpl(STag, Call), ID2('-','1')));
scatter(PACK_TOKEN(tmpl(STag, Data), 0)); scatter(PACK_TOKEN(tmpl(STag, Data), 0));
scatter(PACK_TOKEN(tmpl(STag, Call), ID2('!',' '))); 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, Call), ID2('R','E'))); // Return!
scatter(PACK_TOKEN(tmpl(STag, Format), 0xA)); // Newline scatter(PACK_TOKEN(tmpl(STag, Format), 0xA)); // Newline

BIN
sourcless_snapshot_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB