Hoppa till innehållet
Ridgun
Svenska

Referens

Ridgun — Specifikation av plattformsabstraktionslagret (PAL) och systembiblioteken (posix.rglib, io.rglib)

Den här specifikationen definierar kontraktet mellan Ridgun-kompilatorn (ridgunc v0.9.5) och Ridguns systembibliotek (posix.rglib, io.rglib, unix-tools) för alla operativsystem som stöds eller planeras (Linux, MacOS, Windows) och alla processorarkitekturer (X86_64, Arm64).


1. Översikt över arkitekturen: PAL i två lager + summatyper för målplattformen

Ridgun undviker att exponera råa systemanropsnummer som bara finns på Linux eller OS-specifika bitflaggor i portabla bibliotek genom att dela upp interaktionen med systemet i två kompilatorlager plus starkt typade algebraiska datatyper för målplattformen:

  1. Fördeklarerade summatyper för målplattformen (sys os => SysOs, sys arch => SysArch):
  • I stället för att returnera otypade String (som lätt får stavfel och inte kan kontrolleras av typkontrollanten) fördeklarerar ridgunc två utökningsbara summatyper:
     type SysOs   = Linux | MacOS | Windows
     type SysArch = X86_64 | Arm64
  • sys os => SysOs och sys arch => SysArch löses av backenden vid kompileringstid till NLoadAdt0-konstanter utan extra kostnad (Linux / X86_64 på x86_64-linux, Linux / Arm64 på arm64-linux).
  • Bibliotek kan välja väg på ett rent sätt genom tabellformad mönstermatchning på SysOs / SysArch, jämföra med == ((sys os) == Linux) eller utöka dem för egna bare metal- eller BSD-mål via expand type SysOs = FreeBSD | BareMetal (FR-COMP-005).
  1. Lager 1 — Plattformsoberoende PAL-primitiver (sys open mode, sys open, sys close, sys read fd, sys write fd, sys poll, sys terminate, sys kill, sys call):
  • Alla flaggmasker och poll-händelsemasker som skickas till primitiverna i lager 1 använder Ridguns normaliserade PAL-konstanter.
  • Varje backend (x86_64.rg ELF64, arm64.rg ELF64 och framtida backends för Mach-O på macOS och PE64 på Windows) översätter de normaliserade konstanterna till operativsystemkärnans nativa ABI (openat/poll/kill på Linux, open/poll/kill på macOS, CreateFileW/WaitForSingleObject/WSAPoll/TerminateProcess på Windows).
  • Både syntaxen med naturliga mellanslag (sys open mode path "r") och syntaxen med understreck (sys_open_mode path "r") accepteras på identiskt sätt.
  1. Lager 2 — Deklarativa körningskvoter (with timeout <duration> do):
  • Heltalsliteraler stöder varaktighetssuffix: _ms (* 1), _s (* 1000) och _min (* 60000).
  • with timeout 500_ms do <body> (och kombinerat with region 64_KB, timeout 500_ms do <body>) lägger en lexikal deadline (sys time ms + duration_ms) på den trådlokala PAL-stacken för deadlines, begränsar den till en eventuell striktare yttre deadline (min(outer, new)) och återställer den yttre deadlinen vid utträde.
  • Inuti ett with timeout-block returnerar sys deadline ms => Int den aktiva epokdeadlinen (0 om obegränsad), sys remaining ms => Int returnerar de återstående millisekunderna (-1 om obegränsad, 0 om den har löpt ut), och sys poll fd events -1 begränsar automatiskt sin väntetid till sys remaining ms.

2. Referens för kompilatorns inbyggda PAL (FR-COMP-007)

2.1 Information om målplattformen

PrimitivSignaturBeskrivning
sys os=> SysOsOperativsystemet för målplattformen vid kompileringstid (Linux | MacOS | Windows).
sys arch=> SysArchProcessorarkitekturen för målplattformen vid kompileringstid (X86_64 | Arm64).

Exempel på idiomatiskt val mellan flera operativsystem i ett .rglib-bibliotek utan if/else-kedjor:

fn :: path separator SysOs   => String
      path separator Linux   =  "/"
      path separator MacOS   =  "/"
      path separator Windows =  "\\"

fn :: null device => String
      null device =  null device for (sys os)

fn :: null device for SysOs   => String
      null device for Windows =  "NUL"
      null device for _       =  "/dev/null"

2.2 I/O via deskriptorer och handtag samt poll av beredskap

PrimitivSignaturNormaliserat PAL-kontrakt
sys open modeString String => IntÖppnar path med den portabla lägessträngen "r", "w", "a", "rw", "w+" eller "a+" (standardbehörighet 0644 / 420 vid skapande). Returnerar en deskriptor eller ett handtag >= 0 eller en negativ felkod (-errno).
sys openString Int Int => IntÖppnar path med Ridguns normaliserade PAL-flags (0 = endast läsning, 1 = endast skrivning, 2 = läsning och skrivning, 64 = skapa, 512 = trunkera, 1024 = lägg till i slutet, 2048 = icke-blockerande) och behörigheten mode (t.ex. 420 för 0644).
sys closeInt => IntStänger fd/handtaget. Returnerar 0 vid framgång eller negativt -errno.
sys read fdInt Int => StringLäser upp till max_bytes från fd/handtaget (0 = stdin, 1 = stdout, 2 = stderr, eller en öppnad fil, pipe eller FIFO). Returnerar "" vid EOF (0 byte) eller fel.
sys write fdInt String => IntSkriver data till fd/handtaget. Returnerar antalet skrivna byte (>= 0) eller negativt -errno.
sys pollInt Int Int => IntPollar fd efter de normaliserade händelserna events (1 = POLLIN läsbar, 4 = POLLOUT skrivbar, 8 = POLLERR, 16 = POLLHUP) med timeout_ms (-1 = oändligt eller begränsat till sys remaining ms inuti with timeout, 0 = icke-blockerande poll, > 0 = längsta väntetid i ms). Returnerar en bitmask > 0 med färdiga händelser, 0 vid timeout eller < 0 vid -errno.

2.3 Klockor, deadlines, signaler och nödutgång på låg nivå

PrimitivSignaturNormaliserat PAL-kontrakt
sys time ms=> IntMonoton millisekundklocka (CLOCK_MONOTONIC).
sys sleep msInt => ()Sover i ms millisekunder (nanosleep / Sleep).
sys deadline ms=> IntAktiv lexikal deadline i monotona ms (0 utanför with timeout).
sys remaining ms=> IntMillisekunder kvar till den aktiva lexikala deadlinen (-1 utanför with timeout, 0 när den har löpt ut).
sys getpid=> IntAktuellt process-id (> 0).
sys terminateInt Bool => IntPlattformsoberoende processavslutning: force = False skickar en kontrollerad avslutning (SIGTERM på POSIX), force = True tvingar fram omedelbar avslutning (SIGKILL på POSIX, TerminateProcess på Windows). Returnerar 0 eller -errno.
sys killInt Int => IntSkickar en normaliserad signal (0 = kontroll av att processen finns, 2 = SIGINT, 9 = SIGKILL, 15 = SIGTERM) till pid (eller processgruppen när pid < 0). Returnerar 0 eller -errno.
sys pipe=> Int IntSkapar en pipe i operativsystemet (__NR_pipe = 22) och returnerar (read_fd, write_fd) (eller (-1, -1) vid fel).
sys waitpidInt Int => Int IntVäntar på barnprocessen pid med options (0 = blockerande, 1 = WNOHANG) via __NR_wait4 = 61 och returnerar (ret_pid, exit_status) avkodat via WIFEXITED/WEXITSTATUS (0..255) och WIFSIGNALED (128 + WTERMSIG).
sys callInt Int Int Int Int Int Int => IntRått systemanrop på låg nivå enligt målplattformens ABI (nr, a1..a6) för OS-specifika drivrutiner. Skydda det med sys os / sys arch när det används.

3. Rekommenderat gränssnitt för .rglib-bibliotek (io.rglib och posix.rglib)

3.1 io.rglib — I/O-omslag på hög nivå med stöd för timeout

type IoResult = IoOk String | IoTimeout | IoEof | IoError Int

fn :: io read with timeout String Int     => IoResult
      io read with timeout path   wait_ms =
        with timeout wait_ms do
          -- Open non-blocking (0 + 2048 = O_RDONLY | O_NONBLOCK) so FIFO/device open never hangs
          fd = sys open path 2048 0
          io read poll step fd

fn :: io read poll step Int => IoResult
      io read poll step fd
        | fd < 0 = IoError fd
        | otherwise =
          -- timeout_ms = -1 automatically uses `sys remaining ms` from the active `with timeout` block
          ev = sys poll fd 1 (0 - 1)
          io read after poll fd ev

fn :: io read after poll Int Int => IoResult
      io read after poll fd  ev
        | ev == 0 =
          _ = sys close fd
          IoTimeout
        | ev < 0 =
          _ = sys close fd
          IoError ev
        | otherwise =
          chunk = sys read fd fd 65536
          _ = sys close fd
          io wrap chunk chunk

fn :: io wrap chunk String => IoResult
      io wrap chunk ""     =  IoEof
      io wrap chunk s      =  IoOk s

3.2 posix.rglib — Symboliska konstanter och processhjälpare

-- Normalized PAL Open Flags
fn :: o rdonly   => Int
      o rdonly   =  0

fn :: o wronly   => Int
      o wronly   =  1

fn :: o rdwr     => Int
      o rdwr     =  2

fn :: o creat    => Int
      o creat    =  64

fn :: o trunc    => Int
      o trunc    =  512

fn :: o append   => Int
      o append   =  1024

fn :: o nonblock => Int
      o nonblock =  2048

-- Normalized PAL Poll Events
fn :: poll in  => Int
      poll in  =  1

fn :: poll out => Int
      poll out =  4

fn :: poll err => Int
      poll err =  8

fn :: poll hup => Int
      poll hup =  16

-- Normalized Signals
fn :: sig int  => Int
      sig int  =  2

fn :: sig kill => Int
      sig kill =  9

fn :: sig term => Int
      sig term =  15

fn :: process exists Int => Bool
      process exists pid =  (sys kill pid 0) == 0

4. Bygga och distribuera .rglib- och .so-bibliotek

Kompilera vilken biblioteksmodul som helst utan att main behövs:

# Emit portable Ridgun library bundle (.rglib)
./bin/ridgunc build --lib src/main/ridgun/lib/io.rg -o target/io.rglib

# Emit native ELF64 shared object (.so)
./bin/ridgunc build --so src/main/ridgun/lib/io.rg -o target/libio.so

# Or via stable in a library project (`stable new --lib io`):
./bin/stable built lib