This commit is contained in:
2026-02-19 17:02:32 -05:00
parent 692917664f
commit 437fcde98d
4 changed files with 159 additions and 29 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
# references # references
.env .env
references/processed_visuals references/processed_visuals
build

18
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/attempt_1"
],
"defines": [
"BUILD_DEBUG",
"UNICODE",
"_UNICODE"
],
"cStandard": "c23",
"windowsSdkVersion": "10.0.26100.0"
}
],
"version": 4
}

View File

@@ -1,5 +1,18 @@
// Fundamental Boolean and Null types for no-std environment
#define true 1
#define false 0
#define NULL ((void*)0)
#include "duffle.amd64.win32.h" #include "duffle.amd64.win32.h"
#include <stdio.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) // Semantic Tags (The "Colors" of ColorForth)
#define TAG_DEFINE 0x0 // RED: New word definition #define TAG_DEFINE 0x0 // RED: New word definition
@@ -21,51 +34,57 @@ internal void scatter(U4 token) {
tape[tape_pos++] = token; tape[tape_pos++] = token;
} }
int main() { // 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) // 1. Initialize the Sourceless Memory Arena (Win32 VirtualAlloc)
// We'll allocate 64KB for our initial "tape drive". tape = (U4*)ms_virtual_alloc(NULL, 64 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
tape = (U4*)VirtualAlloc(NULL, 64 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (!tape) ms_exit_process(1);
if (!tape) return 1;
// 2. "Bootstrap" the content (Preemptive Scatter) // 2. "Bootstrap" the content (Preemptive Scatter)
// Here we manually define a word: :SQUARE ( x -- x*x ) scatter(PACK_TOKEN(TAG_DEFINE, 0x51415245)); // ":SQUARE"
// In a real editor, these are written directly by the UI to memory.
scatter(PACK_TOKEN(TAG_DEFINE, 0x51415245)); // ":SQUARE" (Encoded name or index)
scatter(PACK_TOKEN(TAG_CALL, 0x00000001)); // DUP scatter(PACK_TOKEN(TAG_CALL, 0x00000001)); // DUP
scatter(PACK_TOKEN(TAG_CALL, 0x00000002)); // * scatter(PACK_TOKEN(TAG_CALL, 0x00000002)); // *
scatter(PACK_TOKEN(TAG_CALL, 0x00000003)); // ; (Return) scatter(PACK_TOKEN(TAG_CALL, 0x00000003)); // ; (Return)
// Now a comment
scatter(PACK_TOKEN(TAG_COMMENT, 0x4E4F5445)); // "NOTE" scatter(PACK_TOKEN(TAG_COMMENT, 0x4E4F5445)); // "NOTE"
scatter(PACK_TOKEN(TAG_DATA, 5)); // 5
// Now an execution block: 5 SQUARE
scatter(PACK_TOKEN(TAG_DATA, 5)); // The number 5
scatter(PACK_TOKEN(TAG_IMM, 0x51415245)); // EXECUTE SQUARE scatter(PACK_TOKEN(TAG_IMM, 0x51415245)); // EXECUTE SQUARE
// 3. The Visual "Interpreter" Loop // 3. The Visual "Interpreter" Loop
// This simulates the editor/decompiler reading the raw memory. print_str("--- Sourceless Tape Drive Visualization ---\n");
printf("--- Sourceless Tape Drive Visualization ---
");
for (U8 i = 0; i < tape_pos; i++) { for (U8 i = 0; i < tape_pos; i++) {
U4 t = tape[i]; U4 t = tape[i];
U4 tag = UNPACK_TAG(t); U4 tag = UNPACK_TAG(t);
U4 val = UNPACK_VAL(t); U4 val = UNPACK_VAL(t);
switch (tag) { switch (tag) {
case TAG_DEFINE: printf("[RED] Define : 0x%07X case TAG_DEFINE: print_str("[RED] Define : "); break;
", val); break; case TAG_CALL: print_str("[GREEN] Call : "); break;
case TAG_CALL: printf("[GREEN] Call : 0x%07X case TAG_DATA: print_str("[CYAN] Data : "); break;
", val); break; case TAG_IMM: print_str("[YELLOW] Execute: "); break;
case TAG_DATA: printf("[CYAN] Data : %u case TAG_COMMENT: print_str("[WHITE] Note : "); break;
", val); break; default: print_str("[ERROR] Unknown: "); break;
case TAG_IMM: printf("[YELLOW] Execute: 0x%07X
", val); break;
case TAG_COMMENT: printf("[WHITE] Note : 0x%07X
", val); break;
default: printf("[ERROR] Unknown: 0x%08X
", t); break;
} }
print_hex(val);
print_str("\n");
} }
return 0; ms_exit_process(0);
} }

View File

@@ -0,0 +1,92 @@
$path_root = split-path -Path $PSScriptRoot -Parent
# --- Toolchain Executable Paths ---
$compiler = 'clang'
$linker = 'lld-link.exe'
# https://clang.llvm.org/docs/ClangCommandLineReference.html
$flag_c23 = '-std=c23'
$flag_compile = '-c'
$flag_debug = '-g'
$flag_define = '-D'
$flag_exceptions_disabled = '-fno-exceptions'
$flag_diagnostics_absolute_paths = '-fdiagnostics-absolute-paths'
$flag_include = '-I'
$flag_linker = '-Wl,'
$flag_link_mapfile = '/MAP:'
$flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE'
$flag_link_win_machine_64 = '/MACHINE:X64'
$flag_link_win_debug = '/DEBUG'
$flag_link_win_pdb = '/PDB:'
$flag_link_win_path_output = '/OUT:'
$flag_link_no_incremental = '/INCREMENTAL:NO'
$flag_no_optimization = '-O0'
$flag_path_output = '-o'
$flag_wall = '-Wall'
$flag_nologo = '/nologo'
$path_build = join-path $path_root 'build'
if ( -not(test-path -Path $path_build) ) {
new-item -ItemType Directory -Path $path_build
}
push-location $path_build
# --- File Paths ---
$unit_name = "attempt_1"
$unit_source = join-path $path_root "attempt_1\main.c"
$object = join-path $path_build "$unit_name.obj"
$binary = join-path $path_build "$unit_name.exe"
$pdb = join-path $path_build "$unit_name.pdb"
$map = join-path $path_build "$unit_name.map"
# --- Stage 1: Compile C to Object ---
write-host "Stage 1: Compiling C to Object"
$compiler_args = @()
$compiler_args += ($flag_define + 'BUILD_DEBUG=1')
$compiler_args += $flag_debug
$compiler_args += $flag_wall
$compiler_args += $flag_c23
$compiler_args += $flag_no_optimization
$compiler_args += $flag_diagnostics_absolute_paths
$compiler_args += $flag_exceptions_disabled
$compiler_args += ($flag_include + (join-path $path_root "attempt_1"))
$compiler_args += "-nostdlib"
$compiler_args += "-ffreestanding"
$compiler_args += $flag_compile
$compiler_args += $flag_path_output, $object
$compiler_args += $unit_source
$compiler_args | ForEach-Object { Write-Host $_ }
$stage1_time = Measure-Command { & $compiler $compiler_args }
write-host "Compilation took $($stage1_time.TotalMilliseconds)ms"
write-host
# --- Stage 2: Linking ---
write-host "Stage 2: Linking"
$linker_args = @()
$linker_args += $flag_nologo
$linker_args += $flag_link_win_machine_64
$linker_args += $flag_link_no_incremental
$linker_args += ($flag_link_win_path_output + $binary)
$linker_args += $flag_link_win_debug
$linker_args += $flag_link_win_pdb + $pdb
$linker_args += $flag_link_mapfile + $map
$linker_args += $flag_link_win_subsystem_console
$linker_args += "/nodefaultlib"
$linker_args += "kernel32.lib"
$linker_args += "user32.lib"
$linker_args += "/entry:main"
$linker_args += $object
$linker_args | ForEach-Object { Write-Host $_ }
$linking_time = Measure-Command { & $linker $linker_args }
write-host "Linking took $($linking_time.TotalMilliseconds)ms"
write-host
if ($LASTEXITCODE -eq 0) {
write-host "Running $binary..." -ForegroundColor Green
& $binary
}
Pop-Location