uor_foundation_macros/lib.rs
1//! Proc macro crate for the UOR Foundation.
2//!
3//! Provides the `uor!` macro (since v0.2.0) and the v0.2.1 ergonomics
4//! macros: `uor_ground!`, `#[derive(ConstrainedType)]`, `#[derive(CompileUnit)]`,
5//! and the `#[uor_grounded]` attribute. The v0.2.1 macros wire downstream code
6//! into the foundation's sealed-constructor minting path so the consumer-facing
7//! one-liners in `uor_foundation::enforcement::prelude` work end-to-end at
8//! compile time.
9//!
10//! # Usage
11//!
12//! ```rust,ignore
13//! use uor_foundation::uor;
14//!
15//! // Type declaration (named-argument constraint syntax)
16//! let pixel = uor! { type Pixel { ResidueConstraint(modulus: 256, residue: 255); } };
17//!
18//! // Term expression
19//! let sum = uor! { add(mul(3, 5), 7) };
20//!
21//! // Assertion (ground — checked at compile time)
22//! uor! { assert add(1, 2) = 3; };
23//! ```
24
25#![deny(
26 clippy::unwrap_used,
27 clippy::expect_used,
28 clippy::panic,
29 missing_docs,
30 clippy::missing_errors_doc
31)]
32
33mod address;
34mod codegen;
35mod conformance_parser;
36mod derives;
37mod generated;
38mod lexer;
39mod parser;
40mod surface;
41
42use proc_macro::TokenStream;
43
44/// The UOR term language DSL macro.
45///
46/// Parses EBNF surface syntax at compile time and produces typed `Term` ASTs
47/// in the `uor_foundation::enforcement` module. The macro handles:
48///
49/// - **Term expressions**: `add(mul(3, 5), 7)` — operation applications
50/// - **Type declarations**: `type Pixel { ResidueConstraint(modulus: 256, residue: 255); }` — constrained types
51/// - **Bindings**: `let x : Pixel = add(0, 0);` — named term bindings
52/// - **Assertions**: `assert lhs = rhs;` — ground assertions checked at compile time
53/// - **Effect declarations**: `effect Name { target: {0,1}; delta: 0; commutes: true; }` — generic props
54/// - **Boundary declarations**: `source name : Type via grounding;`
55/// - **Quantum literals**: `42@Q7` — level-annotated integers
56/// - **Lift/Project**: `lift(x, Q3)`, `project(y, Q0)` — level transitions
57/// - **Match**: `match x { pred => expr; otherwise => expr; }`
58/// - **Recursion**: `recurse f(n) measure n base is_zero => 1 step => mul(n, f(pred(n)))`
59/// - **Streams**: `unfold nat : Successor from 0`
60///
61/// # Examples
62///
63/// ```rust,ignore
64/// use uor_foundation::uor;
65///
66/// // Term expressions produce a TermArena with the expression tree.
67/// let sum = uor! { add(mul(3, 5), 7) };
68///
69/// // Quantum-annotated literals tag a value at a specific ring width.
70/// let wide = uor! { 144115188075855617@Q7 };
71///
72/// // Type declarations define constrained types.
73/// let pixel = uor! {
74/// type Pixel {
75/// ResidueConstraint(modulus: 256, residue: 255);
76/// HammingConstraint(hammingBound: 8);
77/// DepthConstraint(minDepth: 0, maxDepth: 1);
78/// }
79/// };
80///
81/// // Bindings carry surface syntax and content addresses.
82/// let origin = uor! { let origin : Pixel = add(0, 0); };
83///
84/// // Ground assertions are checked at COMPILE TIME.
85/// uor! { assert add(1, 2) = 3; };
86/// uor! { assert mul(3, 5) = 15; };
87///
88/// // Effect declarations register fiber-targeted effects.
89/// let blit = uor! {
90/// effect Blit {
91/// target: {0, 1, 2, 3};
92/// delta: 0;
93/// commutes: true;
94/// }
95/// };
96///
97/// // Boundary declarations define data sources and sinks.
98/// uor! { source pixel_in : Pixel via sRGB; };
99/// uor! { sink pixel_out : Pixel via DisplayP3; };
100///
101/// // Lift/Project handle level transitions explicitly.
102/// let widened = uor! { lift(x, Q3) };
103/// let narrowed = uor! { project(y, Q0) };
104///
105/// // Match expressions with pattern arms and a required otherwise arm.
106/// let clamped = uor! {
107/// match x {
108/// is_negative => 0;
109/// exceeds_max => 255;
110/// otherwise => x;
111/// }
112/// };
113///
114/// // Bounded recursion with a descent measure and base case.
115/// let factorial = uor! {
116/// recurse fact(n)
117/// measure n
118/// base is_zero => 1
119/// step => mul(n, fact(pred(n)))
120/// };
121///
122/// // Stream construction via unfold (coinductive).
123/// let naturals = uor! { unfold nat : Successor from 0 };
124/// ```
125///
126/// # Errors
127///
128/// Parse errors produce `compile_error!()` at the macro call site.
129/// The error message includes the unexpected token:
130///
131/// ```text
132/// uor! { add(1, ) }
133/// // error: uor! parse error: Unexpected token in expression: RParen
134/// ```
135///
136/// Ground assertions that fail ring evaluation also produce compile errors:
137///
138/// ```text
139/// uor! { assert add(1, 2) = 4; }
140/// // error: assertion failed at compile time
141/// ```
142#[proc_macro]
143pub fn uor(input: TokenStream) -> TokenStream {
144 let input_str = input.to_string();
145 match parser::parse(&input_str) {
146 Ok(parsed) => codegen::emit(&parsed),
147 Err(err) => {
148 let msg = format!("uor! parse error: {err}");
149 quote::quote! { compile_error!(#msg); }.into()
150 }
151 }
152}
153
154/// The v0.2.1 ground-state DSL macro.
155///
156/// Parses a `conformance-program` production of `uor.conformance.ebnf` whose
157/// `compile_unit` body contains a term-language program. Lowers through the
158/// reduction pipeline at build time and expands to a `Grounded<T>` value via
159/// the foundation crate's back-door minting API.
160///
161/// In v0.2.1 the in-process pipeline driver is a stub: it parses the
162/// conformance grammar, validates the keyword set, and emits a back-door
163/// `Grounded<T>` constructor call for inputs in the smoke-test corpus.
164/// Non-corpus inputs produce a `compile_error!` citing the
165/// `reduction:ConvergenceStall` IRI for downstream tooling to surface.
166///
167/// # Examples
168///
169/// ```rust,ignore
170/// use uor_foundation::enforcement::prelude::*;
171///
172/// #[derive(ConstrainedType)]
173/// #[uor(residue = 65535, hamming = 16)]
174/// struct MatVec<const M: usize, const K: usize>;
175///
176/// let unit: Grounded<MatVec<64, 2048>> = uor_ground! {
177/// compile_unit matvec_q32 {
178/// root_term: { /* ... */ };
179/// witt_level_ceiling: W32;
180/// thermodynamic_budget: 2048.0;
181/// target_domains: { ComposedAlgebraic, ArithmeticValuation };
182/// }
183/// };
184/// ```
185#[proc_macro]
186pub fn uor_ground(input: TokenStream) -> TokenStream {
187 let input_str = input.to_string();
188 match conformance_parser::parse(&input_str) {
189 Ok(decl) => conformance_parser::emit_grounded(&decl),
190 Err(err) => {
191 let msg = format!(
192 "uor_ground! parse error: {err}\n\
193 = reason: https://uor.foundation/reduction/ConvergenceStall\n\
194 = run `cargo uor explain reduction:ConvergenceStall` for ontology context"
195 );
196 quote::quote! { compile_error!(#msg); }.into()
197 }
198 }
199}
200
201/// Derive `ConstrainedType` for a struct.
202///
203/// Generates a `GroundedShape` impl so the struct can appear as the type
204/// parameter of `Grounded<T>`. v0.2.1 emits the impl unconditionally; the
205/// `#[uor(residue = …, hamming = …, …)]` attributes are recorded as constants
206/// for downstream introspection.
207///
208/// # Examples
209///
210/// ```rust,ignore
211/// use uor_foundation_macros::ConstrainedType;
212///
213/// #[derive(ConstrainedType)]
214/// #[uor(residue = 255, hamming = 8)]
215/// struct Pixel(u8);
216/// ```
217#[proc_macro_derive(ConstrainedType, attributes(uor))]
218pub fn derive_constrained_type(input: TokenStream) -> TokenStream {
219 derives::derive_constrained_type(input)
220}
221
222/// Derive `CompileUnit` for a struct whose fields name the v0.2.1 builder
223/// inputs (`builder_root_term`, `builder_witt_level_ceiling`,
224/// `builder_thermodynamic_budget`, `builder_target_domains`).
225///
226/// Generates a `build_compile_unit(&self) -> CompileUnit` method that calls
227/// the v0.2.0 `CompileUnitBuilder` chain.
228#[proc_macro_derive(CompileUnit, attributes(uor))]
229pub fn derive_compile_unit(input: TokenStream) -> TokenStream {
230 derives::derive_compile_unit(input)
231}
232
233/// Attribute marker asserting that the function body lowers cleanly at the
234/// named Witt level.
235///
236/// v0.2.1 parses `level = "W8" | "W16" | "W24" | "W32"` and emits a
237/// `const _: ::uor_foundation::WittLevel = ::uor_foundation::WittLevel::WN;`
238/// static assertion after the function. Any undefined level name fails
239/// const evaluation at type-check time.
240///
241/// # Examples
242///
243/// ```rust,ignore
244/// #[uor_foundation_macros::uor_grounded(level = "W32")]
245/// fn matvec() -> Grounded<MatVec<64, 2048>> { /* ... */ }
246/// ```
247#[proc_macro_attribute]
248pub fn uor_grounded(attr: TokenStream, item: TokenStream) -> TokenStream {
249 derives::attr_uor_grounded(attr, item)
250}