rtic_macros/syntax/ast.rs
1//! Abstract Syntax Tree
2
3use syn::{Attribute, Expr, Ident, Item, ItemUse, Pat, PatType, Path, Stmt, Type};
4
5use crate::syntax::{backend::BackendArgs, Map};
6
7/// The `#[app]` attribute
8#[derive(Debug)]
9#[non_exhaustive]
10pub struct App {
11 /// The arguments to the `#[app]` attribute
12 pub args: AppArgs,
13
14 /// The name of the `const` item on which the `#[app]` attribute has been placed
15 pub name: Ident,
16
17 /// The `#[init]` function
18 pub init: Init,
19
20 /// The `#[idle]` function
21 pub idle: Option<Idle>,
22
23 /// Resources shared between tasks defined in `#[shared]`
24 pub shared_resources: Map<SharedResource>,
25
26 pub shared_resources_vis: syn::Visibility,
27
28 /// Task local resources defined in `#[local]`
29 pub local_resources: Map<LocalResource>,
30
31 pub local_resources_vis: syn::Visibility,
32
33 /// User imports
34 pub user_imports: Vec<ItemUse>,
35
36 /// User code
37 pub user_code: Vec<Item>,
38
39 /// Hardware tasks: `#[task(binds = ..)]`s
40 pub hardware_tasks: Map<HardwareTask>,
41
42 /// Async software tasks: `#[task]`
43 pub software_tasks: Map<SoftwareTask>,
44}
45
46/// Interrupts used to dispatch software tasks
47pub type Dispatchers = Map<Dispatcher>;
48
49/// Interrupt that could be used to dispatch software tasks
50#[derive(Debug, Clone)]
51#[non_exhaustive]
52pub struct Dispatcher {
53 /// Attributes that will apply to this interrupt handler
54 pub attrs: Vec<Attribute>,
55}
56
57/// The arguments of the `#[app]` attribute
58#[derive(Debug)]
59pub struct AppArgs {
60 /// Device
61 pub device: Path,
62
63 /// Core peripherals
64 pub core: bool,
65
66 /// Device peripherals
67 pub peripherals: bool,
68
69 /// Interrupts used to dispatch software tasks
70 pub dispatchers: Dispatchers,
71
72 /// Backend-specific arguments
73 #[allow(dead_code)]
74 pub backend: Option<BackendArgs>,
75}
76
77/// The `init`-ialization function
78#[derive(Debug)]
79#[non_exhaustive]
80pub struct Init {
81 /// `init` context metadata
82 pub args: InitArgs,
83
84 /// Attributes that will apply to this `init` function
85 pub attrs: Vec<Attribute>,
86
87 /// The name of the `#[init]` function
88 pub name: Ident,
89
90 /// The context argument
91 pub context: Box<Pat>,
92
93 /// The statements that make up this `init` function
94 pub stmts: Vec<Stmt>,
95
96 /// The name of the user provided shared resources struct
97 pub user_shared_struct: Ident,
98
99 /// The name of the user provided local resources struct
100 pub user_local_struct: Ident,
101
102 /// The init function is declared externally
103 pub is_extern: bool,
104}
105
106/// `init` context metadata
107#[derive(Debug)]
108#[non_exhaustive]
109pub struct InitArgs {
110 /// Local resources that can be accessed from this context
111 pub local_resources: LocalResources,
112}
113
114impl Default for InitArgs {
115 fn default() -> Self {
116 Self {
117 local_resources: LocalResources::new(),
118 }
119 }
120}
121
122/// The `idle` context
123#[derive(Debug)]
124#[non_exhaustive]
125pub struct Idle {
126 /// `idle` context metadata
127 pub args: IdleArgs,
128
129 /// Attributes that will apply to this `idle` function
130 pub attrs: Vec<Attribute>,
131
132 /// The name of the `#[idle]` function
133 pub name: Ident,
134
135 /// The context argument
136 pub context: Box<Pat>,
137
138 /// The statements that make up this `idle` function
139 pub stmts: Vec<Stmt>,
140
141 /// The idle function is declared externally
142 pub is_extern: bool,
143}
144
145/// `idle` context metadata
146#[derive(Debug)]
147#[non_exhaustive]
148pub struct IdleArgs {
149 /// Local resources that can be accessed from this context
150 pub local_resources: LocalResources,
151
152 /// Shared resources that can be accessed from this context
153 pub shared_resources: SharedResources,
154}
155
156impl Default for IdleArgs {
157 fn default() -> Self {
158 Self {
159 local_resources: LocalResources::new(),
160 shared_resources: SharedResources::new(),
161 }
162 }
163}
164
165/// Shared resource properties
166#[derive(Debug)]
167pub struct SharedResourceProperties {
168 /// A lock free (exclusive resource)
169 pub lock_free: bool,
170}
171
172/// A shared resource, defined in `#[shared]`
173#[derive(Debug)]
174#[non_exhaustive]
175pub struct SharedResource {
176 /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
177 pub cfgs: Vec<Attribute>,
178
179 /// `#[doc]` attributes like `/// this is a docstring`
180 pub docs: Vec<Attribute>,
181
182 /// Attributes that will apply to this resource
183 pub attrs: Vec<Attribute>,
184
185 /// The type of this resource
186 pub ty: Box<Type>,
187
188 /// Shared resource properties
189 pub properties: SharedResourceProperties,
190
191 /// The visibility of this resource
192 pub vis: syn::Visibility,
193}
194
195/// A local resource, defined in `#[local]`
196#[derive(Debug)]
197#[non_exhaustive]
198pub struct LocalResource {
199 /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
200 pub cfgs: Vec<Attribute>,
201
202 /// `#[doc]` attributes like `/// this is a docstring`
203 pub docs: Vec<Attribute>,
204
205 /// Attributes that will apply to this resource
206 pub attrs: Vec<Attribute>,
207
208 /// The type of this resource
209 pub ty: Box<Type>,
210
211 /// The visibility of this resource
212 pub vis: syn::Visibility,
213}
214
215/// An async software task
216#[derive(Debug)]
217#[non_exhaustive]
218pub struct SoftwareTask {
219 /// Software task metadata
220 pub args: SoftwareTaskArgs,
221
222 /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
223 pub cfgs: Vec<Attribute>,
224
225 /// Attributes that will apply to this interrupt handler
226 pub attrs: Vec<Attribute>,
227
228 /// The context argument
229 pub context: Box<Pat>,
230
231 /// The inputs of this software task
232 pub inputs: Vec<PatType>,
233
234 /// The statements that make up the task handler
235 pub stmts: Vec<Stmt>,
236
237 /// The task is declared externally
238 pub is_extern: bool,
239
240 /// The task will never return `Poll::Ready`
241 pub is_bottom: bool,
242}
243
244/// Software task metadata
245#[derive(Debug)]
246#[non_exhaustive]
247pub struct SoftwareTaskArgs {
248 /// The priority of this task
249 pub priority: u8,
250
251 /// Local resources that can be accessed from this context
252 pub local_resources: LocalResources,
253
254 /// Shared resources that can be accessed from this context
255 pub shared_resources: SharedResources,
256}
257
258impl Default for SoftwareTaskArgs {
259 fn default() -> Self {
260 Self {
261 priority: 0,
262 local_resources: LocalResources::new(),
263 shared_resources: SharedResources::new(),
264 }
265 }
266}
267
268/// A hardware task
269#[derive(Debug)]
270#[non_exhaustive]
271pub struct HardwareTask {
272 /// Hardware task metadata
273 pub args: HardwareTaskArgs,
274
275 /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
276 pub cfgs: Vec<Attribute>,
277
278 /// Attributes that will apply to this interrupt handler
279 pub attrs: Vec<Attribute>,
280
281 /// The context argument
282 pub context: Box<Pat>,
283
284 /// The statements that make up the task handler
285 pub stmts: Vec<Stmt>,
286
287 /// The task is declared externally
288 pub is_extern: bool,
289}
290
291/// Hardware task metadata
292#[derive(Debug)]
293#[non_exhaustive]
294pub struct HardwareTaskArgs {
295 /// The interrupt or exception that this task is bound to
296 pub binds: Ident,
297
298 /// The priority of this task
299 pub priority: u8,
300
301 /// Local resources that can be accessed from this context
302 pub local_resources: LocalResources,
303
304 /// Shared resources that can be accessed from this context
305 pub shared_resources: SharedResources,
306}
307
308/// A `static mut` variable local to and owned by a context
309#[derive(Debug)]
310#[non_exhaustive]
311pub struct Local {
312 /// Attributes like `#[link_section]`
313 pub attrs: Vec<Attribute>,
314
315 /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
316 pub cfgs: Vec<Attribute>,
317
318 /// Type
319 pub ty: Box<Type>,
320
321 /// Initial value
322 pub expr: Box<Expr>,
323}
324
325/// A wrapper of the 2 kinds of locals that tasks can have
326#[derive(Debug)]
327#[non_exhaustive]
328pub enum TaskLocal {
329 /// The local is declared externally (i.e. `#[local]` struct)
330 External,
331 /// The local is declared in the task
332 Declared(Local),
333}
334
335/// Resource access
336#[derive(Clone, Copy, Debug, Eq, PartialEq)]
337pub enum Access {
338 /// `[x]`, a mutable resource
339 Exclusive,
340
341 /// `[&x]`, a static non-mutable resource
342 Shared,
343}
344
345impl Access {
346 /// Is this enum in the `Exclusive` variant?
347 pub fn is_exclusive(&self) -> bool {
348 *self == Access::Exclusive
349 }
350
351 /// Is this enum in the `Shared` variant?
352 pub fn is_shared(&self) -> bool {
353 *self == Access::Shared
354 }
355}
356
357/// Shared resource access list in task attribute
358pub type SharedResources = Map<Access>;
359
360/// Local resource access/declaration list in task attribute
361pub type LocalResources = Map<TaskLocal>;