compiler/
lib/
scripts/
seed/
sublime/
test/
vim/
.gitignore
336 B
.gitsigners
112 B
LICENSE
1.1 KiB
Makefile
3.7 KiB
README
4.8 KiB
STYLE
2.5 KiB
std.lib
1.2 KiB
std.lib.test
347 B
README
raw
| 1 | |
| 2 | \ | / |
| 3 | - - |
| 4 | / | \ |
| 5 | |
| 6 | RADIANCE |
| 7 | |
| 8 | Radiance is a small statically-typed systems language designed for the Radiant[0] |
| 9 | computer system (https://radiant.computer). It currently targets RISC-V (RV64). |
| 10 | |
| 11 | The compiler is self-hosted: written in Radiance, it compiles to RISC-V and |
| 12 | runs inside a RISC-V emulator on x86-64 platforms. |
| 13 | |
| 14 | Currently, the Radiance compiler supports most of the R' language. See |
| 15 | https://radiant.computer/system/radiance/prime/ for more information on R'. |
| 16 | |
| 17 | [0]: https://radiant.computer |
| 18 | |
| 19 | REQUIREMENTS |
| 20 | |
| 21 | * Linux on x86-64 |
| 22 | * Make |
| 23 | * Radiant's RISC-V Emulator |
| 24 | (https://code.radiant.computer/emulator/) |
| 25 | |
| 26 | BUILDING |
| 27 | |
| 28 | The compiler is self-hosted, so building from source requires bootstrapping |
| 29 | from a seed binary. A known-good compiler is checked into the repository. |
| 30 | |
| 31 | The Radiant emulator is required to run the compiler and build process |
| 32 | on x86-64. The build process will look for it in $PATH, unless $RAD_EMULATOR |
| 33 | is set to its location: |
| 34 | |
| 35 | export RAD_EMULATOR=~/bin/emulator |
| 36 | |
| 37 | Then, build the compiler: |
| 38 | |
| 39 | make |
| 40 | |
| 41 | This uses the emulator to run the seed binary (`seed/radiance.rv64`) which |
| 42 | compiles the self-hosted compiler source to produce `bin/radiance.rv64.dev`. |
| 43 | |
| 44 | To update the seed to a new fixed point: |
| 45 | |
| 46 | make seed |
| 47 | |
| 48 | This iterates self-compilation stages until two consecutive stages produce |
| 49 | identical output, proving the compiler faithfully reproduces itself. See |
| 50 | `seed/README` for full details on the seed workflow, verification, and |
| 51 | how to handle breaking changes. |
| 52 | |
| 53 | USAGE |
| 54 | |
| 55 | Compile a Radiance program: |
| 56 | |
| 57 | emulator -run bin/radiance.rv64.dev \ |
| 58 | -pkg example -mod example.rad -o example.rv64 |
| 59 | |
| 60 | Run a compiled binary: |
| 61 | |
| 62 | emulator -run example.rv64 |
| 63 | |
| 64 | GENERICS |
| 65 | |
| 66 | Records, unions, and free functions declare ordered type or integer |
| 67 | parameters between `⟨` and `⟩`: |
| 68 | |
| 69 | union Maybe⟨T⟩ { None, Some(T) } |
| 70 | record Buffer⟨const N: u32⟩ { data: [u8; N] } |
| 71 | fn first⟨T⟩(left: T, right: T) -> T { return left; } |
| 72 | |
| 73 | Concrete data and function applications use the same syntax. |
| 74 | Every concrete application reachable at run time must be covered by an |
| 75 | explicit package-level monomorphization root and its dependency closure: |
| 76 | |
| 77 | instantiate Maybe⟨u32⟩, first⟨u32⟩; |
| 78 | |
| 79 | Rooted generic functions add generic callees and nested data applications to |
| 80 | the specialization closure. For declarations with only type parameters, |
| 81 | calls may omit the generic argument list when local parameter and result |
| 82 | evidence selects one already-rooted specialization; inference never creates |
| 83 | a root. Integer arguments are compile-time expressions. The compiler checks |
| 84 | each argument against its parameter's declared type. A declaration with |
| 85 | an integer parameter requires a complete argument list. |
| 86 | |
| 87 | Type parameters may have trait bounds. Calls through those bounds use |
| 88 | static instance dispatch: |
| 89 | |
| 90 | trait Less { fn (&Less) less(other: &Self) -> bool; } |
| 91 | fn minimum⟨T: Less⟩(a: T, b: T) -> T { |
| 92 | if a.less(&b) { return a; } |
| 93 | return b; |
| 94 | } |
| 95 | |
| 96 | `Self` is the concrete instance type in trait signatures. Opaque trait |
| 97 | objects remain dynamic. The compiler rejects traits whose `Self` usage is |
| 98 | not object-safe. `instance` declares a trait implementation. `instantiate` |
| 99 | requests generic monomorphization. |
| 100 | |
| 101 | Generic symbols follow ordinary module visibility. A root may reference an |
| 102 | exported template in another module by its qualified name: |
| 103 | |
| 104 | use containers; |
| 105 | instantiate containers::Maybe⟨u32⟩; |
| 106 | |
| 107 | Duplicate roots share one package-wide specialization. |
| 108 | |
| 109 | Unsupported by design: generic traits, instances, or methods; associated |
| 110 | types; overlapping instances; user-defined specialization; arbitrary |
| 111 | compile-time execution; inferred roots; and higher-kinded types. The compiler |
| 112 | diagnoses wrong arity or argument kind, unsatisfied or ambiguous bounds, |
| 113 | missing roots, incomplete or conflicting inference, recursive layout, |
| 114 | expanding dependency chains, and implementation-limit overflow. |
| 115 | |
| 116 | TESTING |
| 117 | |
| 118 | Run all tests: |
| 119 | |
| 120 | make test |
| 121 | |
| 122 | Individual test suites: |
| 123 | |
| 124 | make std-test # Standard library tests |
| 125 | make lower-test # IL lowering tests |
| 126 | make asm-test # RV64 code generation tests |
| 127 | |
| 128 | PROJECT STRUCTURE |
| 129 | |
| 130 | seed/ Seed compiler binary and update tooling |
| 131 | compiler/ Self-hosted compiler entry point |
| 132 | lib/std/ Standard library |
| 133 | lib/std/lang/ Compiler modules |
| 134 | lib/std/arch/ Architecture backends |
| 135 | test/ Test harnesses |
| 136 | scripts/ Utility scripts |
| 137 | vim/ Vim syntax files |
| 138 | |
| 139 | EDITOR SUPPORT |
| 140 | |
| 141 | Vim syntax files for Radiance (.rad) and RIL (.ril) are in the vim/ folder. |
| 142 | Copy them to ~/.vim/syntax/ for syntax highlighting. |
| 143 | |
| 144 | LICENSE |
| 145 | |
| 146 | Licensed under the MIT License, |
| 147 | Copyright (c) 2025-2026 Radiant Computer (https://radiant.computer) |