Progress
This page is the project's status board. Update it in the same commit as the work.
Milestones
| Version | Theme | Status |
|---|---|---|
| 0.1 | Compiler to static ELF, std (sys/io/net/http), web on :8001 | done |
| 0.2 | Hardening from the adversarial review (23 tasks) | done |
| 0.3 | Language: structs, enums + match, &T, function values, u8/u32, bitwise ops; second review | done |
| 0.4 | Language: slices returned from parameters, [N]T arrays, struct literals, for | next |
| 0.5 | Memory: regions/arenas, linear file descriptors | planned |
| 0.6 | Server: epoll event loop, sendfile | planned |
| 0.7 | HTTPS: crypto + TLS 1.3 written in lpp | planned |
Done
- ☑ Lexer, parser, one-pass type check and x86-64 codegen
- ☑ Static ELF64 writer: no assembler, linker or libc
- ☑ Bounds-checked indexing and slicing, zeroed memory, no escaping slices
- ☑
trustedstd module as the only place with raw syscalls - ☑ Dead-code elimination (only code reachable from
main) - ☑
lpp file.lppruns like a script,lpp buildwrites a binary, shebang support - ☑
argc()/arg(i),copyintrinsic - ☑ HTTP server, forked workers, static file serving
- ☑ Test suite: examples, runtime traps, rejected unsafe programs, live web routes
- ☑ Socket read/write timeouts (5 s), so an idle connection cannot hold a worker
- ☑ Files streamed in 16 KB chunks: site worker RSS 288 KB → ~70 KB
- ☑ Live memory panel on the home page: HTML+CSS generated by lpp per request, no JavaScript
- ☑ This site, served by an lpp binary on https://lpp.olibuijr.com (2026-10-04)
Adversarial review (2026-10-04)
An independent review filed 23 tasks. Adopted and done:
- ☑ Signed division overflow defined (
MIN / -1wraps,MIN % -1= 0); separate trap messages - ☑
put,put_int,parse_intcorrect over the whole int range - ☑
copyhas memmove semantics - ☑ Every function is type-checked, even if never called; duplicate parameters and locals rejected
- ☑ Bounded arrays, frames, source size, module count and nesting; page-probed stack growth
- ☑
trustedallowed only instd/sys.lpp - ☑ Per-user, owner-checked run cache; exclusive temp files; verified cache hits
- ☑ Static files confined by the kernel (
openat2), regular files only, length-bounded streaming - ☑ HTTP requests read across fragments; 400/408/431 handling; HEAD without body; header injection refused
- ☑ Errors kept as negative errno; EINTR retries; accept back-off; lingering close
- ☑ Workers capped at 64, die with the parent, reaped by the kernel
- ☑ Literal interning, short immediates, traps emitted only when used (
exit256 → 191 bytes) - ☑
lpp check, strict CLI arguments,--helpexits 0 - ☑ Test runner with exact exits and diagnostics: 54 checks, including byte-by-byte request fragmentation
- ☑
make bench: reproducible baselines inbench/results/
Moved to the roadmap: cache before compiling, stack-slot reuse, an optimizing code generator, compiler allocation work, an epoll event loop.
Second review (2026-10-04)
18 more tasks (024–041), all adopted and done:
- ☑ Depth limits on the real AST (flat sums, postfix chains, else-if chains); compiler on a 64 MiB-stack thread
- ☑
lpp buildnever overwrites a source file (extensionless input or any used module) - ☑ Output and cache modes set explicitly, so umask 0111 still gives runnable binaries
- ☑
put_le/le_u64round-trip negative numbers;c_pathalways NUL-terminates;sys_socketadds CLOEXEC idempotently - ☑ Bounded lingering close (absolute 1 s), every blocking read/send bounded by the time left
- ☑ Header validation before dispatch (Host, names, control bytes, Content-Length, Transfer-Encoding)
- ☑ 204/304 carry no body or Content-Length
- ☑ Check pass keeps one function's code at a time (4,000-function file checks in 31 ms)
- ☑ HEAD never touches the 16 KiB body-chunk stack pages
- ☑ Benchmark: compiler RSS from the compiler itself (
LPP_STATS), responses validated, provenance recorded,--self-test - ☑ Timeout tests run against a 1 s head timeout with matching client budgets
- ☑ Explicit
LPP_STDnever falls back;--works for build, check and run - ☑ SIGPIPE ignored: writes to a closed pipe return -32
0.3 language
- ☑ Structs (nested, array fields, u8/u32 fields, copy semantics)
- ☑ Enums with payloads,
matchon enums and ints, with exhaustiveness checks - ☑
&Treference parameters with the no-slice-through-reference rule - ☑ Function values,
fn(...)types, calls through variables and fields - ☑ Bitwise operators
& | ^ << >> ~,\xNNescapes, full-range hex literals - ☑
file:line:colerrors with the source line and a caret - ☑ HTTP handler API:
http_serve(port, workers, handler),Requeststruct,HttpServerconfig
Next up
- ☐ return slices derived from parameters
- ☐
[N]Tarrays, struct literals,forloops
Numbers
Measured with make bench on an i7-10700K, Linux 7.2. Results are in bench/results/.
| What | Value |
|---|---|
examples/exit.lpp binary | 247 bytes (includes the SIGPIPE setup) |
examples/web.lpp binary | 27 KB |
| Site server binary | 45 KB |
| Build time (web example) | 3.3 ms |
| Compiler peak RSS | 2.7–3.6 MB (measured inside the compiler) |
| Web, 1 worker, idle | 52 KB PSS |
| Web, 4 workers, after load | 88 KB PSS in total |
| Web, 4 workers, 8 clients | ~46k valid req/s, p50 85 µs, p99 123 µs (Python client; may be client-bound) |