Merge branch 'do-parse'

This commit is contained in:
Shunsuke Shibayama 2022-08-28 11:33:09 +09:00
commit f847029e16
3 changed files with 48 additions and 1 deletions

View file

@ -2269,6 +2269,15 @@ impl LambdaSignature {
bounds,
}
}
pub fn do_sig(do_symbol: &Token) -> Self {
let parens = Some((do_symbol.clone(), do_symbol.clone()));
Self::new(
Params::new(vec![], vec![], parens),
None,
TypeBoundSpecs::empty(),
)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]

View file

@ -53,6 +53,7 @@ enum PosOrKwArg {
pub enum Side {
LhsAssign,
LhsLambda,
Do,
Rhs,
}
@ -156,6 +157,15 @@ impl Parser {
/// `(Rhs) , (LhsLambda) ->`
/// `(Rhs) (LhsLambda) -> (Rhs);`
fn cur_side(&self) -> Side {
match self.peek() {
Some(t) => {
let name = &t.inspect()[..];
if name == "do" || name == "do!" {
return Side::Do;
}
}
_ => {}
}
// 以降に=, ->などがないならすべて右辺値
let opt_equal_pos = self.tokens.iter().skip(1).position(|t| t.is(Equal));
let opt_arrow_pos = self
@ -1651,6 +1661,29 @@ impl Parser {
Ok(Lambda::new(sig, op, body, self.counter))
}
fn try_reduce_do_block(&mut self) -> ParseResult<Lambda> {
debug_call_info!(self);
let do_symbol = self.lpop();
let sig = LambdaSignature::do_sig(&do_symbol);
let op = match &do_symbol.inspect()[..] {
"do" => Token::from_str(FuncArrow, "->"),
"do!" => Token::from_str(ProcArrow, "=>"),
_ => todo!(),
};
if self.cur_is(Colon) {
self.lpop();
let body = self.try_reduce_block().map_err(|_| self.stack_dec())?;
self.counter.inc();
self.level -= 1;
Ok(Lambda::new(sig, op, body, self.counter))
} else {
let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?;
let block = Block::new(vec![expr]);
self.level -= 1;
Ok(Lambda::new(sig, op, block, self.counter))
}
}
fn try_reduce_expr(&mut self) -> ParseResult<Expr> {
debug_call_info!(self);
let mut stack = Vec::<ExprOrOp>::new();
@ -1665,6 +1698,11 @@ impl Parser {
self.level -= 1;
Ok(Expr::Lambda(lambda))
}
Side::Do => {
let lambda = self.try_reduce_do_block().map_err(|_| self.stack_dec())?;
self.level -= 1;
Ok(Expr::Lambda(lambda))
}
Side::Rhs => {
stack.push(ExprOrOp::Expr(
self.try_reduce_bin_lhs().map_err(|_| self.stack_dec())?,