Saltar ao contido
Ridgun
Galego

Referencia

Ridgun — Especificación da capa de abstracción da plataforma (PAL) e das bibliotecas do sistema (posix.rglib, io.rglib)

Esta especificación define o contrato entre o compilador de Ridgun (ridgunc v0.9.5) e as bibliotecas do sistema de Ridgun (posix.rglib, io.rglib, unix-tools) en todos os sistemas operativos de destino admitidos e previstos (Linux, MacOS, Windows) e en todas as arquitecturas de CPU (X86_64, Arm64).


1. Visión xeral da arquitectura: PAL de 2 capas + ADT suma de destino

Ridgun evita expoñer nas bibliotecas portables números de chamada ao sistema exclusivos de Linux ou indicadores de bits propios de cada sistema operativo. Para iso divide a interacción co sistema en dúas capas do compilador, máis uns ADT de destino con tipado forte:

  1. ADT suma predeclarados da plataforma de destino (sys os => SysOs, sys arch => SysArch):
  • En vez de devolver Strings sen tipo (propensos a erros tipográficos e que o verificador de tipos non pode comprobar), ridgunc predeclara dous ADT suma extensibles:
     type SysOs   = Linux | MacOS | Windows
     type SysArch = X86_64 | Arm64
  • O backend resolve sys os => SysOs e sys arch => SysArch en tempo de compilación como constantes NLoadAdt0 sen sobrecusto (Linux / X86_64 en x86_64-linux, Linux / Arm64 en arm64-linux).
  • As bibliotecas poden despachar limpamente con pattern matching tabular sobre SysOs / SysArch, comparar con == ((sys os) == Linux) ou estendelos para destinos bare-metal ou BSD propios mediante expand type SysOs = FreeBSD | BareMetal (FR-COMP-005).
  1. Capa 1 — Primitivas PAL multiplataforma (sys open mode, sys open, sys close, sys read fd, sys write fd, sys poll, sys terminate, sys kill, sys call):
  • Todas as máscaras de indicadores e de eventos de sondaxe que se pasan ás primitivas da Capa 1 usan constantes normalizadas da PAL de Ridgun.
  • Cada backend (x86_64.rg ELF64, arm64.rg ELF64 e os futuros backends Mach-O para macOS e PE64 para Windows) traduce esas constantes normalizadas á ABI nativa do núcleo do sistema operativo (openat/poll/kill en Linux, open/poll/kill en macOS, CreateFileW/WaitForSingleObject/WSAPoll/TerminateProcess en Windows).
  • Acéptanse por igual a sintaxe de linguaxe natural separada por espazos (sys open mode path "r") e a sintaxe separada por guións baixos (sys_open_mode path "r").
  1. Capa 2 — Cotas de execución declarativas (with timeout <duration> do):
  • Os literais enteiros admiten sufixos de duración: _ms (* 1), _s (* 1000) e _min (* 60000).
  • with timeout 500_ms do <body> (e a forma combinada with region 64_KB, timeout 500_ms do <body>) pon un prazo léxico (sys time ms + duration_ms) na pila de prazos da PAL local ao fío, axústao a calquera prazo exterior máis estrito (min(outer, new)) e restaura o prazo exterior ao saír.
  • Dentro dun bloque with timeout, sys deadline ms => Int devolve o prazo activo en tempo absoluto (0 se non hai límite), sys remaining ms => Int devolve os milisegundos que quedan (-1 se non hai límite, 0 se xa venceu) e sys poll fd events -1 limita automaticamente o seu tempo de espera a sys remaining ms.

2. Referencia das primitivas PAL integradas no compilador (FR-COMP-007)

2.1 Introspección da plataforma de destino

PrimitivaSinaturaDescrición
sys os=> SysOsSistema operativo de destino en tempo de compilación (Linux | MacOS | Windows).
sys arch=> SysArchArquitectura de CPU de destino en tempo de compilación (X86_64 | Arm64).

Exemplo de despacho idiomático para varios sistemas operativos nunha biblioteca .rglib, sen cadeas de if/else:

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 E/S por descritor ou handle e sondaxe de dispoñibilidade

PrimitivaSinaturaContrato normalizado da PAL
sys open modeString String => IntAbre path co modo portable "r", "w", "a", "rw", "w+" ou "a+" (permiso predeterminado 0644 / 420 ao crear). Devolve un descritor ou handle >= 0 ou un código de erro negativo (-errno).
sys openString Int Int => IntAbre path cos flags normalizados da PAL de Ridgun (0 = só lectura, 1 = só escritura, 2 = lectura e escritura, 64 = crear, 512 = truncar, 1024 = engadir, 2048 = non bloqueante) e o permiso mode (por exemplo, 420 para 0644).
sys closeInt => IntPecha fd ou o handle. Devolve 0 se ten éxito ou -errno negativo.
sys read fdInt Int => StringLe ata max_bytes de fd ou do handle (0 = stdin, 1 = stdout, 2 = stderr, ou un ficheiro, tubo ou FIFO aberto). Devolve "" en EOF (0 bytes) ou en caso de erro.
sys write fdInt String => IntEscribe data en fd ou no handle. Devolve os bytes escritos (>= 0) ou -errno negativo.
sys pollInt Int Int => IntSonda fd para os events normalizados (1 = POLLIN lexible, 4 = POLLOUT escribible, 8 = POLLERR, 16 = POLLHUP) con timeout_ms (-1 = infinito ou limitado a sys remaining ms dentro de with timeout, 0 = sondaxe non bloqueante, > 0 = espera máxima en ms). Devolve unha máscara de bits de eventos listos > 0, 0 se se esgota o tempo ou < 0 con -errno.

2.3 Reloxos, prazos, sinais e vía de escape de baixo nivel

PrimitivaSinaturaContrato normalizado da PAL
sys time ms=> IntReloxo monótono en milisegundos (CLOCK_MONOTONIC).
sys sleep msInt => ()Dorme durante ms milisegundos (nanosleep / Sleep).
sys deadline ms=> IntPrazo léxico activo en ms monótonos (0 fóra de with timeout).
sys remaining ms=> IntMilisegundos que quedan ata o prazo léxico activo (-1 fóra de with timeout, 0 se xa venceu).
sys getpid=> IntID do proceso actual (> 0).
sys terminateInt Bool => IntTerminación de procesos multiplataforma: force = False envía unha terminación ordenada (SIGTERM en POSIX) e force = True forza a terminación inmediata (SIGKILL en POSIX, TerminateProcess en Windows). Devolve 0 ou -errno.
sys killInt Int => IntEnvía un sinal normalizado (0 = proba de existencia, 2 = SIGINT, 9 = SIGKILL, 15 = SIGTERM) a pid (ou ao grupo de procesos cando pid < 0). Devolve 0 ou -errno.
sys pipe=> Int IntCrea un tubo do sistema operativo (__NR_pipe = 22) e devolve (read_fd, write_fd) (ou (-1, -1) en caso de erro).
sys waitpidInt Int => Int IntAgarda polo proceso fillo pid con options (0 = bloqueante, 1 = WNOHANG) mediante __NR_wait4 = 61 e devolve (ret_pid, exit_status), descodificado con WIFEXITED/WEXITSTATUS (0..255) e WIFSIGNALED (128 + WTERMSIG).
sys callInt Int Int Int Int Int Int => IntChamada ao sistema en cru e de baixo nivel segundo a ABI de destino (nr, a1..a6) para controladores específicos de cada sistema operativo. Protexea con sys os / sys arch cando a uses.

3. Superficie recomendada das bibliotecas .rglib (io.rglib e posix.rglib)

3.1 io.rglib: envoltorios de E/S de alto nivel que teñen en conta o tempo límite

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: constantes simbólicas e funcións auxiliares de procesos

-- 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. Construción e distribución de bibliotecas .rglib e .so

Compila calquera módulo de biblioteca sen necesidade de main:

# 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