Skip to content
Ridgun
English

Ridgun

The language itself: a compiler that compiles itself, the stable project tool, the specification and the book

pal-and-system-libraries.md192 lines · 9.2 KBRaw
1# Ridgun — Platform Abstraction Layer (PAL) & System Libraries (`posix.rglib`, `io.rglib`) Specification
2
3This specification defines the contract between the **Ridgun Compiler (`ridgunc`)** and the **Ridgun System Libraries (`posix.rglib`, `io.rglib`, `unix-tools`)** across all supported and planned OS targets (`Linux`, `MacOS`, `Windows`) and CPU architectures (`X86_64`, `Arm64`).
4
5---
6
7## 1. Architecture Overview: 2-Layer PAL + Target Sum ADTs
8
9Ridgun avoids exposing raw Linux-only syscall numbers or OS-specific bitflags in portable libraries by splitting system interaction into two compiler layers plus strongly typed target ADTs:
10
111. **Pre-Declared Target Platform Sum ADTs (`sys os => SysOs`, `sys arch => SysArch`)**:
12 - Rather than returning untyped `String`s (which are prone to typos and cannot be checked by the typechecker), `ridgunc` pre-declares two extensible Sum ADTs:
13 ```ridgun
14 type SysOs = Linux | MacOS | Windows
15 type SysArch = X86_64 | Arm64
16 ```
17 - `sys os => SysOs` and `sys arch => SysArch` are resolved by the backend at compile time into zero-overhead `NLoadAdt0` constants (`Linux` / `X86_64` on `x86_64-linux`, `Linux` / `Arm64` on `arm64-linux`).
18 - Libraries can dispatch cleanly by **tabular pattern matching** on `SysOs` / `SysArch`, compare with `==` (`(sys os) == Linux`), or extend them for custom bare-metal/BSD targets via `expand type SysOs = FreeBSD | BareMetal` (`FR-COMP-005`).
19
202. **Layer 1 — Cross-Platform PAL Primitives (`sys open mode`, `sys open`, `sys close`, `sys read fd`, `sys write fd`, `sys poll`, `sys terminate`, `sys kill`, `sys call`)**:
21 - All flag masks and poll event masks passed to Layer 1 primitives use **Ridgun PAL Normalized Constants**.
22 - Each backend (`x86_64.rg` ELF64, `arm64.rg` ELF64, and future `Mach-O` macOS / `PE64` Windows backends) translates those normalized constants into the native OS kernel ABI (`openat`/`poll`/`kill` on Linux, `open`/`poll`/`kill` on macOS, `CreateFileW`/`WaitForSingleObject`/`WSAPoll`/`TerminateProcess` on Windows).
23 - Both natural-language space-separated syntax (`sys open mode path "r"`) and underscore-separated syntax (`sys open mode path "r"`) are accepted identically.
24
253. **Layer 2 — Declarative Execution Quotas (`with timeout <duration> do`)**:
26 - Integer literals support duration suffixes: `_ms` (`* 1`), `_s` (`* 1000`), and `_min` (`* 60000`).
27 - `with timeout 500_ms do <body>` (and combined `with region 64_KB, timeout 500_ms do <body>`) pushes a lexical deadline (`sys time ms + duration_ms`) onto the thread-local PAL deadline stack, clamping to any stricter outer deadline (`min(outer, new)`) and restoring the outer deadline on exit.
28 - Inside a `with timeout` block, `sys deadline ms => Int` returns the active epoch deadline (`0` if unbounded), `sys remaining ms => Int` returns the remaining milliseconds (`-1` if unbounded, `0` if expired), and `sys poll fd events -1` automatically clamps its wait time to `sys remaining ms`.
29
30---
31
32## 2. Compiler Built-In PAL Reference (`FR-COMP-007`)
33
34### 2.1 Target Platform Introspection
35
36| Primitive | Signature | Description |
37|---|---|---|
38| `sys os` | `=> SysOs` | Compile-time target operating system (`Linux \| MacOS \| Windows`). |
39| `sys arch` | `=> SysArch` | Compile-time target CPU architecture (`X86_64 \| Arm64`). |
40
41Example of idiomatic multi-OS dispatch in a `.rglib` library without `if/else` chains:
42
43```ridgun
44fn :: path separator SysOs => String
45 path separator Linux = "/"
46 path separator MacOS = "/"
47 path separator Windows = "\\"
48
49fn :: null device => String
50 null device = null device for (sys os)
51
52fn :: null device for SysOs => String
53 null device for Windows = "NUL"
54 null device for _ = "/dev/null"
55```
56
57### 2.2 Descriptor / Handle I/O & Readiness Polling
58
59| Primitive | Signature | Normalized PAL Contract |
60|---|---|---|
61| `sys open mode` | `String String => Int` | Opens `path` with portable mode string `"r"`, `"w"`, `"a"`, `"rw"`, `"w+"`, or `"a+"` (default permission `0644` / `420` when creating). Returns descriptor/handle `>= 0` or negative error code (`-errno`). |
62| `sys open` | `String Int Int => Int` | Opens `path` with Ridgun PAL normalized `flags` (`0` = read-only, `1` = write-only, `2` = read-write, `64` = create, `512` = truncate, `1024` = append, `2048` = non-blocking) and permission `mode` (e.g. `420` for `0644`). |
63| `sys close` | `Int => Int` | Closes `fd`/handle. Returns `0` on success or negative `-errno`. |
64| `sys read fd` | `Int Int => String` | Reads up to `max_bytes` from `fd`/handle (`0` = stdin, `1` = stdout, `2` = stderr, or opened file/pipe/FIFO). Returns `""` on EOF (`0` bytes) or error. |
65| `sys write fd` | `Int String => Int` | Writes `data` to `fd`/handle. Returns bytes written (`>= 0`) or negative `-errno`. |
66| `sys poll` | `Int Int Int => Int` | Polls `fd` for normalized `events` (`1` = `POLLIN` readable, `4` = `POLLOUT` writable, `8` = `POLLERR`, `16` = `POLLHUP`) with `timeout_ms` (`-1` = infinite or clamped to `sys remaining ms` when inside `with timeout`, `0` = non-blocking poll, `> 0` = max wait in ms). Returns `> 0` ready event bitmask, `0` on timeout, or `< 0` on `-errno`. |
67
68### 2.3 Clocks, Deadlines, Signals & Low-Level Escape Hatch
69
70| Primitive | Signature | Normalized PAL Contract |
71|---|---|---|
72| `sys time ms` | `=> Int` | Monotonic millisecond clock (`CLOCK_MONOTONIC`). |
73| `sys sleep ms` | `Int => ()` | Sleeps for `ms` milliseconds (`nanosleep` / `Sleep`). |
74| `sys deadline ms` | `=> Int` | Active lexical deadline in monotonic ms (`0` when outside `with timeout`). |
75| `sys remaining ms` | `=> Int` | Milliseconds remaining until active lexical deadline (`-1` when outside `with timeout`, `0` when expired). |
76| `sys getpid` | `=> Int` | Current process ID (`> 0`). |
77| `sys terminate` | `Int Bool => Int` | Cross-platform process termination: `force = False` sends graceful termination (`SIGTERM` on POSIX), `force = True` forces immediate termination (`SIGKILL` on POSIX, `TerminateProcess` on Windows). Returns `0` or `-errno`. |
78| `sys kill` | `Int Int => Int` | Sends normalized signal (`0` = existence probe, `2` = `SIGINT`, `9` = `SIGKILL`, `15` = `SIGTERM`) to `pid` (or process group when `pid < 0`). Returns `0` or `-errno`. |
79| `sys pipe` | `=> Int Int` | Creates an OS pipe (`__NR_pipe = 22`) and returns `(read_fd, write_fd)` (or `(-1, -1)` on error). |
80| `sys waitpid` | `Int Int => Int Int` | Waits for child process `pid` with `options` (`0` = blocking, `1` = `WNOHANG`) via `__NR_wait4 = 61` and returns `(ret_pid, exit_status)` decoded via `WIFEXITED`/`WEXITSTATUS` (`0..255`) and `WIFSIGNALED` (`128 + WTERMSIG`). |
81| `sys call` | `Int Int... => Int` | Low-level target-ABI raw syscall (`nr` plus `0..6` arguments `a1..a6`) for OS-specific drivers. Guard with `sys os` / `sys arch` when used. |
82
83---
84
85## 3. Recommended `.rglib` Library Surface (`io.rglib` & `posix.rglib`)
86
87### 3.1 `io.rglib` — High-Level Timeout-Aware I/O Wrappers
88
89```ridgun
90type IoResult = IoOk String | IoTimeout | IoEof | IoError Int
91
92fn :: io read with timeout String Int => IoResult
93 io read with timeout path wait_ms =
94 with timeout wait_ms do
95 -- Open non-blocking (0 + 2048 = O_RDONLY | O_NONBLOCK) so FIFO/device open never hangs
96 fd = sys open path 2048 0
97 io read poll step fd
98
99fn :: io read poll step Int => IoResult
100 io read poll step fd
101 | fd < 0 = IoError fd
102 | otherwise =
103 -- timeout_ms = -1 automatically uses `sys remaining ms` from the active `with timeout` block
104 ev = sys poll fd 1 (0 - 1)
105 io read after poll fd ev
106
107fn :: io read after poll Int Int => IoResult
108 io read after poll fd ev
109 | ev == 0 =
110 sys close fd -> ()
111 IoTimeout
112 | ev < 0 =
113 sys close fd -> ()
114 IoError ev
115 | otherwise =
116 chunk = sys read fd fd 65536
117 sys close fd -> ()
118 io wrap chunk chunk
119
120fn :: io wrap chunk String => IoResult
121 io wrap chunk "" = IoEof
122 io wrap chunk s = IoOk s
123```
124
125### 3.2 `posix.rglib` — Symbolic Constants & Process Helpers
126
127```ridgun
128-- Normalized PAL Open Flags
129fn :: o rdonly => Int
130 o rdonly = 0
131
132fn :: o wronly => Int
133 o wronly = 1
134
135fn :: o rdwr => Int
136 o rdwr = 2
137
138fn :: o creat => Int
139 o creat = 64
140
141fn :: o trunc => Int
142 o trunc = 512
143
144fn :: o append => Int
145 o append = 1024
146
147fn :: o nonblock => Int
148 o nonblock = 2048
149
150-- Normalized PAL Poll Events
151fn :: poll in => Int
152 poll in = 1
153
154fn :: poll out => Int
155 poll out = 4
156
157fn :: poll err => Int
158 poll err = 8
159
160fn :: poll hup => Int
161 poll hup = 16
162
163-- Normalized Signals
164fn :: sig int => Int
165 sig int = 2
166
167fn :: sig kill => Int
168 sig kill = 9
169
170fn :: sig term => Int
171 sig term = 15
172
173fn :: process exists Int => Bool
174 process exists pid = (sys kill pid 0) == 0
175```
176
177---
178
179## 4. Building & Distributing `.rglib` and `.so` Libraries
180
181Compile any library module without requiring `main`:
182
183```bash
184# Emit portable Ridgun library bundle (.rglib)
185./bin/ridgunc build --lib src/main/ridgun/lib/io.rg -o target/io.rglib
186
187# Emit native ELF64 shared object (.so)
188./bin/ridgunc build --so src/main/ridgun/lib/io.rg -o target/libio.so
189
190# Or via stable in a library project (`stable new --lib io`):
191./bin/stable built lib
192```