Skip to main content

alice_lol_macro/
lib.rs

1//! ALICE-LOL `proc_macro`: LOL DSL → `SdfNode` construction code
2//!
3//! # Syntax (v0.5)
4//!
5//! ```ignore
6//! lol! {
7//!     field SceneName {
8//!         smooth_union(0.2,
9//!             sphere(1.0),
10//!             translate(2.0, 0.0, 0.0,
11//!                 box3d(0.5, 0.5, 0.5)
12//!             )
13//!         )
14//!     }
15//! }
16//! ```
17//!
18//! Also supports bare expressions without the `field` wrapper:
19//! ```ignore
20//! lol! { sphere(1.0) }
21//! ```
22//!
23//! Runtime variable capture with `{expr}` in numeric positions:
24//! ```ignore
25//! let r = 1.5_f32;
26//! lol! { sphere({r}) }
27//! lol! { translate({x}, {y}, 0.0, sphere({r * 2.0})) }
28//! ```
29//!
30//! # Module 構成 (private)
31//!
32//! - `ast` — LOL Internal AST (`Expr` enum + variants)
33//! - `parser` — Parser (LOL DSL → `Expr` AST)
34//! - `codegen` — Codegen (`Expr` → Rust `TokenStream`)
35//!
36//! `proc_macro` crate は 1 entry point (`lol!`) のみ export、
37//! backward compat 用の re-export は不要 (macro invocation は変わらない)
38
39#![allow(
40    clippy::wildcard_imports,
41    clippy::type_complexity,
42    clippy::many_single_char_names
43)]
44
45mod ast;
46mod codegen;
47mod parser;
48
49use crate::codegen::codegen;
50use crate::parser::LolInput;
51use proc_macro::TokenStream;
52
53/// LOL (Law-Oriented Language) `proc_macro`.
54///
55/// Parses LOL DSL and generates Rust code that constructs an `SdfNode` tree.
56///
57/// # Usage
58///
59/// ```ignore
60/// use alice_lol::lol;
61///
62/// // With field wrapper
63/// let node = lol! {
64///     field MyScene {
65///         smooth_union(0.2,
66///             sphere(1.0),
67///             translate(2.0, 0.0, 0.0, box3d(0.5, 0.5, 0.5))
68///         )
69///     }
70/// };
71///
72/// // Bare expression
73/// let node = lol! { sphere(1.0) };
74///
75/// // Variable capture with {expr}
76/// let r = 1.5_f32;
77/// let node = lol! { sphere({r}) };
78/// let node = lol! { translate({x}, {y}, 0.0, sphere({r * 2.0})) };
79/// ```
80#[proc_macro]
81pub fn lol(input: TokenStream) -> TokenStream {
82    let scene = syn::parse_macro_input!(input as LolInput);
83    let node_code = codegen(&scene.body);
84    node_code.into()
85}