1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
//! Provides macros that allow downstream crates to examine the choice of
//! the target kernel.
//!
//! This module's macros whose names start with `tt_` follow `tt-call`'s token
//! tree calling convention.
include!(concat!(env!("OUT_DIR"), "/macros.rs"));
// Make `tt_call` available to the following macros' expansion
#[doc(hidden)]
pub use tt_call;
/// Expand to the current kernel's name (e.g., `"asp3"`).
///
/// # Examples
///
/// ```rust
/// println!("We are running on {}", itron::macros::kernel!());
/// ```
///
/// ```rust,compile_fail
/// compile_error!(concat!("kernel `", itron::macros::kernel!(), "` is not supported"));
/// ```
pub macro kernel() {
tt_call::tt_call! { macro = [{ itron::macros::tt_kernel }] }
}
/// Expand to the arm corresponding to the current kernel.
///
/// # Example
///
/// ```rust
/// itron::macros::match_kernel! {
/// "asp3" | "solid_asp3" => { fn say() { println!("We are running on TOPPERS/ASP3, yay!"); } }
/// "nonexistent_kernel" => { call_nonexistent_function(); }
/// _ => { fn say() { println!("This kernel looks like something new!"); } }
/// }
/// say();
/// ```
///
/// The arms don't create local scopes, and unselected arms are eliminated
/// during an early stage of compilation. Compare to the following example:
///
/// ```rust,compile_fail
/// match itron::macros::kernel!() {
/// "asp3" | "solid_asp3" => { fn say() { println!("We are running on TOPPERS/ASP3, yay!"); } }
/// "nonexistent_kernel" => { call_nonexistent_function(); }
/// // ERROR: `call_nonexistent_function` is undefined
/// _ => { fn say() { println!("This kernel looks like something new!"); } }
/// }
/// say(); // ERROR: Each arm's `say` is not accessible from here
/// ```
///
pub macro match_kernel {
(
_ => { $($wildcard:tt)* }
) => { $($wildcard)* },
(
_ => { $($wildcard:tt)* }
$($rest:tt)*
) => {
compile_error!("anything that follow `_ => { ... }` never match")
},
(
$( $kernel:tt )|+ => { $($tt:tt)* }
$($rest:tt)*
) => {
tt_call::tt_if! {
condition = [{ $crate::macros::tt_is_kernel }]
input = [{ $( $kernel )|+ }]
true = [{ $($tt)* }]
false = [{
match_kernel! { $($rest)* }
}]
}
},
}