aboutsummaryrefslogtreecommitdiff
path: root/macros/src/syntax/ast.rs
diff options
context:
space:
mode:
authorGravatar Emil Fresk <emil.fresk@gmail.com> 2022-12-31 14:45:13 +0100
committerGravatar Henrik Tjäder <henrik@tjaders.com> 2023-03-01 00:29:10 +0100
commit7614b96fe45240dafe91ae549e712b560e2d4c10 (patch)
tree30e1666c0aac09480e1a87e5fe7965487f4a99e6 /macros/src/syntax/ast.rs
parent1c5db277e4161470136dbd2a11e914ff1d383581 (diff)
downloadrtic-7614b96fe45240dafe91ae549e712b560e2d4c10.tar.gz
rtic-7614b96fe45240dafe91ae549e712b560e2d4c10.tar.zst
rtic-7614b96fe45240dafe91ae549e712b560e2d4c10.zip
RTIC v2: Initial commit
rtic-syntax is now part of RTIC repository
Diffstat (limited to 'macros/src/syntax/ast.rs')
-rw-r--r--macros/src/syntax/ast.rs380
1 files changed, 380 insertions, 0 deletions
diff --git a/macros/src/syntax/ast.rs b/macros/src/syntax/ast.rs
new file mode 100644
index 00000000..0f2e36f4
--- /dev/null
+++ b/macros/src/syntax/ast.rs
@@ -0,0 +1,380 @@
+//! Abstract Syntax Tree
+
+use syn::{Attribute, Expr, Ident, Item, ItemUse, Pat, PatType, Path, Stmt, Type};
+
+use crate::syntax::Map;
+
+/// The `#[app]` attribute
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct App {
+ /// The arguments to the `#[app]` attribute
+ pub args: AppArgs,
+
+ /// The name of the `const` item on which the `#[app]` attribute has been placed
+ pub name: Ident,
+
+ /// The `#[init]` function
+ pub init: Init,
+
+ /// The `#[idle]` function
+ pub idle: Option<Idle>,
+
+ /// Monotonic clocks
+ pub monotonics: Map<Monotonic>,
+
+ /// Resources shared between tasks defined in `#[shared]`
+ pub shared_resources: Map<SharedResource>,
+
+ /// Task local resources defined in `#[local]`
+ pub local_resources: Map<LocalResource>,
+
+ /// User imports
+ pub user_imports: Vec<ItemUse>,
+
+ /// User code
+ pub user_code: Vec<Item>,
+
+ /// Hardware tasks: `#[task(binds = ..)]`s
+ pub hardware_tasks: Map<HardwareTask>,
+
+ /// Software tasks: `#[task]`
+ pub software_tasks: Map<SoftwareTask>,
+}
+
+/// Interrupts used to dispatch software tasks
+pub type Dispatchers = Map<Dispatcher>;
+
+/// Interrupt that could be used to dispatch software tasks
+#[derive(Debug, Clone)]
+#[non_exhaustive]
+pub struct Dispatcher {
+ /// Attributes that will apply to this interrupt handler
+ pub attrs: Vec<Attribute>,
+}
+
+/// The arguments of the `#[app]` attribute
+#[derive(Debug)]
+pub struct AppArgs {
+ /// Device
+ pub device: Path,
+
+ /// Peripherals
+ pub peripherals: bool,
+
+ /// Interrupts used to dispatch software tasks
+ pub dispatchers: Dispatchers,
+}
+
+/// The `init`-ialization function
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct Init {
+ /// `init` context metadata
+ pub args: InitArgs,
+
+ /// Attributes that will apply to this `init` function
+ pub attrs: Vec<Attribute>,
+
+ /// The name of the `#[init]` function
+ pub name: Ident,
+
+ /// The context argument
+ pub context: Box<Pat>,
+
+ /// The statements that make up this `init` function
+ pub stmts: Vec<Stmt>,
+
+ /// The name of the user provided shared resources struct
+ pub user_shared_struct: Ident,
+
+ /// The name of the user provided local resources struct
+ pub user_local_struct: Ident,
+}
+
+/// `init` context metadata
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct InitArgs {
+ /// Local resources that can be accessed from this context
+ pub local_resources: LocalResources,
+}
+
+impl Default for InitArgs {
+ fn default() -> Self {
+ Self {
+ local_resources: LocalResources::new(),
+ }
+ }
+}
+
+/// The `idle` context
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct Idle {
+ /// `idle` context metadata
+ pub args: IdleArgs,
+
+ /// Attributes that will apply to this `idle` function
+ pub attrs: Vec<Attribute>,
+
+ /// The name of the `#[idle]` function
+ pub name: Ident,
+
+ /// The context argument
+ pub context: Box<Pat>,
+
+ /// The statements that make up this `idle` function
+ pub stmts: Vec<Stmt>,
+}
+
+/// `idle` context metadata
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct IdleArgs {
+ /// Local resources that can be accessed from this context
+ pub local_resources: LocalResources,
+
+ /// Shared resources that can be accessed from this context
+ pub shared_resources: SharedResources,
+}
+
+impl Default for IdleArgs {
+ fn default() -> Self {
+ Self {
+ local_resources: LocalResources::new(),
+ shared_resources: SharedResources::new(),
+ }
+ }
+}
+
+/// Shared resource properties
+#[derive(Debug)]
+pub struct SharedResourceProperties {
+ /// A lock free (exclusive resource)
+ pub lock_free: bool,
+}
+
+/// A shared resource, defined in `#[shared]`
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct SharedResource {
+ /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
+ pub cfgs: Vec<Attribute>,
+
+ /// `#[doc]` attributes like `/// this is a docstring`
+ pub docs: Vec<Attribute>,
+
+ /// Attributes that will apply to this resource
+ pub attrs: Vec<Attribute>,
+
+ /// The type of this resource
+ pub ty: Box<Type>,
+
+ /// Shared resource properties
+ pub properties: SharedResourceProperties,
+}
+
+/// A local resource, defined in `#[local]`
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct LocalResource {
+ /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
+ pub cfgs: Vec<Attribute>,
+
+ /// `#[doc]` attributes like `/// this is a docstring`
+ pub docs: Vec<Attribute>,
+
+ /// Attributes that will apply to this resource
+ pub attrs: Vec<Attribute>,
+
+ /// The type of this resource
+ pub ty: Box<Type>,
+}
+
+/// Monotonic
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct Monotonic {
+ /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
+ pub cfgs: Vec<Attribute>,
+
+ /// The identifier of the monotonic
+ pub ident: Ident,
+
+ /// The type of this monotonic
+ pub ty: Box<Type>,
+
+ /// Monotonic args
+ pub args: MonotonicArgs,
+}
+
+/// Monotonic metadata
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct MonotonicArgs {
+ /// The interrupt or exception that this monotonic is bound to
+ pub binds: Ident,
+
+ /// The priority of this monotonic
+ pub priority: Option<u8>,
+
+ /// If this is the default monotonic
+ pub default: bool,
+}
+
+/// A software task
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct SoftwareTask {
+ /// Software task metadata
+ pub args: SoftwareTaskArgs,
+
+ /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
+ pub cfgs: Vec<Attribute>,
+
+ /// Attributes that will apply to this interrupt handler
+ pub attrs: Vec<Attribute>,
+
+ /// The context argument
+ pub context: Box<Pat>,
+
+ /// The inputs of this software task
+ pub inputs: Vec<PatType>,
+
+ /// The statements that make up the task handler
+ pub stmts: Vec<Stmt>,
+
+ /// The task is declared externally
+ pub is_extern: bool,
+
+ /// If the task is marked as `async`
+ pub is_async: bool,
+}
+
+/// Software task metadata
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct SoftwareTaskArgs {
+ /// The task capacity: the maximum number of pending messages that can be queued
+ pub capacity: u8,
+
+ /// The priority of this task
+ pub priority: u8,
+
+ /// Local resources that can be accessed from this context
+ pub local_resources: LocalResources,
+
+ /// Shared resources that can be accessed from this context
+ pub shared_resources: SharedResources,
+
+ /// Only same priority tasks can spawn this task
+ pub only_same_priority_spawn: bool,
+}
+
+impl Default for SoftwareTaskArgs {
+ fn default() -> Self {
+ Self {
+ capacity: 1,
+ priority: 1,
+ local_resources: LocalResources::new(),
+ shared_resources: SharedResources::new(),
+ only_same_priority_spawn: false,
+ }
+ }
+}
+
+/// A hardware task
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct HardwareTask {
+ /// Hardware task metadata
+ pub args: HardwareTaskArgs,
+
+ /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
+ pub cfgs: Vec<Attribute>,
+
+ /// Attributes that will apply to this interrupt handler
+ pub attrs: Vec<Attribute>,
+
+ /// The context argument
+ pub context: Box<Pat>,
+
+ /// The statements that make up the task handler
+ pub stmts: Vec<Stmt>,
+
+ /// The task is declared externally
+ pub is_extern: bool,
+}
+
+/// Hardware task metadata
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct HardwareTaskArgs {
+ /// The interrupt or exception that this task is bound to
+ pub binds: Ident,
+
+ /// The priority of this task
+ pub priority: u8,
+
+ /// Local resources that can be accessed from this context
+ pub local_resources: LocalResources,
+
+ /// Shared resources that can be accessed from this context
+ pub shared_resources: SharedResources,
+}
+
+/// A `static mut` variable local to and owned by a context
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct Local {
+ /// Attributes like `#[link_section]`
+ pub attrs: Vec<Attribute>,
+
+ /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
+ pub cfgs: Vec<Attribute>,
+
+ /// Type
+ pub ty: Box<Type>,
+
+ /// Initial value
+ pub expr: Box<Expr>,
+}
+
+/// A wrapper of the 2 kinds of locals that tasks can have
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum TaskLocal {
+ /// The local is declared externally (i.e. `#[local]` struct)
+ External,
+ /// The local is declared in the task
+ Declared(Local),
+}
+
+/// Resource access
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum Access {
+ /// `[x]`, a mutable resource
+ Exclusive,
+
+ /// `[&x]`, a static non-mutable resource
+ Shared,
+}
+
+impl Access {
+ /// Is this enum in the `Exclusive` variant?
+ pub fn is_exclusive(&self) -> bool {
+ *self == Access::Exclusive
+ }
+
+ /// Is this enum in the `Shared` variant?
+ pub fn is_shared(&self) -> bool {
+ *self == Access::Shared
+ }
+}
+
+/// Shared resource access list in task attribute
+pub type SharedResources = Map<Access>;
+
+/// Local resource access/declaration list in task attribute
+pub type LocalResources = Map<TaskLocal>;