summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chomp/check/inline.rs119
-rw-r--r--src/chomp/error.rs17
-rw-r--r--src/lower/rust.rs5
3 files changed, 136 insertions, 5 deletions
diff --git a/src/chomp/check/inline.rs b/src/chomp/check/inline.rs
index 43a2eb8..da501f1 100644
--- a/src/chomp/check/inline.rs
+++ b/src/chomp/check/inline.rs
@@ -158,7 +158,7 @@ mod tests {
None,
)
.into(),
- None
+ None,
);
let inlined = expr.fold(&mut InlineCalls::new(function));
assert_eq!(
@@ -208,7 +208,7 @@ mod tests {
None,
)
.into(),
- None
+ None,
);
let inlined = expr.fold(&mut InlineCalls::new(function));
assert_eq!(
@@ -231,4 +231,119 @@ mod tests {
.into())
)
}
+
+ #[test]
+ fn test_inline_double_subst() {
+ let expr = Call::new(
+ Name::Spanless("opt".to_string()),
+ vec![Call::new(
+ Name::Spanless("opt".to_string()),
+ vec![Literal::Spanless("x".to_string()).into()],
+ None,
+ )
+ .into()],
+ None,
+ );
+ let inlined = expr.fold(&mut InlineCalls::new(opt()));
+ assert_eq!(
+ inlined,
+ Ok(Alt::new(
+ Epsilon::default().into(),
+ None,
+ Alt::new(
+ Epsilon::default().into(),
+ None,
+ Literal::Spanless("x".to_string()).into()
+ )
+ .into()
+ )
+ .into())
+ )
+ }
+
+ #[test]
+ fn test_inline_call_args() {
+ let expr = Fix::new(
+ Name::Spanless("rec".to_string()),
+ Cat::new(
+ Literal::Spanless("a".to_string()).into(),
+ None,
+ Call::new(
+ Name::Spanless("opt".to_string()),
+ vec![Cat::new(
+ Cat::new(
+ Literal::Spanless("a".to_string()).into(),
+ None,
+ Fix::new(
+ Name::Spanless("star".to_string()),
+ Call::new(
+ Name::Spanless("opt".to_string()),
+ vec![Cat::new(
+ Literal::Spanless(" ".to_string()).into(),
+ None,
+ Variable::new(Name::Spanless("star".to_string()), 0).into(),
+ )
+ .into()],
+ None,
+ )
+ .into(),
+ None,
+ )
+ .into(),
+ )
+ .into(),
+ None,
+ Variable::new(Name::Spanless("rec".to_string()), 0).into(),
+ )
+ .into()],
+ None,
+ )
+ .into(),
+ )
+ .into(),
+ None,
+ );
+ let inlined = expr.fold(&mut InlineCalls::new(opt()));
+ assert_eq!(inlined,
+ Ok(Fix::new(
+ Name::Spanless("rec".to_string()),
+ Cat::new(
+ Literal::Spanless("a".to_string()).into(),
+ None,
+ Alt::new(
+ Epsilon::default().into(),
+ None,
+ Cat::new(
+ Cat::new(
+ Literal::Spanless("a".to_string()).into(),
+ None,
+ Fix::new(
+ Name::Spanless("star".to_string()),
+ Alt::new(
+ Epsilon::default().into(),
+ None,
+ Cat::new(
+ Literal::Spanless(" ".to_string()).into(),
+ None,
+ Variable::new(Name::Spanless("star".to_string()), 0).into(),
+ )
+ .into()
+ )
+ .into(),
+ None,
+ )
+ .into(),
+ )
+ .into(),
+ None,
+ Variable::new(Name::Spanless("rec".to_string()), 0).into(),
+ )
+ .into(),
+ )
+ .into(),
+ )
+ .into(),
+ None,
+ ).into()))
+ }
}
diff --git a/src/chomp/error.rs b/src/chomp/error.rs
index ffcbdd0..e7e4660 100644
--- a/src/chomp/error.rs
+++ b/src/chomp/error.rs
@@ -358,6 +358,19 @@ pub enum SubstituteError {
WrongArgCount { call: Call, expected: usize },
}
+impl From<SubstituteError> for syn::Error {
+ fn from(e: SubstituteError) -> Self {
+ match e {
+ SubstituteError::FreeParameter(param) => {
+ Self::new(param.name().span().unwrap_or_else(Span::call_site), format!("undeclared variable `{}'", param.name()))
+ }
+ SubstituteError::WrongArgCount { call, expected } => {
+ Self::new(call.span().unwrap_or_else(Span::call_site), format!("wrong number of arguments. Expected {}, got {}", expected, call.args().len()))
+ }
+ }
+ }
+}
+
impl Display for SubstituteError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
@@ -378,8 +391,8 @@ impl Display for SubstituteError {
"{}:{}: wrong number of arguments. Expected {}, got {}",
start.line,
start.column,
- call.args().len(),
- expected
+ expected,
+ call.args().len()
)
}
}
diff --git a/src/lower/rust.rs b/src/lower/rust.rs
index 74deb73..7931306 100644
--- a/src/lower/rust.rs
+++ b/src/lower/rust.rs
@@ -75,7 +75,7 @@ impl Backend for RustBackend {
impl Parse for #name {
fn take<P: Parser + ?Sized>(input: &mut P) -> Result<Self, TakeError> {
- input.take_str(#lit).map(|()| #name)
+ input.consume_str(#lit).map(|()| #name)
}
}
};
@@ -206,8 +206,11 @@ impl Backend for RustBackend {
TokenStream::new(),
BTreeSet::new(),
));
+
self.context.push(id);
let inner = inner.gen(self);
+ self.context.pop();
+
let inner_ty = self.data[inner].0.clone();
let tokens = quote! {
#[derive(Clone, Debug, Eq, Hash, PartialEq)]