Skip to content

Commit f4592b8

Browse files
committed
Add LUT proc macro
1 parent 405cb0a commit f4592b8

2 files changed

Lines changed: 82 additions & 1 deletion

File tree

exp_lut_macro/src/lib.rs

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,82 @@
11
extern crate proc_macro;
22

3-
use proc_macro::TokenStream;
3+
use proc_macro::TokenStream;
4+
use quote::{quote, ToTokens};
5+
use syn::{
6+
Ident, LitFloat, LitInt, LitStr, Result, Token, parse::{Parse, ParseStream}, parse_macro_input
7+
};
8+
9+
#[derive(Debug, Clone)]
10+
struct ExpLutMacroInput {
11+
start: f32,
12+
end: f32,
13+
steps: usize,
14+
}
15+
16+
impl Parse for ExpLutMacroInput {
17+
fn parse(input: ParseStream) -> Result<Self> {
18+
let key1: Ident = input.parse()?;
19+
input.parse::<Token![:]>()?;
20+
let lit1: LitFloat = input.parse()?;
21+
let value1: &str = lit1.base10_digits();
22+
23+
input.parse::<Token![,]>()?;
24+
25+
let key2: Ident = input.parse()?;
26+
input.parse::<Token![:]>()?;
27+
let lit2: LitFloat = input.parse()?;
28+
let value2: &str = lit2.base10_digits();
29+
30+
input.parse::<Token![,]>()?;
31+
32+
let key3: Ident = input.parse()?;
33+
input.parse::<Token![:]>()?;
34+
let lit3: LitInt = input.parse()?;
35+
let value3: &str = lit3.base10_digits();
36+
37+
let mut input = ExpLutMacroInput {
38+
start: 0.0,
39+
end: 0.0,
40+
steps: 0,
41+
};
42+
43+
for (key, value) in [(key1, value1), (key2, value2), (key3, value3)] {
44+
if key == "start" {
45+
input.start = value.parse::<f32>().unwrap();
46+
} else if key == "end" {
47+
input.end = value.parse::<f32>().unwrap();
48+
} else if key == "steps" {
49+
input.steps = value.parse::<usize>().unwrap();
50+
}
51+
}
52+
53+
Ok(input)
54+
}
55+
}
56+
57+
#[proc_macro]
58+
pub fn exp_lut_macro(input: TokenStream) -> TokenStream {
59+
let input = parse_macro_input!(input as ExpLutMacroInput);
60+
61+
if input.steps < 2 {
62+
panic!("EXP_LOOKUP_STEPS must be >= 2");
63+
}
64+
65+
if input.end <= input.start {
66+
panic!("EXP_LOOKUP_END must be > EXP_LOOKUP_START");
67+
}
68+
69+
let steps: usize = input.steps;
70+
let start: f32 = input.start;
71+
let end: f32 = input.end;
72+
let step_size: f32 = (end - start) / steps as f32;
73+
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+
};
80+
81+
TokenStream::from(expanded)
82+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@ impl AnxiousState {
4040
}
4141

4242
/// Constants for the exponential lookup table
43+
/// EXP_LOOKUP_STEPS >= 2 and EXP_LOOKUP_END > EXP_LOOKUP_START is assumed
4344
const EXP_LOOKUP_START: f32 = -20.0;
4445
const EXP_LOOKUP_END: f32 = 20.0;
4546
const EXP_LOOKUP_STEPS: usize = 1000;
4647
const EXP_LOOKUP_STEP_SIZE: f32 = (EXP_LOOKUP_END - EXP_LOOKUP_START) / EXP_LOOKUP_STEPS as f32;
4748

49+
// exp_lut_macro::exp_lut_macro!(EXP_LOOKUP_START, EXP_LOOKUP_END, EXP_LOOKUP_STEPS);
4850

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

0 commit comments

Comments
 (0)