Saltar para o conteúdo
Ridgun
Português

Referência

Ridgun — Especificação da Camada de Abstração da Plataforma (PAL) e das Bibliotecas de Sistema (posix.rglib, io.rglib)

Esta especificação define o contrato entre o compilador do Ridgun (ridgunc v0.9.5) e as bibliotecas de sistema do Ridgun (posix.rglib, io.rglib, unix-tools) em todos os sistemas operativos alvo, suportados e planeados (Linux, MacOS, Windows), e em todas as arquiteturas de CPU (X86_64, Arm64).


1. Visão geral da arquitetura: PAL de 2 camadas + ADTs soma de plataforma alvo

O Ridgun evita expor em bibliotecas portáteis números de chamadas ao sistema exclusivos do Linux ou máscaras de bits específicas de cada sistema operativo. Para isso, divide a interação com o sistema em duas camadas do compilador, mais ADTs de plataforma alvo com tipos fortes:

  1. ADTs soma de plataforma alvo pré-declarados (sys os => SysOs, sys arch => SysArch):
  • Em vez de devolver Strings sem tipo (sujeitas a gralhas e que o verificador de tipos não consegue validar), o ridgunc pré-declara dois ADTs soma extensíveis:
     type SysOs   = Linux | MacOS | Windows
     type SysArch = X86_64 | Arm64
  • sys os => SysOs e sys arch => SysArch são resolvidos pelo backend em tempo de compilação como constantes NLoadAdt0 sem sobrecarga (Linux / X86_64 em x86_64-linux, Linux / Arm64 em arm64-linux).
  • As bibliotecas podem despachar de forma limpa por pattern matching tabular sobre SysOs / SysArch, comparar com == ((sys os) == Linux) ou estendê-los para alvos BSD ou bare-metal próprios com expand type SysOs = FreeBSD | BareMetal (FR-COMP-005).
  1. Camada 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 flags e de eventos de poll passadas às primitivas da Camada 1 usam as constantes normalizadas da PAL do Ridgun.
  • Cada backend (x86_64.rg ELF64, arm64.rg ELF64 e os futuros backends Mach-O para macOS e PE64 para Windows) traduz essas constantes normalizadas para a ABI nativa do kernel do sistema operativo (openat/poll/kill no Linux, open/poll/kill no macOS, CreateFileW/WaitForSingleObject/WSAPoll/TerminateProcess no Windows).
  • A sintaxe em linguagem natural separada por espaços (sys open mode path "r") e a sintaxe separada por sublinhados (sys_open_mode path "r") são aceites de forma idêntica.
  1. Camada 2 — Quotas de execução declarativas (with timeout <duration> do):
  • Os literais inteiros aceitam sufixos de duração: _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>) coloca um prazo léxico (sys time ms + duration_ms) na pilha de prazos da PAL local à thread, limita-o a qualquer prazo exterior mais restrito (min(outer, new)) e repõe o prazo exterior à saída.
  • Dentro de um bloco with timeout, sys deadline ms => Int devolve o prazo ativo, em tempo epoch (0 se não houver limite), sys remaining ms => Int devolve os milissegundos restantes (-1 se não houver limite, 0 se tiver expirado) e sys poll fd events -1 limita automaticamente o tempo de espera a sys remaining ms.

2. Referência das primitivas PAL nativas do compilador (FR-COMP-007)

2.1 Introspeção da plataforma alvo

PrimitivaAssinaturaDescrição
sys os=> SysOsSistema operativo alvo em tempo de compilação (Linux | MacOS | Windows).
sys arch=> SysArchArquitetura de CPU alvo em tempo de compilação (X86_64 | Arm64).

Exemplo de despacho idiomático para vários sistemas operativos numa biblioteca .rglib, sem cadeias 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 espera por disponibilidade

PrimitivaAssinaturaContrato normalizado da PAL
sys open modeString String => IntAbre path com a cadeia de modo portátil "r", "w", "a", "rw", "w+" ou "a+" (permissão por omissão 0644 / 420 ao criar). Devolve um descritor ou handle >= 0 ou um código de erro negativo (-errno).
sys openString Int Int => IntAbre path com as flags normalizadas da PAL do Ridgun (0 = só leitura, 1 = só escrita, 2 = leitura e escrita, 64 = criar, 512 = truncar, 1024 = acrescentar, 2048 = não bloqueante) e a permissão mode (por exemplo, 420 para 0644).
sys closeInt => IntFecha fd ou o handle. Devolve 0 em caso de sucesso ou um -errno negativo.
sys read fdInt Int => StringLê até max_bytes de fd ou do handle (0 = stdin, 1 = stdout, 2 = stderr, ou um ficheiro, pipe ou FIFO aberto). Devolve "" em EOF (0 bytes) ou em caso de erro.
sys write fdInt String => IntEscreve data em fd ou no handle. Devolve os bytes escritos (>= 0) ou um -errno negativo.
sys pollInt Int Int => IntConsulta fd para os events normalizados (1 = POLLIN legível, 4 = POLLOUT gravável, 8 = POLLERR, 16 = POLLHUP) com timeout_ms (-1 = infinito ou limitado a sys remaining ms dentro de with timeout, 0 = consulta não bloqueante, > 0 = espera máxima em ms). Devolve uma máscara de bits > 0 com os eventos prontos, 0 se o tempo limite expirar ou < 0 com -errno.

2.3 Relógios, prazos, sinais e via de escape de baixo nível

PrimitivaAssinaturaContrato normalizado da PAL
sys time ms=> IntRelógio monotónico em milissegundos (CLOCK_MONOTONIC).
sys sleep msInt => ()Dorme durante ms milissegundos (nanosleep / Sleep).
sys deadline ms=> IntPrazo léxico ativo em ms monotónicos (0 fora de with timeout).
sys remaining ms=> IntMilissegundos que faltam até ao prazo léxico ativo (-1 fora de with timeout, 0 se tiver expirado).
sys getpid=> IntID do processo atual (> 0).
sys terminateInt Bool => IntTerminação de processos multiplataforma: force = False envia um pedido de terminação ordenada (SIGTERM em POSIX), force = True força a terminação imediata (SIGKILL em POSIX, TerminateProcess no Windows). Devolve 0 ou -errno.
sys killInt Int => IntEnvia um sinal normalizado (0 = teste de existência, 2 = SIGINT, 9 = SIGKILL, 15 = SIGTERM) a pid (ou ao grupo de processos quando pid < 0). Devolve 0 ou -errno.
sys pipe=> Int IntCria um pipe do sistema operativo (__NR_pipe = 22) e devolve (read_fd, write_fd) (ou (-1, -1) em caso de erro).
sys waitpidInt Int => Int IntEspera pelo processo filho pid com options (0 = bloqueante, 1 = WNOHANG) através de __NR_wait4 = 61 e devolve (ret_pid, exit_status) descodificado com WIFEXITED/WEXITSTATUS (0..255) e WIFSIGNALED (128 + WTERMSIG).
sys callInt Int Int Int Int Int Int => IntChamada ao sistema direta de baixo nível, na ABI do alvo (nr, a1..a6), para controladores específicos de um sistema operativo. Ao usá-la, proteja-a com sys os / sys arch.

3. Superfície recomendada para as bibliotecas .rglib (io.rglib e posix.rglib)

3.1 io.rglib — Funções de E/S de alto nível que respeitam o tempo limite

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 funções auxiliares de processos

-- 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 e distribuir bibliotecas .rglib e .so

Compile qualquer módulo de biblioteca sem precisar 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