furiosa_mapping/parser/
mod.rs1use crate::PaddingKind;
4use lalrpop_util::lalrpop_mod;
5use quote::quote;
6
7mod lexer;
8lalrpop_mod!(
9 #[expect(missing_docs, missing_debug_implementations)]
10 parser,
11 "/parser/parser.rs"
12);
13
14pub use lexer::{Lexer, LexerMode};
15pub use parser::{IndexParser, MappingParser};
16
17#[derive(Debug, Clone)]
19pub struct IndexAssignment {
20 pub mapping: Mapping,
22 pub value: proc_macro2::TokenStream,
24}
25
26impl IndexAssignment {
27 pub fn expand(&self) -> proc_macro2::TokenStream {
29 let value = &self.value;
30 self.mapping.expand_as_index(value)
31 }
32}
33
34#[derive(Debug, Clone)]
36#[expect(missing_docs)]
37pub enum Mapping {
38 Identity,
39 Symbol {
40 symbol: String,
41 },
42 Stride {
43 inner: Box<Self>,
44 stride: usize,
45 },
46 Modulo {
47 inner: Box<Self>,
48 modulo: usize,
49 },
50 Resize {
51 inner: Box<Self>,
52 resize: usize,
53 },
54 Padding {
55 inner: Box<Self>,
56 padding: usize,
57 kind: PaddingKind,
58 },
59 Pair {
60 left: Box<Self>,
61 right: Box<Self>,
62 },
63 Escaped {
64 tokens: proc_macro2::TokenStream,
65 },
66}
67
68impl Mapping {
69 pub fn expand(&self) -> proc_macro2::TokenStream {
71 match self {
72 Self::Identity => {
73 quote! { Identity }
74 }
75 Self::Symbol { symbol } => {
76 let sym_ident = proc_macro2::Ident::new(symbol, proc_macro2::Span::call_site());
77 quote! { Symbol<#sym_ident> }
78 }
79 Self::Stride {
80 inner: left,
81 stride: value,
82 } => {
83 let l = left.expand();
84 quote! { Stride<#l, #value> }
85 }
86 Self::Modulo {
87 inner: left,
88 modulo: value,
89 } => {
90 let l = left.expand();
91 quote! { Modulo<#l, #value> }
92 }
93 Self::Resize {
94 inner: left,
95 resize: value,
96 } => {
97 let l = left.expand();
98 quote! { Resize<#l, #value> }
99 }
100 Self::Padding {
101 inner: left,
102 padding: value,
103 kind: _,
104 } => {
105 let l = left.expand();
106 quote! { Padding<#l, #value> }
107 }
108 Self::Pair { left, right } => {
109 let l = left.expand();
110 let r = right.expand();
111 quote! { Pair<#l, #r> }
112 }
113 Self::Escaped { tokens } => {
114 quote! { #tokens }
115 }
116 }
117 }
118
119 pub fn expand_as_index(&self, value: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
121 match self {
122 Self::Symbol { symbol } => {
123 let sym_ident = proc_macro2::Ident::new(symbol, proc_macro2::Span::call_site());
124 let size_expr = quote! { <#sym_ident as m::AxisName>::SIZE };
125 quote! {
126 {
127 use ::furiosa_mapping as m;
128 const SIZE: usize = #size_expr;
129 index.add_term(
130 m::Term {
131 inner: m::Atom::Symbol {
132 symbol: m::Ident::new(#symbol),
133 size: SIZE,
134 },
135 stride: 1,
136 modulo: SIZE,
137 },
138 #value
139 );
140 }
141 }
142 }
143 Self::Identity => {
144 quote! {
145 {
146 use ::furiosa_mapping as m;
147 if let Some(mapped_index) = <m::Identity as m::M>::map(#value) {
148 index.add(mapped_index);
149 } else {
150 index.mark_invalid();
151 }
152 }
153 }
154 }
155 Self::Stride { inner, stride } => {
156 let inner_expanded = inner.expand();
157 quote! {
158 {
159 use ::furiosa_mapping as m;
160 if let Some(mapped_index) = <m::Stride<#inner_expanded, #stride> as m::M>::map(#value) {
161 index.add(mapped_index);
162 } else {
163 index.mark_invalid();
164 }
165 }
166 }
167 }
168 Self::Modulo { inner, modulo } => {
169 let inner_expanded = inner.expand();
170 quote! {
171 {
172 use ::furiosa_mapping as m;
173 if let Some(mapped_index) = <m::Modulo<#inner_expanded, #modulo> as m::M>::map(#value) {
174 index.add(mapped_index);
175 } else {
176 index.mark_invalid();
177 }
178 }
179 }
180 }
181 Self::Resize { inner, resize } => {
182 let inner_expanded = inner.expand();
183 quote! {
184 {
185 use ::furiosa_mapping as m;
186 if let Some(mapped_index) = <m::Resize<#inner_expanded, #resize> as m::M>::map(#value) {
187 index.add(mapped_index);
188 } else {
189 index.mark_invalid();
190 }
191 }
192 }
193 }
194 Self::Padding {
195 inner,
196 padding,
197 kind: _,
198 } => {
199 let inner_expanded = inner.expand();
200 quote! {
201 {
202 use ::furiosa_mapping as m;
203 if let Some(mapped_index) = <m::Padding<#inner_expanded, #padding> as m::M>::map(#value) {
204 index.add(mapped_index);
205 } else {
206 index.mark_invalid();
207 }
208 }
209 }
210 }
211 Self::Pair { left, right } => {
212 let left_expanded = left.expand();
213 let right_expanded = right.expand();
214 quote! {
215 {
216 use ::furiosa_mapping as m;
217 if let Some(mapped_index) = <m::Pair<#left_expanded, #right_expanded> as m::M>::map(#value) {
218 index.add(mapped_index);
219 } else {
220 index.mark_invalid();
221 }
222 }
223 }
224 }
225 Self::Escaped { tokens } => {
226 quote! {
227 {
228 use ::furiosa_mapping as m;
229 if let Some(mapped_index) = <#tokens as m::M>::map(#value) {
230 index.add(mapped_index);
231 } else {
232 index.mark_invalid();
233 }
234 }
235 }
236 }
237 }
238 }
239}