Skip to content
Snippets Groups Projects
Commit 404a781d authored by pln's avatar pln
Browse files

sketch of crc abstraction

parent de349bf3
No related branches found
No related tags found
No related merge requests found
......@@ -189,7 +189,7 @@ fn tasks(tasks: Option<::Tasks>) -> Result<Tasks> {
})
}
/// `crc! { .. }`
/// `cro! { .. }`
#[derive(Debug)]
pub struct Cro {
/// `crcs: Crcs`
......@@ -198,7 +198,7 @@ pub struct Cro {
pub ops: ::Ops,
}
/// Checks the syntax of the parsed `app!` macro
/// Checks the syntax of the parsed `cro!` macro
pub fn cro(cro: ::Cro) -> Result<Cro> {
Ok(Cro {
ips: ::check::ips(cro.ips).chain_err(|| "checking `ips`")?,
......@@ -212,7 +212,7 @@ pub fn ips(ips: Option<::Ips>) -> Result<::Ips> {
Ok(if let Some(ips) = ips {
ensure!(
!ips.is_empty(),
"empty `ips` field. Each Crc must have at least one input port"
"empty `ips` field. Each Cro must have at least one input port"
);
ips
} else {
......@@ -229,3 +229,32 @@ pub fn ops(ops: Option<::Ops>) -> Result<::Ops> {
//Ops::new()
})
}
/// `crc! { .. }`
#[derive(Debug)]
pub struct Crc {
/// `crcs: Crcs`
pub crcs: ::Crcs,
}
/// Checks the syntax of the parsed `crc!` macro
pub fn crc(crc: ::Crc) -> Result<Crc> {
Ok(Crc {
crcs: ::check::crcs(crc.crcs).chain_err(|| "checking `crcs`")?,
})
}
///
pub fn crcs(crcs: Option<::Crcs>) -> Result<Crcs> {
Ok(if let Some(crcs) = crcs {
ensure!(
!crcs.is_empty(),
"empty `crcs` field. Each Crc must have at least one inner component"
);
crcs
} else {
bail!("missing `crcs` field")
})
}
......@@ -102,9 +102,6 @@ impl App {
/// Crc related
/// `$($Ident: $Path,)*`
pub type Crcs = HashMap<Ident, Path>;
/// Input port binding
#[derive(Debug)]
pub enum IpTo {
......@@ -136,3 +133,28 @@ impl Cro {
parse::cro(input)
}
}
// Crc related
/// `$($Ident: $Path,)*`
pub type Crcs = HashMap<Ident, (Path, OpBind)>;
/// `$($Ident: $Path,)*`
pub type OpBind = HashMap<Ident, Path>;
/// `crc! { .. }`
#[derive(Debug)]
pub struct Crc {
/// Crcs are the inner Cro/Crcs
pub crcs: Option<Crcs>,
// /// Input ports (should not be None, given we have interrupts at top level)
// pub ips: Option<Ips>,
// /// Output ports (should not be None, given we treat peripherals as Crcs)
// pub ops: Option<Ops>,
}
impl Crc {
/// Parses the contents of the `sys! { .. }` macro
pub fn parse(input: &str) -> Result<Self> {
parse::crc(input)
}
}
......@@ -7,8 +7,8 @@ use syn::{self, DelimToken, Ident, IntTy, Lit, Path, Token, BinOpToken,
use error::*;
use {Cro, Ips, Ops, App, Idle, Init, Resources, Static, Statics, Task, Tasks,
Expr};
use {Cro, Ips, Ops, Crc, Crcs, OpBind, App, Idle, Init, Resources, Static,
Statics, Task, Tasks, Expr};
/// Parses the contents of `app! { $App }`
pub fn app(input: &str) -> Result<App> {
......@@ -435,7 +435,7 @@ fn u8(tt: Option<&TokenTree>) -> Result<u8> {
}
}
/// Parses the contents of `crc! { $Crc }`
/// Parses the contents of `cro! { $Cro }`
pub fn cro(input: &str) -> Result<Cro> {
let tts = syn::parse_token_trees(input)?;
......@@ -467,8 +467,32 @@ pub fn cro(input: &str) -> Result<Cro> {
Ok(Cro { ips, ops })
}
/// Parses the contents of `crc! { $Crc }`
pub fn crc(input: &str) -> Result<Crc> {
let tts = syn::parse_token_trees(input)?;
let mut crcs = None;
fields(&tts, |key, tts| {
match key.as_ref() {
"crcs" => {
ensure!(crcs.is_none(), "duplicated `crcs` field");
crcs = Some(::parse::crcs(tts).chain_err(|| "parsing `crcs`")?);
}
_ => bail!("unknown field: `{}`", key),
}
Ok(())
})?;
Ok(Crc { crcs })
}
/*
/// Parses `$($Ident: $Path,)*`
fn crcs(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Crcs> {
::parse::delimited(tts, DelimToken::Brace, |tts| {
......@@ -495,13 +519,46 @@ fn crcs(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Crcs> {
let path = ::parse::path(&mut tts).chain_err(|| "parsing `path`")?;
tts.next();
crcs.insert(ident.clone(), path);
let op_bind =
::parse::op_bind(&mut tts).chain_err(|| "parsing `path`")?;
tts.next();
crcs.insert(ident.clone(), (path, op_bind));
}
Ok(crcs)
})
}
*/
fn op_bind(tts: &mut Peekable<Iter<TokenTree>>) -> Result<OpBind> {
::parse::delimited(tts, DelimToken::Brace, |tts| {
let mut op_bind = HashMap::new();
let mut tts = tts.iter().peekable();
while let Some(tt) = tts.next() {
let ident = if let &TokenTree::Token(Token::Ident(ref id)) = tt {
id
} else {
bail!("expected Ident, found {:?}", tt);
};
ensure!(
!op_bind.contains_key(ident),
"op {} listed more than once",
ident
);
let tt = tts.next();
if let Some(&TokenTree::Token(Token::RArrow)) = tt {
} else {
bail!("expected '->' found {:?}", tt);
}
tts.next();
let path = ::parse::path(&mut tts).chain_err(|| "parsing `path`")?;
tts.next();
op_bind.insert(ident.clone(), path);
}
Ok(op_bind)
})
}
/// Parses `$($Ident: $Ty > $Path,)*`
fn ips(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ips> {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment