Skip to content

Commit b4da9bd

Browse files
committed
Refine LUT proc macro
1 parent f4592b8 commit b4da9bd

2 files changed

Lines changed: 52 additions & 16 deletions

File tree

exp_lut_macro/src/lib.rs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
extern crate proc_macro;
22

33
use proc_macro::TokenStream;
4-
use quote::{quote, ToTokens};
4+
use quote::quote;
55
use syn::{
66
Ident, LitFloat, LitInt, LitStr, Result, Token, parse::{Parse, ParseStream}, parse_macro_input
77
};
@@ -55,6 +55,28 @@ impl Parse for ExpLutMacroInput {
5555
}
5656

5757
#[proc_macro]
58+
/// Generate an exponential lookup table and related constants.
59+
///
60+
/// Inputs are literals:
61+
/// - `start: f32` — lower bound (inclusive)
62+
/// - `end: f32` — upper bound (inclusive, requires `end > start`)
63+
/// - `steps: usize` — number of samples (must be >= 2)
64+
///
65+
/// Expansion defines the following `const`s in the invocation scope:
66+
/// - `EXP_LOOKUP_START: f32`
67+
/// - `EXP_LOOKUP_END: f32`
68+
/// - `EXP_LOOKUP_STEPS: usize`
69+
/// - `EXP_LOOKUP_STEP_SIZE: f32`
70+
/// - `EXP_LOOKUP_LUT: [f32; EXP_LOOKUP_STEPS]` (values of `e^x` over `[start, end]`)
71+
///
72+
/// Example:
73+
/// ```ignore
74+
/// exp_lut_macro::exp_lut_macro!(
75+
/// start: -20.0,
76+
/// end: 20.0,
77+
/// steps: 1000
78+
/// );
79+
/// ```
5880
pub fn exp_lut_macro(input: TokenStream) -> TokenStream {
5981
let input = parse_macro_input!(input as ExpLutMacroInput);
6082

@@ -71,12 +93,16 @@ pub fn exp_lut_macro(input: TokenStream) -> TokenStream {
7193
let end: f32 = input.end;
7294
let step_size: f32 = (end - start) / steps as f32;
7395

74-
let expanded = quote! {
75-
const LUT: [f32; #steps] = core::array::from_fn(|i| {
76-
let x = #start + (i as f32 * #step_size);
77-
x.exp()
78-
});
79-
};
96+
let lut: Vec<f32> = (0..steps).map(|i| {
97+
let x = start + (i as f32 * step_size);
98+
x.exp()
99+
}).collect();
80100

81-
TokenStream::from(expanded)
101+
TokenStream::from(quote! {
102+
const EXP_LOOKUP_START: f32 = #start;
103+
const EXP_LOOKUP_END: f32 = #end;
104+
const EXP_LOOKUP_STEPS: usize = #steps;
105+
const EXP_LOOKUP_STEP_SIZE: f32 = #step_size;
106+
const EXP_LOOKUP_LUT: [f32; #steps] = [ #(#lut),* ];
107+
})
82108
}

src/lib.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,24 @@ impl AnxiousState {
3939
}
4040
}
4141

42-
/// Constants for the exponential lookup table
43-
/// EXP_LOOKUP_STEPS >= 2 and EXP_LOOKUP_END > EXP_LOOKUP_START is assumed
44-
const EXP_LOOKUP_START: f32 = -20.0;
45-
const EXP_LOOKUP_END: f32 = 20.0;
46-
const EXP_LOOKUP_STEPS: usize = 1000;
47-
const EXP_LOOKUP_STEP_SIZE: f32 = (EXP_LOOKUP_END - EXP_LOOKUP_START) / EXP_LOOKUP_STEPS as f32;
48-
49-
// exp_lut_macro::exp_lut_macro!(EXP_LOOKUP_START, EXP_LOOKUP_END, EXP_LOOKUP_STEPS);
42+
// Exponential lookup table (LUT) configuration and data
43+
//
44+
// The following macro invocation expands at compile time to define:
45+
// - EXP_LOOKUP_START: f32 (inclusive lower bound)
46+
// - EXP_LOOKUP_END: f32 (inclusive upper bound)
47+
// - EXP_LOOKUP_STEPS: usize (number of samples; must be >= 2)
48+
// - EXP_LOOKUP_STEP_SIZE: f32
49+
// - EXP_LOOKUP_LUT: [f32; EXP_LOOKUP_STEPS] (samples of e^x over [START, END])
50+
//
51+
// Inputs must be literals because the proc macro computes the LUT at
52+
// compile time and emits the array as a literal. Adjust START/END/STEPS
53+
// here to regenerate the table.
54+
exp_lut_macro::exp_lut_macro!(
55+
start: -20.0,
56+
end: 20.0,
57+
steps: 1000
58+
);
59+
5060

5161
#[inline(always)]
5262
/// We use a logistic function as the transformation function.

0 commit comments

Comments
 (0)