91 lines
3.1 KiB
C
91 lines
3.1 KiB
C
// Fundamental Boolean and Null types for no-std environment
|
|
#define true 1
|
|
#define false 0
|
|
#define NULL ((void*)0)
|
|
|
|
#include "duffle.amd64.win32.h"
|
|
|
|
// Define Win32 VirtualAlloc and ExitProcess signature
|
|
WinAPI void* ms_virtual_alloc(void* addr, U8 size, U4 allocation_type, U4 protect) asm("VirtualAlloc");
|
|
WinAPI void ms_exit_process(U4 status) asm("ExitProcess");
|
|
|
|
// Win32 constants
|
|
#define MEM_COMMIT 0x00001000
|
|
#define MEM_RESERVE 0x00002000
|
|
#define PAGE_READWRITE 0x04
|
|
|
|
// 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
|
|
|
|
// 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;
|
|
|
|
internal void scatter(U4 token) {
|
|
tape[tape_pos++] = token;
|
|
}
|
|
|
|
// Minimal u64 to hex string helper for manual "printf" replacement
|
|
internal void print_hex(U8 val) {
|
|
static const char hex_chars[] = "0123456789ABCDEF";
|
|
UTF8 buf[19] = "0x0000000000000000";
|
|
for(S1 i = 17; i >= 2; --i) {
|
|
buf[i] = hex_chars[val & 0xF];
|
|
val >>= 4;
|
|
}
|
|
U4 written;
|
|
ms_write_console(ms_get_std_handle(u4_(-11)), buf, 18, &written, 0);
|
|
}
|
|
|
|
internal void print_str(const char* s) {
|
|
U4 len = 0;
|
|
while(s[len]) len++;
|
|
U4 written;
|
|
ms_write_console(ms_get_std_handle(u4_(-11)), (UTF8 const*)s, len, &written, 0);
|
|
}
|
|
|
|
void main() {
|
|
// 1. Initialize the Sourceless Memory Arena (Win32 VirtualAlloc)
|
|
tape = (U4*)ms_virtual_alloc(NULL, 64 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
if (!tape) ms_exit_process(1);
|
|
|
|
// 2. "Bootstrap" the content (Preemptive Scatter)
|
|
scatter(PACK_TOKEN(TAG_DEFINE, 0x51415245)); // ":SQUARE"
|
|
scatter(PACK_TOKEN(TAG_CALL, 0x00000001)); // DUP
|
|
scatter(PACK_TOKEN(TAG_CALL, 0x00000002)); // *
|
|
scatter(PACK_TOKEN(TAG_CALL, 0x00000003)); // ; (Return)
|
|
scatter(PACK_TOKEN(TAG_COMMENT, 0x4E4F5445)); // "NOTE"
|
|
scatter(PACK_TOKEN(TAG_DATA, 5)); // 5
|
|
scatter(PACK_TOKEN(TAG_IMM, 0x51415245)); // EXECUTE SQUARE
|
|
|
|
// 3. The Visual "Interpreter" Loop
|
|
print_str("--- Sourceless Tape Drive Visualization ---\n");
|
|
for (U8 i = 0; i < tape_pos; i++) {
|
|
U4 t = tape[i];
|
|
U4 tag = UNPACK_TAG(t);
|
|
U4 val = UNPACK_VAL(t);
|
|
|
|
switch (tag) {
|
|
case TAG_DEFINE: print_str("[RED] Define : "); break;
|
|
case TAG_CALL: print_str("[GREEN] Call : "); break;
|
|
case TAG_DATA: print_str("[CYAN] Data : "); break;
|
|
case TAG_IMM: print_str("[YELLOW] Execute: "); break;
|
|
case TAG_COMMENT: print_str("[WHITE] Note : "); break;
|
|
default: print_str("[ERROR] Unknown: "); break;
|
|
}
|
|
print_hex(val);
|
|
print_str("\n");
|
|
}
|
|
|
|
ms_exit_process(0);
|
|
}
|