progress
This commit is contained in:
@@ -159,7 +159,7 @@ IA_ U8 atm_swap_u8(U8*r addr, U8 value){asm volatile("lock xchgq %0,%1":"=r"(val
|
||||
#pragma endregion Thread Coherence
|
||||
|
||||
#pragma region Debug
|
||||
WinAPI void process_exit(U4 status) asm("exit");
|
||||
WinAPI void process_exit(U4 status) asm("ExitProcess");
|
||||
#define debug_trap() __builtin_debugtrap()
|
||||
#if BUILD_DEBUG
|
||||
IA_ void assert(U8 cond) { if(cond){return;} else{debug_trap(); process_exit(1);} }
|
||||
@@ -566,3 +566,61 @@ IA_ void str8gen_append_fmt(Str8Gen*r gen, Str8 fmt, KTL_Str8 tbl) {
|
||||
}
|
||||
#define str8gen_append_str8_(gen, s) str8gen_append_str8(gen, str8(s))
|
||||
#pragma endregion Text Ops
|
||||
|
||||
#pragma region OS_GDI_And_Minimal
|
||||
// --- WinAPI Minimal Definitions ---
|
||||
typedef struct MS_WNDCLASSA {
|
||||
U4 style;
|
||||
S8 (*lpfnWndProc)(void*, U4, U8, S8);
|
||||
S4 cbClsExtra;
|
||||
S4 cbWndExtra;
|
||||
void* hInstance;
|
||||
void* hIcon;
|
||||
void* hCursor;
|
||||
void* hbrBackground;
|
||||
char const* lpszMenuName;
|
||||
char const* lpszClassName;
|
||||
} MS_WNDCLASSA;
|
||||
|
||||
typedef struct MS_POINT { S4 x, y; } MS_POINT;
|
||||
typedef struct MS_MSG { void* hwnd; U4 message; U8 wParam; S8 lParam; U4 time; MS_POINT pt; } MS_MSG;
|
||||
typedef struct MS_RECT { S4 left, top, right, bottom; } MS_RECT;
|
||||
typedef struct MS_PAINTSTRUCT { void* hdc; S4 fErase; MS_RECT rcPaint; S4 fRestore; S4 fIncUpdate; U1 rgbReserved[32]; } MS_PAINTSTRUCT;
|
||||
|
||||
// Win32 API declarations
|
||||
WinAPI void* ms_virtual_alloc(void* lpAddress, U8 dwSize, U4 flAllocationType, U4 flProtect) asm("VirtualAlloc");
|
||||
WinAPI void ms_exit_process(U4 uExitCode) asm("ExitProcess");
|
||||
WinAPI U2 ms_register_class_a(const MS_WNDCLASSA* lpWndClass) asm("RegisterClassA");
|
||||
WinAPI void* ms_create_window_ex_a(U4 dwExStyle, char const* lpClassName, char const* lpWindowName, U4 dwStyle, S4 X, S4 Y, S4 nWidth, S4 nHeight, void* hWndParent, void* hMenu, void* hInstance, void* lpParam) asm("CreateWindowExA");
|
||||
WinAPI S4 ms_show_window(void* hWnd, S4 nCmdShow) asm("ShowWindow");
|
||||
WinAPI S4 ms_get_message_a(MS_MSG* lpMsg, void* hWnd, U4 wMsgFilterMin, U4 wMsgFilterMax) asm("GetMessageA");
|
||||
WinAPI S4 ms_translate_message(const MS_MSG* lpMsg) asm("TranslateMessage");
|
||||
WinAPI S8 ms_dispatch_message_a(const MS_MSG* lpMsg) asm("DispatchMessageA");
|
||||
WinAPI S8 ms_def_window_proc_a(void* hWnd, U4 Msg, U8 wParam, S8 lParam) asm("DefWindowProcA");
|
||||
WinAPI void ms_post_quit_message(S4 nExitCode) asm("PostQuitMessage");
|
||||
WinAPI S4 ms_invalidate_rect(void* hWnd, const MS_RECT* lpRect, S4 bErase) asm("InvalidateRect");
|
||||
WinAPI void* ms_begin_paint(void* hWnd, MS_PAINTSTRUCT* lpPaint) asm("BeginPaint");
|
||||
WinAPI S4 ms_end_paint(void* hWnd, const MS_PAINTSTRUCT* lpPaint) asm("EndPaint");
|
||||
WinAPI U4 ms_set_text_color(void* hdc, U4 color) asm("SetTextColor");
|
||||
WinAPI U4 ms_set_bk_color(void* hdc, U4 color) asm("SetBkColor");
|
||||
WinAPI S4 ms_text_out_a(void* hdc, S4 x, S4 y, char const* lpString, S4 c) asm("TextOutA");
|
||||
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");
|
||||
|
||||
#define MS_MEM_COMMIT 0x00001000
|
||||
#define MS_MEM_RESERVE 0x00002000
|
||||
#define MS_PAGE_READWRITE 0x04
|
||||
#define MS_WM_DESTROY 0x0002
|
||||
#define MS_WM_PAINT 0x000F
|
||||
#define MS_WM_KEYDOWN 0x0100
|
||||
#define MS_WS_OVERLAPPEDWINDOW 0x00CF0000
|
||||
#define MS_WS_VISIBLE 0x10000000
|
||||
#define MS_VK_LEFT 0x25
|
||||
#define MS_VK_UP 0x26
|
||||
#define MS_VK_RIGHT 0x27
|
||||
#define MS_VK_DOWN 0x28
|
||||
|
||||
#define MS_PAGE_EXECUTE_READWRITE 0x40
|
||||
#pragma endregion OS_GDI_And_Minimal
|
||||
|
||||
507
attempt_1/main.c
507
attempt_1/main.c
@@ -5,332 +5,301 @@
|
||||
|
||||
#include "duffle.amd64.win32.h"
|
||||
|
||||
// --- WinAPI Minimal Definitions ---
|
||||
typedef int MS_BOOL;
|
||||
typedef unsigned long MS_DWORD;
|
||||
typedef void* MS_HANDLE;
|
||||
typedef MS_HANDLE MS_HWND;
|
||||
typedef MS_HANDLE MS_HMENU;
|
||||
typedef MS_HANDLE MS_HINSTANCE;
|
||||
typedef MS_HANDLE MS_HICON;
|
||||
typedef MS_HANDLE MS_HCURSOR;
|
||||
typedef MS_HANDLE MS_HBRUSH;
|
||||
typedef MS_HANDLE MS_HDC;
|
||||
typedef MS_HANDLE MS_HFONT;
|
||||
typedef long MS_LONG;
|
||||
typedef char const* MS_LPCSTR;
|
||||
typedef void* MS_LPVOID;
|
||||
typedef S8 MS_LRESULT;
|
||||
typedef U8 MS_WPARAM;
|
||||
typedef S8 MS_LPARAM;
|
||||
typedef U4 MS_UINT;
|
||||
// --- Semantic Tags (Using X-Macros & Enum_) ---
|
||||
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 */
|
||||
|
||||
typedef struct MS_WNDCLASSA {
|
||||
MS_UINT style;
|
||||
MS_LRESULT (*lpfnWndProc)(MS_HWND, MS_UINT, MS_WPARAM, MS_LPARAM);
|
||||
int cbClsExtra;
|
||||
int cbWndExtra;
|
||||
MS_HINSTANCE hInstance;
|
||||
MS_HICON hIcon;
|
||||
MS_HCURSOR hCursor;
|
||||
MS_HBRUSH hbrBackground;
|
||||
MS_LPCSTR lpszMenuName;
|
||||
MS_LPCSTR lpszClassName;
|
||||
} MS_WNDCLASSA;
|
||||
#define X(n, s, c, p) tmpl(STag, n),
|
||||
Tag_Entries()
|
||||
#undef X
|
||||
STag_Count,
|
||||
};
|
||||
|
||||
typedef struct MS_POINT {
|
||||
MS_LONG x, y;
|
||||
} MS_POINT;
|
||||
// Helper array to fetch Hex colors for UI rendering based on STag
|
||||
global U4 tag_colors[] = {
|
||||
#define X(n, s, c, p) c,
|
||||
Tag_Entries()
|
||||
#undef X
|
||||
};
|
||||
|
||||
typedef struct MS_MSG {
|
||||
MS_HWND hwnd;
|
||||
MS_UINT message;
|
||||
MS_WPARAM wParam;
|
||||
MS_LPARAM lParam;
|
||||
MS_DWORD time;
|
||||
MS_POINT pt;
|
||||
} MS_MSG;
|
||||
|
||||
typedef struct MS_RECT {
|
||||
MS_LONG left, top, right, bottom;
|
||||
} MS_RECT;
|
||||
|
||||
typedef struct MS_PAINTSTRUCT {
|
||||
MS_HDC hdc;
|
||||
MS_BOOL fErase;
|
||||
MS_RECT rcPaint;
|
||||
MS_BOOL fRestore;
|
||||
MS_BOOL fIncUpdate;
|
||||
U1 rgbReserved[32];
|
||||
} MS_PAINTSTRUCT;
|
||||
|
||||
// Win32 API declarations
|
||||
WinAPI MS_LPVOID VirtualAlloc(MS_LPVOID lpAddress, U8 dwSize, MS_DWORD flAllocationType, MS_DWORD flProtect);
|
||||
WinAPI void ExitProcess(MS_UINT uExitCode);
|
||||
|
||||
WinAPI U2 RegisterClassA(const MS_WNDCLASSA* lpWndClass);
|
||||
WinAPI MS_HWND CreateWindowExA(MS_DWORD dwExStyle, MS_LPCSTR lpClassName, MS_LPCSTR lpWindowName, MS_DWORD dwStyle, int X, int Y, int nWidth, int nHeight, MS_HWND hWndParent, MS_HMENU hMenu, MS_HINSTANCE hInstance, MS_LPVOID lpParam);
|
||||
WinAPI MS_BOOL ShowWindow(MS_HWND hWnd, int nCmdShow);
|
||||
WinAPI MS_BOOL GetMessageA(MS_MSG* lpMsg, MS_HWND hWnd, MS_UINT wMsgFilterMin, MS_UINT wMsgFilterMax);
|
||||
WinAPI MS_BOOL TranslateMessage(const MS_MSG* lpMsg);
|
||||
WinAPI MS_LRESULT DispatchMessageA(const MS_MSG* lpMsg);
|
||||
WinAPI MS_LRESULT DefWindowProcA(MS_HWND hWnd, MS_UINT Msg, MS_WPARAM wParam, MS_LPARAM lParam);
|
||||
WinAPI void PostQuitMessage(int nExitCode);
|
||||
WinAPI MS_BOOL InvalidateRect(MS_HWND hWnd, const MS_RECT* lpRect, MS_BOOL bErase);
|
||||
|
||||
WinAPI MS_HDC BeginPaint(MS_HWND hWnd, MS_PAINTSTRUCT* lpPaint);
|
||||
WinAPI MS_BOOL EndPaint(MS_HWND hWnd, const MS_PAINTSTRUCT* lpPaint);
|
||||
WinAPI MS_DWORD SetTextColor(MS_HDC hdc, MS_DWORD color);
|
||||
WinAPI MS_DWORD SetBkColor(MS_HDC hdc, MS_DWORD color);
|
||||
WinAPI MS_BOOL TextOutA(MS_HDC hdc, int x, int y, MS_LPCSTR lpString, int c);
|
||||
WinAPI MS_HANDLE GetStockObject(int i);
|
||||
WinAPI MS_HFONT CreateFontA(int cHeight, int cWidth, int cEscapement, int cOrientation, int cWeight, MS_DWORD bItalic, MS_DWORD bUnderline, MS_DWORD bStrikeOut, MS_DWORD iCharSet, MS_DWORD iOutPrecision, MS_DWORD iClipPrecision, MS_DWORD iQuality, MS_DWORD iPitchAndFamily, MS_LPCSTR pszFaceName);
|
||||
WinAPI MS_HANDLE SelectObject(MS_HDC hdc, MS_HANDLE h);
|
||||
|
||||
#define MS_MEM_COMMIT 0x00001000
|
||||
#define MS_MEM_RESERVE 0x00002000
|
||||
#define MS_PAGE_READWRITE 0x04
|
||||
|
||||
#define MS_WM_DESTROY 0x0002
|
||||
#define MS_WM_PAINT 0x000F
|
||||
#define MS_WM_KEYDOWN 0x0100
|
||||
#define MS_WS_OVERLAPPEDWINDOW 0x00CF0000
|
||||
#define MS_WS_VISIBLE 0x10000000
|
||||
|
||||
#define MS_VK_PRIOR 0x21 // Page Up
|
||||
#define MS_VK_NEXT 0x22 // Page Down
|
||||
|
||||
// --- Semantic Tags (The "Colors" of ColorForth) ---
|
||||
#define TAG_DEFINE 0x0 // RED: New word definition
|
||||
#define TAG_CALL 0x1 // GREEN: Call/Compile word
|
||||
#define TAG_DATA 0x2 // CYAN: Variable or Literal Address
|
||||
#define TAG_IMM 0x3 // YELLOW: Immediate value/Execute
|
||||
#define TAG_COMMENT 0x4 // WHITE: Ignored by compiler
|
||||
// Helper array to fetch the text prefix based on STag
|
||||
global const char* tag_prefixes[] = {
|
||||
#define X(n, s, c, p) p,
|
||||
Tag_Entries()
|
||||
#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)
|
||||
|
||||
// The Tape Drive (Memory Arena)
|
||||
global U4* tape;
|
||||
global U8 tape_pos = 0;
|
||||
global U8 view_block = 0; // Current block being viewed
|
||||
#define TOKENS_PER_BLOCK 256
|
||||
#define TOKENS_PER_ROW 8
|
||||
|
||||
// Virtual Machine State (Onat's 2-item stack)
|
||||
global U8 vm_rax = 0;
|
||||
global U8 vm_rdx = 0;
|
||||
// The Tape Drive (Using FArena from duffle)
|
||||
global FArena tape_arena;
|
||||
global U8 cursor_idx = 0;
|
||||
|
||||
internal void scatter(U4 token) {
|
||||
tape[tape_pos++] = token;
|
||||
}
|
||||
// Executable Code Arena (The JIT)
|
||||
global FArena code_arena;
|
||||
|
||||
// Minimal u64 to hex string helper
|
||||
internal void u64_to_hex(U8 val, char* buf, int chars) {
|
||||
static const char hex_chars[] = "0123456789ABCDEF";
|
||||
for(S1 i = chars - 1; i >= 0; --i) {
|
||||
buf[i] = hex_chars[val & 0xF];
|
||||
val >>= 4;
|
||||
}
|
||||
}
|
||||
// VM State: 2-Reg Stack + Global Memory
|
||||
global U8 vm_rax = 0; // Top
|
||||
global U8 vm_rdx = 0; // Next
|
||||
global U8 vm_globals[16] = {0};
|
||||
|
||||
// Provide memset for the compiler's implicit struct zeroing (-nostdlib)
|
||||
// Provide memset/memcpy for the compiler's implicit struct zeroing (-nostdlib)
|
||||
void* memset(void* dest, int c, U8 count) {
|
||||
U1* bytes = (U1*)dest;
|
||||
while (count--) {
|
||||
*bytes++ = (U1)c;
|
||||
}
|
||||
mem_fill(u8_(dest), c, count);
|
||||
return dest;
|
||||
}
|
||||
|
||||
// --- The Tiny Interpreter ---
|
||||
internal void vm_execute(U4 val) {
|
||||
// Very rudimentary simulated execution.
|
||||
// 0x1 = DUP
|
||||
// 0x2 = MULT
|
||||
// Normally this would look up the address in the dictionary.
|
||||
if (val == 0x1) {
|
||||
// DUP (push rax into rdx, simulating a 2-reg stack)
|
||||
vm_rdx = vm_rax;
|
||||
} else if (val == 0x2) {
|
||||
// MULT (rax = rax * rdx)
|
||||
vm_rax = vm_rax * vm_rdx;
|
||||
} else if (val == 0x51415245) {
|
||||
// Call "SQUARE". For this tiny mock, we just execute its body directly: DUP *
|
||||
vm_execute(0x1); // DUP
|
||||
vm_execute(0x2); // MULT
|
||||
}
|
||||
void* memcpy(void* dest, const void* src, U8 count) {
|
||||
mem_copy(u8_(dest), u8_(src), count);
|
||||
return dest;
|
||||
}
|
||||
|
||||
internal void vm_eval_tape() {
|
||||
for (U8 i = 0; i < tape_pos; ++i) {
|
||||
U4 t = tape[i];
|
||||
U4 tag = UNPACK_TAG(t);
|
||||
U4 val = UNPACK_VAL(t);
|
||||
IA_ void scatter(U4 token) {
|
||||
U4*r ptr = farena_push_type(&tape_arena, U4);
|
||||
if (ptr) { ptr[0] = token; }
|
||||
}
|
||||
|
||||
if (tag == TAG_DATA) {
|
||||
// Push data onto the 2-register stack (simulate the xchg setup)
|
||||
vm_rdx = vm_rax;
|
||||
vm_rax = val;
|
||||
} else if (tag == TAG_IMM) {
|
||||
// Execute immediately
|
||||
vm_execute(val);
|
||||
IA_ void u64_to_hex(U8 val, char* buf, S4 chars) {
|
||||
static const char hex_chars[] = "0123456789ABCDEF";
|
||||
for(S1 i = chars - 1; i >= 0; --i) { buf[i] = hex_chars[val & 0xF]; val >>= 4; }
|
||||
}
|
||||
|
||||
// --- Minimal x86-64 Emitter ---
|
||||
IA_ void emit8(U1 b) { U1*r p = farena_push_type(&code_arena, U1); if(p) p[0] = b; }
|
||||
IA_ void emit32(U4 val){ U4*r p = farena_push_type(&code_arena, U4); if(p) p[0] = val; }
|
||||
|
||||
IA_ void compile_word(U4 tag, U4 val) {
|
||||
if (tag == tmpl(STag, Data)) {
|
||||
// mov rdx, rax
|
||||
emit8(0x48); emit8(0x89); emit8(0xC2);
|
||||
// mov rax, imm32
|
||||
emit8(0x48); emit8(0xC7); emit8(0xC0); emit32(val);
|
||||
} else if (tag == tmpl(STag, Imm) || tag == tmpl(STag, Call)) {
|
||||
if (val == 0x1) { // SWAP: xchg rax, rdx
|
||||
emit8(0x48); emit8(0x87); emit8(0xC2);
|
||||
} else if (val == 0x2) { // MULT: imul rax, rdx
|
||||
emit8(0x48); emit8(0x0F); emit8(0xAF); emit8(0xC2);
|
||||
} else if (val == 0x3) { // ADD: add rax, rdx
|
||||
emit8(0x48); emit8(0x01); emit8(0xD0);
|
||||
} else if (val == 0x4) { // FETCH: mov rax, QWORD PTR [rcx + rax*8]
|
||||
emit8(0x48); emit8(0x8B); emit8(0x04); emit8(0xC1);
|
||||
} else if (val == 0x5) { // DEC: dec rax
|
||||
emit8(0x48); emit8(0xFF); emit8(0xC8);
|
||||
} else if (val == 0x6) { // STORE: mov QWORD PTR [rcx + rax*8], rdx
|
||||
emit8(0x48); emit8(0x89); emit8(0x14); emit8(0xC1);
|
||||
} else if (val == 0x7) { // RET_IF_ZERO: test rax, rax; jnz +9; epilogue; ret
|
||||
emit8(0x48); emit8(0x85); emit8(0xC0); // test rax, rax
|
||||
emit8(0x75); emit8(0x09); // jnz skip_ret (+9 bytes)
|
||||
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
|
||||
} else if (val == 0xFA) { // F_STEP (Inlined Compiler Macro)
|
||||
compile_word(tmpl(STag, Data), 0);
|
||||
compile_word(tmpl(STag, Imm), 0x4);
|
||||
compile_word(tmpl(STag, Imm), 0x7);
|
||||
|
||||
compile_word(tmpl(STag, Data), 1);
|
||||
compile_word(tmpl(STag, Imm), 0x4);
|
||||
compile_word(tmpl(STag, Data), 0);
|
||||
compile_word(tmpl(STag, Imm), 0x4);
|
||||
compile_word(tmpl(STag, Imm), 0x2);
|
||||
compile_word(tmpl(STag, Data), 1);
|
||||
compile_word(tmpl(STag, Imm), 0x6);
|
||||
|
||||
compile_word(tmpl(STag, Data), 0);
|
||||
compile_word(tmpl(STag, Imm), 0x4);
|
||||
compile_word(tmpl(STag, Imm), 0x5);
|
||||
compile_word(tmpl(STag, Data), 0);
|
||||
compile_word(tmpl(STag, Imm), 0x6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Window Procedure (Event Loop) ---
|
||||
MS_LRESULT win_proc(MS_HWND hwnd, MS_UINT msg, MS_WPARAM wparam, MS_LPARAM lparam) {
|
||||
IA_ void compile_and_run_tape(void) {
|
||||
farena_reset(&code_arena);
|
||||
|
||||
// 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]
|
||||
|
||||
// Compile the selected tokens
|
||||
U4*r tape_ptr = C_(U4*r, tape_arena.start);
|
||||
for (U8 i = 0; i <= cursor_idx; i++) {
|
||||
compile_word(UNPACK_TAG(tape_ptr[i]), UNPACK_VAL(tape_ptr[i]));
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
// 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);
|
||||
|
||||
switch (msg) {
|
||||
case MS_WM_KEYDOWN: {
|
||||
if (wparam == MS_VK_NEXT) { // Page Down
|
||||
if ((view_block + 1) * TOKENS_PER_BLOCK < tape_pos) view_block++;
|
||||
InvalidateRect(hwnd, NULL, true);
|
||||
} else if (wparam == MS_VK_PRIOR) { // Page Up
|
||||
if (view_block > 0) view_block--;
|
||||
InvalidateRect(hwnd, NULL, true);
|
||||
}
|
||||
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_DOWN && cursor_idx + TOKENS_PER_ROW < tape_count) cursor_idx += TOKENS_PER_ROW;
|
||||
if (wparam == MS_VK_UP && cursor_idx >= TOKENS_PER_ROW) cursor_idx -= TOKENS_PER_ROW;
|
||||
|
||||
// Interaction: Reset VM and compile up to cursor
|
||||
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;
|
||||
}
|
||||
case MS_WM_PAINT: {
|
||||
MS_PAINTSTRUCT ps;
|
||||
MS_HDC hdc = BeginPaint(hwnd, &ps);
|
||||
void* hdc = ms_begin_paint(hwnd, &ps);
|
||||
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);
|
||||
|
||||
// Modern Monospace Font (Consolas)
|
||||
MS_HFONT hFont = CreateFontA(22, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Consolas");
|
||||
MS_HANDLE hOldFont = SelectObject(hdc, hFont);
|
||||
ms_set_bk_color(hdc, 0x001E1E1E);
|
||||
S4 start_x = 40, start_y = 60, spacing_x = 110, spacing_y = 35;
|
||||
|
||||
// Dark background
|
||||
U4 bg_color = 0x001E1E1E;
|
||||
SetBkColor(hdc, bg_color);
|
||||
U4*r tape_ptr = C_(U4*r, tape_arena.start);
|
||||
|
||||
int x = 20;
|
||||
int y = 20;
|
||||
int line_height = 24;
|
||||
// Render Tokens
|
||||
for (U8 i = 0; i < tape_count; i++) {
|
||||
S4 col = (S4)(i % TOKENS_PER_ROW);
|
||||
S4 row = (S4)(i / TOKENS_PER_ROW);
|
||||
S4 x = start_x + (col * spacing_x);
|
||||
S4 y = start_y + (row * spacing_y);
|
||||
|
||||
// Render Block Header
|
||||
SetTextColor(hdc, 0x00AAAAAA);
|
||||
char header_str[32] = "Block 0x000";
|
||||
u64_to_hex(view_block, header_str + 8, 3);
|
||||
TextOutA(hdc, x, y, header_str, 11);
|
||||
y += line_height * 2;
|
||||
if (i == cursor_idx) {
|
||||
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);
|
||||
}
|
||||
|
||||
// Render Tokens for current block
|
||||
U8 start_idx = view_block * TOKENS_PER_BLOCK;
|
||||
U8 end_idx = start_idx + TOKENS_PER_BLOCK;
|
||||
if (end_idx > tape_pos) end_idx = tape_pos;
|
||||
|
||||
for (U8 i = start_idx; i < end_idx; i++) {
|
||||
U4 t = tape[i];
|
||||
U4 t = tape_ptr[i];
|
||||
U4 tag = UNPACK_TAG(t);
|
||||
U4 val = UNPACK_VAL(t);
|
||||
|
||||
U4 color = 0x00FFFFFF;
|
||||
const char* prefix = "";
|
||||
U4 color = tag_colors[tag];
|
||||
const char* prefix = tag_prefixes[tag];
|
||||
|
||||
switch (tag) {
|
||||
case TAG_DEFINE: color = 0x003333FF; prefix = ": "; break; // RED
|
||||
case TAG_CALL: color = 0x0033FF33; prefix = "~ "; break; // GREEN
|
||||
case TAG_DATA: color = 0x00FFFF33; prefix = "$ "; break; // CYAN
|
||||
case TAG_IMM: color = 0x0033FFFF; prefix = "^ "; break; // YELLOW
|
||||
case TAG_COMMENT: color = 0x00AAAAAA; prefix = ". "; break; // DIM
|
||||
ms_set_text_color(hdc, color);
|
||||
|
||||
char val_str[9];
|
||||
u64_to_hex(val, val_str, 6);
|
||||
val_str[6] = '\0';
|
||||
|
||||
// Friendly names for our primitives
|
||||
if (tag == tmpl(STag, Imm) || tag == tmpl(STag, Call)) {
|
||||
if (val == 0x1) mem_copy(u8_(val_str), u8_("SWAP "), 6);
|
||||
if (val == 0x2) mem_copy(u8_(val_str), u8_("MULT "), 6);
|
||||
if (val == 0x3) mem_copy(u8_(val_str), u8_("ADD "), 6);
|
||||
if (val == 0x4) mem_copy(u8_(val_str), u8_("FETCH "), 6);
|
||||
if (val == 0x5) mem_copy(u8_(val_str), u8_("DEC "), 6);
|
||||
if (val == 0x6) mem_copy(u8_(val_str), u8_("STORE "), 6);
|
||||
if (val == 0x7) mem_copy(u8_(val_str), u8_("RET_IF"), 6);
|
||||
if (val == 0xFA) mem_copy(u8_(val_str), u8_("F_STEP"), 6);
|
||||
}
|
||||
|
||||
SetTextColor(hdc, color);
|
||||
TextOutA(hdc, x, y, prefix, 2);
|
||||
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';
|
||||
|
||||
char val_str[8];
|
||||
u64_to_hex(val, val_str, 7);
|
||||
val_str[7] = '\0';
|
||||
TextOutA(hdc, x + 24, y, val_str, 7);
|
||||
|
||||
y += line_height;
|
||||
// Simple column wrapping inside the block
|
||||
if (y > 500) {
|
||||
y = 20 + line_height * 2;
|
||||
x += 160;
|
||||
}
|
||||
ms_text_out_a(hdc, x, y, out_buf, 8);
|
||||
}
|
||||
|
||||
// Render VM State at the bottom right
|
||||
y = 480;
|
||||
x = 600;
|
||||
SetTextColor(hdc, 0x00FFFFFF);
|
||||
TextOutA(hdc, x, y, "VM State (2-Reg Stack)", 22);
|
||||
y += line_height;
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
char rax_str[16] = "RAX: 0x00000000";
|
||||
char rdx_str[16] = "RDX: 0x00000000";
|
||||
u64_to_hex(vm_rax, rax_str + 7, 8);
|
||||
u64_to_hex(vm_rdx, rdx_str + 7, 8);
|
||||
ms_set_text_color(hdc, 0x00FFFFFF);
|
||||
ms_text_out_a(hdc, 400, 480, "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);
|
||||
}
|
||||
|
||||
SetTextColor(hdc, 0x0033FF33);
|
||||
TextOutA(hdc, x, y, rax_str, 15);
|
||||
y += line_height;
|
||||
SetTextColor(hdc, 0x00FFFF33);
|
||||
TextOutA(hdc, x, y, rdx_str, 15);
|
||||
|
||||
SelectObject(hdc, hOldFont);
|
||||
EndPaint(hwnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_DESTROY: {
|
||||
PostQuitMessage(0);
|
||||
ms_select_object(hdc, hOldFont);
|
||||
ms_end_paint(hwnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_DESTROY: { ms_post_quit_message(0); return 0; }
|
||||
}
|
||||
return DefWindowProcA(hwnd, msg, wparam, lparam);
|
||||
return ms_def_window_proc_a(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
void main() {
|
||||
tape = (U4*)VirtualAlloc(NULL, 64 * 1024, MS_MEM_COMMIT | MS_MEM_RESERVE, MS_PAGE_READWRITE);
|
||||
if (!tape) ExitProcess(1);
|
||||
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 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);
|
||||
|
||||
farena_init(&tape_arena, tape_mem);
|
||||
farena_init(&code_arena, code_mem);
|
||||
|
||||
// Bootstrap Block 0
|
||||
scatter(PACK_TOKEN(TAG_DEFINE, 0x51415245)); // ":SQUARE"
|
||||
scatter(PACK_TOKEN(TAG_CALL, 0x00000001)); // DUP
|
||||
scatter(PACK_TOKEN(TAG_CALL, 0x00000002)); // MULT
|
||||
scatter(PACK_TOKEN(TAG_CALL, 0x00000003)); // RET
|
||||
scatter(PACK_TOKEN(TAG_COMMENT, 0x4E4F5445)); // ".NOTE"
|
||||
scatter(PACK_TOKEN(TAG_DATA, 5)); // $5
|
||||
scatter(PACK_TOKEN(TAG_IMM, 0x51415245)); // ^SQUARE
|
||||
// Bootstrap Robust Sample: Factorial State Machine
|
||||
scatter(PACK_TOKEN(tmpl(STag, Comment), 0x1111)); // .INIT
|
||||
scatter(PACK_TOKEN(tmpl(STag, Data), 5)); // $5
|
||||
scatter(PACK_TOKEN(tmpl(STag, Data), 0)); // $0 (Addr)
|
||||
scatter(PACK_TOKEN(tmpl(STag, Imm), 0x6)); // ^STORE
|
||||
scatter(PACK_TOKEN(tmpl(STag, Data), 1)); // $1
|
||||
scatter(PACK_TOKEN(tmpl(STag, Data), 1)); // $1 (Addr)
|
||||
scatter(PACK_TOKEN(tmpl(STag, Imm), 0x6)); // ^STORE
|
||||
scatter(PACK_TOKEN(tmpl(STag, Comment), 0xFAFA)); // .FAFA
|
||||
scatter(PACK_TOKEN(tmpl(STag, Imm), 0xFA)); // ^F_STEP
|
||||
scatter(PACK_TOKEN(tmpl(STag, Imm), 0xFA));
|
||||
scatter(PACK_TOKEN(tmpl(STag, Imm), 0xFA));
|
||||
scatter(PACK_TOKEN(tmpl(STag, Imm), 0xFA));
|
||||
scatter(PACK_TOKEN(tmpl(STag, Imm), 0xFA));
|
||||
|
||||
// Fill some padding so we can test pagination (Page Down)
|
||||
for(int i=0; i < 300; i++) {
|
||||
scatter(PACK_TOKEN(TAG_COMMENT, 0x0));
|
||||
}
|
||||
|
||||
// Block 1 content
|
||||
scatter(PACK_TOKEN(TAG_DATA, 10)); // $10
|
||||
scatter(PACK_TOKEN(TAG_IMM, 0x51415245)); // ^SQUARE
|
||||
|
||||
// Run Interpreter
|
||||
vm_eval_tape();
|
||||
|
||||
// Window Setup
|
||||
MS_WNDCLASSA wc;
|
||||
memset(&wc, 0, sizeof(wc));
|
||||
wc.lpfnWndProc = win_proc;
|
||||
wc.hInstance = (MS_HINSTANCE)GetStockObject(0);
|
||||
wc.hInstance = ms_get_stock_object(0);
|
||||
wc.lpszClassName = "ColorForthWindow";
|
||||
wc.hbrBackground = (MS_HBRUSH)GetStockObject(4);
|
||||
|
||||
if (!RegisterClassA(&wc)) ExitProcess(1);
|
||||
|
||||
MS_HWND hwnd = CreateWindowExA(
|
||||
0, wc.lpszClassName, "Sourceless Tape Drive Editor",
|
||||
MS_WS_OVERLAPPEDWINDOW | MS_WS_VISIBLE,
|
||||
100, 100, 800, 600, NULL, NULL, wc.hInstance, NULL
|
||||
);
|
||||
|
||||
if (!hwnd) ExitProcess(1);
|
||||
wc.hbrBackground = ms_get_stock_object(4);
|
||||
ms_register_class_a(&wc);
|
||||
|
||||
void* hwnd = ms_create_window_ex_a(0, wc.lpszClassName, "Sourceless Global Memory Explorer", MS_WS_OVERLAPPEDWINDOW | MS_WS_VISIBLE, 100, 100, 1100, 750, NULL, NULL, wc.hInstance, NULL);
|
||||
MS_MSG msg;
|
||||
while (GetMessageA(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
|
||||
ExitProcess(0);
|
||||
while (ms_get_message_a(&msg, NULL, 0, 0)) { ms_translate_message(&msg); ms_dispatch_message_a(&msg); }
|
||||
ms_exit_process(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user