Skip to main content

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}