feat(windows): a Windows target for ludicc, and the compiler builds itself there

--target <triple> (default: the host, from OS=Windows_NT) selects the Windows
runtime. emit_win.ludic defines the POSIX names the backend already calls over
the UCRT and Win32 in IR, so rename replaces an existing file, ftell is 64-bit,
and fopen is binary. Known folders follow %APPDATA% / %LOCALAPPDATA% / %TEMP%,
and the driver speaks cmd.exe, writes .exe outputs and finds LLVM's clang.

Verified: macOS three-stage fixpoint, ludic-dev test 135/135, and on Windows
the Mac-emitted Windows IR and the Windows-built compiler's IR are identical
through two generations.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-13 01:59:41 +03:00
parent 572e09b2b1
commit 5801005fca
15 changed files with 23292 additions and 21806 deletions

View file

@ -3,6 +3,15 @@
# Matches compiler/back/ir_intrin.c. Reached from emit_intrinsic's fall-through.
var g_windowed: bool = false # headless by default (games read stdin / dump PPM)
var g_target_win: bool = false # a Windows target: the header emits emit_win_prelude and the libSystem declares are skipped
# the IR that loads stdout (fd 1) or stderr (fd 2) as a FILE*. macOS names them as
# globals; the UCRT hands them out through a function (see emit_win.ludic).
function stdstream_rhs(fd: int) -> pointer {
if g_target_win { return `call ptr @lp_win_stdio(i32 {itoa(fd)})` }
if fd == 2 { return "load ptr, ptr @__stderrp" }
return "load ptr, ptr @__stdoutp"
}
function is_intrinsic2(name: pointer) -> bool {
if (name == "free") or (name == "fill") { return true }