Referencia
Ridgun — Especificación de la capa de abstracción de la plataforma (PAL) y de las librerías de sistema (posix.rglib, io.rglib)
Esta especificación define el contrato entre el compilador de Ridgun (ridgunc v0.9.5) y las librerías de sistema de Ridgun (posix.rglib, io.rglib, unix-tools) en todos los sistemas operativos de destino admitidos y previstos (Linux, MacOS, Windows) y en todas las arquitecturas de CPU (X86_64, Arm64).
1. Visión general de la arquitectura: PAL de 2 capas + ADT suma de destino
Ridgun evita exponer en las librerías portables números de syscall exclusivos de Linux o máscaras de bits específicas de un sistema operativo. Para ello divide la interacción con el sistema en dos capas del compilador, más unos ADT de destino con tipado fuerte:
- ADT suma de plataforma de destino predeclarados (
sys os => SysOs,sys arch => SysArch):
- En lugar de devolver valores
Stringsin tipo (propensos a erratas y que el verificador de tipos no puede comprobar),ridguncpredeclara dos ADT suma extensibles:
type SysOs = Linux | MacOS | Windows
type SysArch = X86_64 | Arm64
sys os => SysOsysys arch => SysArchlos resuelve el backend en tiempo de compilación a constantesNLoadAdt0sin sobrecoste (Linux/X86_64enx86_64-linux,Linux/Arm64enarm64-linux).- Las librerías pueden despachar limpiamente con pattern matching en forma de tabla sobre
SysOs/SysArch, comparar con==((sys os) == Linux) o extenderlos para destinos BSD o bare-metal propios conexpand type SysOs = FreeBSD | BareMetal(FR-COMP-005).
- 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 las máscaras de flags y de eventos de sondeo que se pasan a las primitivas de la capa 1 usan las constantes normalizadas de la PAL de Ridgun.
- Cada backend (
x86_64.rgELF64,arm64.rgELF64 y los futuros backendsMach-Opara macOS yPE64para Windows) traduce esas constantes normalizadas a la ABI nativa del núcleo del sistema operativo (openat/poll/killen Linux,open/poll/killen macOS,CreateFileW/WaitForSingleObject/WSAPoll/TerminateProcessen Windows). - Se aceptan por igual la sintaxis natural separada por espacios (
sys open mode path "r") y la separada por guiones bajos (sys_open_mode path "r").
- Capa 2 — Cuotas de ejecución declarativas (
with timeout <duration> do):
- Los literales enteros admiten sufijos de duración:
_ms(* 1),_s(* 1000) y_min(* 60000). with timeout 500_ms do <body>(y la forma combinadawith region 64_KB, timeout 500_ms do <body>) apila un plazo léxico (sys time ms + duration_ms) en la pila de plazos PAL local del hilo, lo limita a cualquier plazo exterior más estricto (min(outer, new)) y restaura el plazo exterior al salir.- Dentro de un bloque
with timeout,sys deadline ms => Intdevuelve el plazo activo en tiempo de época (0si no hay límite),sys remaining ms => Intdevuelve los milisegundos restantes (-1si no hay límite,0si ha vencido) ysys poll fd events -1limita automáticamente su tiempo de espera asys remaining ms.
2. Referencia de la PAL nativa del compilador (FR-COMP-007)
2.1 Introspección de la plataforma de destino
| Primitiva | Firma | Descripción |
|---|---|---|
sys os | => SysOs | Sistema operativo de destino en tiempo de compilación (Linux | MacOS | Windows). |
sys arch | => SysArch | Arquitectura de CPU de destino en tiempo de compilación (X86_64 | Arm64). |
Ejemplo de despacho idiomático entre varios sistemas operativos en una librería .rglib, sin cadenas 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 descriptor o handle y sondeo de disponibilidad
| Primitiva | Firma | Contrato PAL normalizado |
|---|---|---|
sys open mode | String String => Int | Abre path con la cadena de modo portable "r", "w", "a", "rw", "w+" o "a+" (permiso por defecto 0644 / 420 al crear). Devuelve un descriptor o handle >= 0 o un código de error negativo (-errno). |
sys open | String Int Int => Int | Abre path con los flags normalizados de la PAL de Ridgun (0 = solo lectura, 1 = solo escritura, 2 = lectura y escritura, 64 = crear, 512 = truncar, 1024 = añadir al final, 2048 = no bloqueante) y el permiso mode (por ejemplo, 420 para 0644). |
sys close | Int => Int | Cierra fd o el handle. Devuelve 0 si tiene éxito o el valor negativo -errno. |
sys read fd | Int Int => String | Lee hasta max_bytes de fd o del handle (0 = stdin, 1 = stdout, 2 = stderr, o un archivo, tubería o FIFO abierto). Devuelve "" en EOF (0 bytes) o si hay un error. |
sys write fd | Int String => Int | Escribe data en fd o en el handle. Devuelve los bytes escritos (>= 0) o el valor negativo -errno. |
sys poll | Int Int Int => Int | Sondea fd en busca de los events normalizados (1 = POLLIN legible, 4 = POLLOUT escribible, 8 = POLLERR, 16 = POLLHUP) con timeout_ms (-1 = infinito, o limitado a sys remaining ms dentro de with timeout; 0 = sondeo no bloqueante; > 0 = espera máxima en ms). Devuelve > 0 con la máscara de bits de eventos listos, 0 si se agota el tiempo o < 0 con -errno. |
2.3 Relojes, plazos, señales y vía de escape de bajo nivel
| Primitiva | Firma | Contrato PAL normalizado |
|---|---|---|
sys time ms | => Int | Reloj monotónico en milisegundos (CLOCK_MONOTONIC). |
sys sleep ms | Int => () | Duerme durante ms milisegundos (nanosleep / Sleep). |
sys deadline ms | => Int | Plazo léxico activo en ms monotónicos (0 fuera de with timeout). |
sys remaining ms | => Int | Milisegundos que quedan hasta el plazo léxico activo (-1 fuera de with timeout, 0 si ha vencido). |
sys getpid | => Int | ID del proceso actual (> 0). |
sys terminate | Int Bool => Int | Terminación de procesos multiplataforma: force = False envía una terminación ordenada (SIGTERM en POSIX) y force = True fuerza la terminación inmediata (SIGKILL en POSIX, TerminateProcess en Windows). Devuelve 0 o -errno. |
sys kill | Int Int => Int | Envía una señal normalizada (0 = comprobación de existencia, 2 = SIGINT, 9 = SIGKILL, 15 = SIGTERM) a pid (o al grupo de procesos si pid < 0). Devuelve 0 o -errno. |
sys pipe | => Int Int | Crea una tubería del sistema operativo (__NR_pipe = 22) y devuelve (read_fd, write_fd) (o (-1, -1) si hay un error). |
sys waitpid | Int Int => Int Int | Espera al proceso hijo pid con options (0 = bloqueante, 1 = WNOHANG) mediante __NR_wait4 = 61 y devuelve (ret_pid, exit_status), decodificado con WIFEXITED/WEXITSTATUS (0..255) y WIFSIGNALED (128 + WTERMSIG). |
sys call | Int Int Int Int Int Int Int => Int | Syscall en crudo de bajo nivel según la ABI de destino (nr, a1..a6) para controladores específicos de un sistema operativo. Si la usas, protégela con sys os / sys arch. |
3. Superficie recomendada de las librerías .rglib (io.rglib y posix.rglib)
3.1 io.rglib — Envoltorios de E/S de alto nivel que respetan los plazos
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 y utilidades 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. Compilar y distribuir librerías .rglib y .so
Compila cualquier módulo de librería sin necesidad 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