use crate::{Expression, Variable};
grammar;
pub Variable: Variable = {
Id => Variable(<>.to_string(), None),
<id:Id> ":" <ty:Id> => Variable(id, Some(ty)),
};
pub Expression: Expression = {
Abstraction => <>,
Application => <>,
}
Abstraction: Expression = {
<ls:(Lambda)+> <ids:(Variable)*> <term:("." Expression?)?> => {
let body = match term {
Some((_, o @ Some(_))) => o,
_ => None,
};
Expression::build_abs(ls.len(), ids, body)
},
}
Application: Expression = {
// NOTE: Base case of terminals is here to allow the `Application`
// production to be left associative.
Terminal => <>,
<e1:Application> <e2:Terminal> => {
app!({e1},{e2})
}
}
Terminal: Expression = {
Variable => Expression::Var(<>),
"(" <e:Expression> ")" => e,
}
Lambda = {
"λ",
"\\",
}
Id: String = r"[a-zA-Z0-9-_]+" => {
<>.to_string()
};