syntax: Remove parse settings struct

This commit is contained in:
Emil Fresk 2023-01-03 07:51:35 +01:00 committed by Henrik Tjäder
parent 9829d0ac07
commit d7ed7a8b9f
13 changed files with 22 additions and 86 deletions

View file

@ -18,25 +18,7 @@ mod syntax;
#[doc(hidden)] #[doc(hidden)]
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn mock_app(args: TokenStream, input: TokenStream) -> TokenStream { pub fn mock_app(args: TokenStream, input: TokenStream) -> TokenStream {
let mut settings = syntax::Settings::default(); if let Err(e) = syntax::parse(args, input) {
let mut rtic_args = vec![];
for arg in args.to_string().split(',') {
if arg.trim() == "parse_binds" {
settings.parse_binds = true;
} else if arg.trim() == "parse_extern_interrupt" {
settings.parse_extern_interrupt = true;
} else {
rtic_args.push(arg.to_string());
}
}
// rtic_args.push("device = mock".into());
let args = rtic_args.join(", ").parse();
println!("args: {:?}", args);
if let Err(e) = syntax::parse(args.unwrap(), input, settings) {
e.to_compile_error().into() e.to_compile_error().into()
} else { } else {
"fn main() {}".parse().unwrap() "fn main() {}".parse().unwrap()
@ -52,12 +34,7 @@ pub fn mock_app(args: TokenStream, input: TokenStream) -> TokenStream {
/// Should never panic, cargo feeds a path which is later converted to a string /// Should never panic, cargo feeds a path which is later converted to a string
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn app(args: TokenStream, input: TokenStream) -> TokenStream { pub fn app(args: TokenStream, input: TokenStream) -> TokenStream {
let mut settings = syntax::Settings::default(); let (app, analysis) = match syntax::parse(args, input) {
settings.optimize_priorities = false;
settings.parse_binds = true;
settings.parse_extern_interrupt = true;
let (app, analysis) = match syntax::parse(args, input, settings) {
Err(e) => return e.to_compile_error().into(), Err(e) => return e.to_compile_error().into(),
Ok(x) => x, Ok(x) => x,
}; };

View file

@ -13,7 +13,6 @@ mod accessors;
pub mod analyze; pub mod analyze;
pub mod ast; pub mod ast;
mod check; mod check;
mod optimize;
mod parse; mod parse;
/// An ordered map keyed by identifier /// An ordered map keyed by identifier
@ -31,10 +30,10 @@ pub enum Context<'a> {
/// The `init`-ialization function /// The `init`-ialization function
Init, Init,
/// A software task: `#[task]` /// A async software task
SoftwareTask(&'a Ident), SoftwareTask(&'a Ident),
/// A hardware task: `#[exception]` or `#[interrupt]` /// A hardware task
HardwareTask(&'a Ident), HardwareTask(&'a Ident),
} }
@ -93,36 +92,21 @@ impl<'a> Context<'a> {
} }
} }
/// Parser and optimizer configuration
#[derive(Default)]
#[non_exhaustive]
pub struct Settings {
/// Whether to accept the `binds` argument in `#[task]` or not
pub parse_binds: bool,
/// Whether to parse `extern` interrupts (functions) or not
pub parse_extern_interrupt: bool,
/// Whether to "compress" priorities or not
pub optimize_priorities: bool,
}
/// Parses the input of the `#[app]` attribute /// Parses the input of the `#[app]` attribute
pub fn parse( pub fn parse(
args: TokenStream, args: TokenStream,
input: TokenStream, input: TokenStream,
settings: Settings,
) -> Result<(ast::App, analyze::Analysis), syn::parse::Error> { ) -> Result<(ast::App, analyze::Analysis), syn::parse::Error> {
parse2(args.into(), input.into(), settings) parse2(args.into(), input.into())
} }
/// `proc_macro2::TokenStream` version of `parse` /// `proc_macro2::TokenStream` version of `parse`
pub fn parse2( pub fn parse2(
args: TokenStream2, args: TokenStream2,
input: TokenStream2, input: TokenStream2,
settings: Settings,
) -> Result<(ast::App, analyze::Analysis), syn::parse::Error> { ) -> Result<(ast::App, analyze::Analysis), syn::parse::Error> {
let mut app = parse::app(args, input, &settings)?; let app = parse::app(args, input)?;
check::app(&app)?; check::app(&app)?;
optimize::app(&mut app, &settings);
match analyze::app(&app) { match analyze::app(&app) {
Err(e) => Err(e), Err(e) => Err(e),

View file

@ -1,6 +1,6 @@
use std::collections::{BTreeSet, HashMap}; use std::collections::{BTreeSet, HashMap};
use crate::syntax::{ast::App, Settings}; use crate::syntax::ast::App;
pub fn app(app: &mut App, settings: &Settings) { pub fn app(app: &mut App, settings: &Settings) {
// "compress" priorities // "compress" priorities

View file

@ -20,15 +20,15 @@ use crate::syntax::{
App, AppArgs, HardwareTaskArgs, IdleArgs, InitArgs, MonotonicArgs, SoftwareTaskArgs, App, AppArgs, HardwareTaskArgs, IdleArgs, InitArgs, MonotonicArgs, SoftwareTaskArgs,
TaskLocal, TaskLocal,
}, },
Either, Settings, Either,
}; };
// Parse the app, both app arguments and body (input) // Parse the app, both app arguments and body (input)
pub fn app(args: TokenStream2, input: TokenStream2, settings: &Settings) -> parse::Result<App> { pub fn app(args: TokenStream2, input: TokenStream2) -> parse::Result<App> {
let args = AppArgs::parse(args)?; let args = AppArgs::parse(args)?;
let input: Input = syn::parse2(input)?; let input: Input = syn::parse2(input)?;
App::parse(args, input, settings) App::parse(args, input)
} }
pub(crate) struct Input { pub(crate) struct Input {
@ -188,10 +188,7 @@ fn idle_args(tokens: TokenStream2) -> parse::Result<IdleArgs> {
.parse2(tokens) .parse2(tokens)
} }
fn task_args( fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, SoftwareTaskArgs>> {
tokens: TokenStream2,
settings: &Settings,
) -> parse::Result<Either<HardwareTaskArgs, SoftwareTaskArgs>> {
(|input: ParseStream<'_>| -> parse::Result<Either<HardwareTaskArgs, SoftwareTaskArgs>> { (|input: ParseStream<'_>| -> parse::Result<Either<HardwareTaskArgs, SoftwareTaskArgs>> {
if input.is_empty() { if input.is_empty() {
return Ok(Either::Right(SoftwareTaskArgs::default())); return Ok(Either::Right(SoftwareTaskArgs::default()));
@ -242,14 +239,7 @@ fn task_args(
let _: Token![=] = content.parse()?; let _: Token![=] = content.parse()?;
match &*ident_s { match &*ident_s {
"binds" if !settings.parse_binds => { "binds" => {
return Err(parse::Error::new(
ident.span(),
"Unexpected bind in task argument. Binds are only parsed if Settings::parse_binds is set.",
));
}
"binds" if settings.parse_binds => {
if binds.is_some() { if binds.is_some() {
return Err(parse::Error::new( return Err(parse::Error::new(
ident.span(), ident.span(),

View file

@ -15,7 +15,7 @@ use crate::syntax::{
LocalResource, Monotonic, MonotonicArgs, SharedResource, SoftwareTask, LocalResource, Monotonic, MonotonicArgs, SharedResource, SoftwareTask,
}, },
parse::{self as syntax_parse, util}, parse::{self as syntax_parse, util},
Either, Map, Set, Settings, Either, Map, Set,
}; };
impl AppArgs { impl AppArgs {
@ -142,7 +142,7 @@ impl AppArgs {
} }
impl App { impl App {
pub(crate) fn parse(args: AppArgs, input: Input, settings: &Settings) -> parse::Result<Self> { pub(crate) fn parse(args: AppArgs, input: Input) -> parse::Result<Self> {
let mut init = None; let mut init = None;
let mut idle = None; let mut idle = None;
@ -253,7 +253,7 @@ impl App {
)); ));
} }
match syntax_parse::task_args(item.attrs.remove(pos).tokens, settings)? { match syntax_parse::task_args(item.attrs.remove(pos).tokens)? {
Either::Left(args) => { Either::Left(args) => {
check_binding(&args.binds)?; check_binding(&args.binds)?;
check_ident(&item.sig.ident)?; check_ident(&item.sig.ident)?;
@ -410,10 +410,7 @@ impl App {
)); ));
} }
match syntax_parse::task_args( match syntax_parse::task_args(item.attrs.remove(pos).tokens)? {
item.attrs.remove(pos).tokens,
settings,
)? {
Either::Left(args) => { Either::Left(args) => {
check_binding(&args.binds)?; check_binding(&args.binds)?;
check_ident(&item.sig.ident)?; check_ident(&item.sig.ident)?;

View file

@ -1,6 +1,6 @@
#![no_main] #![no_main]
#[rtic_macros::mock_app(parse_extern_interrupt, parse_binds, device = mock, dispatchers = [EXTI0])] #[rtic_macros::mock_app(device = mock, dispatchers = [EXTI0])]
mod app { mod app {
#[shared] #[shared]
struct Shared {} struct Shared {}

View file

@ -1,6 +1,6 @@
#![no_main] #![no_main]
#[rtic_macros::mock_app(parse_binds, device = mock)] #[rtic_macros::mock_app(device = mock)]
mod app { mod app {
#[task(binds = UART0)] #[task(binds = UART0)]
fn foo(_: foo::Context) {} fn foo(_: foo::Context) {}

View file

@ -1,6 +1,6 @@
#![no_main] #![no_main]
#[rtic_macros::mock_app(parse_extern_interrupt, parse_binds, device = mock)] #[rtic_macros::mock_app(device = mock)]
mod app { mod app {
#[monotonic(binds = Tim1)] #[monotonic(binds = Tim1)]
type Fast1 = hal::Tim1Monotonic; type Fast1 = hal::Tim1Monotonic;

View file

@ -1,7 +0,0 @@
#![no_main]
#[rtic_macros::mock_app(device = mock)]
mod app {
#[task(binds = UART0)]
fn foo(_: foo::Context) {}
}

View file

@ -1,5 +0,0 @@
error: Unexpected bind in task argument. Binds are only parsed if Settings::parse_binds is set.
--> $DIR/task-bind.rs:5:12
|
5 | #[task(binds = UART0)]
| ^^^^^

View file

@ -1,6 +1,6 @@
#![no_main] #![no_main]
#[rtic_macros::mock_app(parse_binds, device = mock)] #[rtic_macros::mock_app(device = mock)]
mod app { mod app {
#[task(binds = SysTick, only_same_priority_spawn_please_fix_me)] #[task(binds = SysTick, only_same_priority_spawn_please_fix_me)]
fn foo(_: foo::Context) {} fn foo(_: foo::Context) {}

View file

@ -1,6 +1,6 @@
#![no_main] #![no_main]
#[rtic_macros::mock_app(parse_binds, device = mock)] #[rtic_macros::mock_app(device = mock)]
mod app { mod app {
#[task(binds = SysTick)] #[task(binds = SysTick)]
fn foo(_: foo::Context) {} fn foo(_: foo::Context) {}

View file

@ -1,6 +1,6 @@
#![no_main] #![no_main]
#[rtic_macros::mock_app(parse_binds, device = mock)] #[rtic_macros::mock_app(device = mock)]
mod app { mod app {
#[task(binds = UART0, priority = 0)] #[task(binds = UART0, priority = 0)]
fn foo(_: foo::Context) {} fn foo(_: foo::Context) {}