Merge branch 'main' into improve-repl

This commit is contained in:
Cai Bingjun 2023-02-02 15:07:52 +08:00 committed by GitHub
commit 556ce8e6aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
84 changed files with 2283 additions and 356 deletions

View file

@ -589,14 +589,14 @@ impl Parser {
fn try_reduce_elems(&mut self) -> ParseResult<ArrayInner> {
debug_call_info!(self);
if self.cur_category_is(TC::REnclosure) {
let args = Args::new(vec![], vec![], None);
let args = Args::empty();
debug_exit_info!(self);
return Ok(ArrayInner::Normal(args));
}
let first = self
.try_reduce_elem()
.map_err(|_| self.stack_dec(fn_name!()))?;
let mut elems = Args::new(vec![first], vec![], None);
let mut elems = Args::pos_only(vec![first], None);
match self.peek_kind() {
Some(Semi) => {
self.lpop();
@ -727,11 +727,11 @@ impl Parser {
Some(RParen) => {
rp = Some(self.lpop());
debug_exit_info!(self);
return Ok(Args::new(vec![], vec![], Some((lp.unwrap(), rp.unwrap()))));
return Ok(Args::pos_only(vec![], Some((lp.unwrap(), rp.unwrap()))));
}
Some(RBrace | RSqBr | Dedent) => {
debug_exit_info!(self);
return Ok(Args::new(vec![], vec![], None));
return Ok(Args::pos_only(vec![], None));
}
Some(Newline) if style.needs_parens() => {
self.skip();
@ -746,8 +746,21 @@ impl Parser {
.try_reduce_arg(in_type_args)
.map_err(|_| self.stack_dec(fn_name!()))?
{
PosOrKwArg::Pos(arg) => Args::new(vec![arg], vec![], None),
PosOrKwArg::Kw(arg) => Args::new(vec![], vec![arg], None),
PosOrKwArg::Pos(PosArg {
expr: Expr::UnaryOp(unary),
}) if unary.op.is(PreStar) => {
let pos_args = PosArg::new(unary.deconstruct().1);
Args::new(vec![], Some(pos_args), vec![], None)
}
PosOrKwArg::Pos(PosArg {
expr: Expr::TypeAsc(TypeAscription { expr, op, t_spec }),
}) if matches!(expr.as_ref(), Expr::UnaryOp(unary) if unary.op.is(PreStar)) => {
let Expr::UnaryOp(unary) = *expr else { unreachable!() };
let var_args = PosArg::new(unary.deconstruct().1.type_asc_expr(op, t_spec));
Args::new(vec![], Some(var_args), vec![], None)
}
PosOrKwArg::Pos(arg) => Args::pos_only(vec![arg], None),
PosOrKwArg::Kw(arg) => Args::new(vec![], None, vec![arg], None),
};
loop {
match self.peek_kind() {
@ -790,8 +803,8 @@ impl Parser {
}
if style.needs_parens() && self.cur_is(RParen) {
let rp = self.lpop();
let (pos_args, kw_args, _) = args.deconstruct();
args = Args::new(pos_args, kw_args, Some((lp.unwrap(), rp)));
let (pos_args, var_args, kw_args, _) = args.deconstruct();
args = Args::new(pos_args, var_args, kw_args, Some((lp.unwrap(), rp)));
break;
}
if !args.kw_is_empty() {
@ -804,6 +817,20 @@ impl Parser {
.try_reduce_arg(in_type_args)
.map_err(|_| self.stack_dec(fn_name!()))?
{
PosOrKwArg::Pos(PosArg {
expr: Expr::UnaryOp(unary),
}) if unary.op.is(PreStar) => {
args.set_var_args(PosArg::new(unary.deconstruct().1));
}
PosOrKwArg::Pos(PosArg {
expr: Expr::TypeAsc(TypeAscription { expr, op, t_spec }),
}) if matches!(expr.as_ref(), Expr::UnaryOp(unary) if unary.op.is(PreStar)) =>
{
let Expr::UnaryOp(unary) = *expr else { unreachable!() };
args.set_var_args(PosArg::new(
unary.deconstruct().1.type_asc_expr(op, t_spec),
));
}
PosOrKwArg::Pos(arg) => {
args.push_pos(arg);
}
@ -816,12 +843,12 @@ impl Parser {
Some(RParen) => {
if let Some(lp) = lp {
let rp = self.lpop();
let (pos_args, kw_args, _) = args.deconstruct();
args = Args::new(pos_args, kw_args, Some((lp, rp)));
let (pos_args, var_args, kw_args, _) = args.deconstruct();
args = Args::new(pos_args, var_args, kw_args, Some((lp, rp)));
} else {
// e.g. f(g 1)
let (pos_args, kw_args, _) = args.deconstruct();
args = Args::new(pos_args, kw_args, None);
let (pos_args, var_args, kw_args, _) = args.deconstruct();
args = Args::new(pos_args, var_args, kw_args, None);
}
break;
}
@ -839,8 +866,8 @@ impl Parser {
debug_exit_info!(self);
return Err(());
}
let (pos_args, kw_args, _) = args.deconstruct();
args = Args::new(pos_args, kw_args, Some((lp.unwrap(), rp)));
let (pos_args, var_args, kw_args, _) = args.deconstruct();
args = Args::new(pos_args, var_args, kw_args, Some((lp.unwrap(), rp)));
}
break;
}
@ -1694,11 +1721,9 @@ impl Parser {
Signature::Var(var) => {
let mut last = def.body.block.pop().unwrap();
for deco in decos.into_iter() {
last = deco.into_expr().call_expr(Args::new(
vec![PosArg::new(last)],
vec![],
None,
));
last = deco
.into_expr()
.call_expr(Args::pos_only(vec![PosArg::new(last)], None));
}
def.body.block.push(last);
let expr = Expr::Def(Def::new(Signature::Var(var), def.body));
@ -1734,7 +1759,7 @@ impl Parser {
};
if self.cur_is(RParen) {
let rparen = self.lpop();
let args = Args::new(vec![], vec![], Some((lparen, rparen)));
let args = Args::pos_only(vec![], Some((lparen, rparen)));
let unit = Tuple::Normal(NormalTuple::new(args));
debug_exit_info!(self);
return Ok(Expr::Tuple(unit));
@ -2303,7 +2328,7 @@ impl Parser {
len,
)));
}
let mut args = Args::new(vec![PosArg::new(first_elem)], vec![], None);
let mut args = Args::pos_only(vec![PosArg::new(first_elem)], None);
loop {
match self.peek_kind() {
Some(Comma) => {
@ -2372,8 +2397,22 @@ impl Parser {
) -> ParseResult<Tuple> {
debug_call_info!(self);
let mut args = match first_elem {
PosOrKwArg::Pos(pos) => Args::new(vec![pos], vec![], None),
PosOrKwArg::Kw(kw) => Args::new(vec![], vec![kw], None),
PosOrKwArg::Pos(PosArg {
expr: Expr::UnaryOp(unary),
}) if unary.op.is(PreStar) => {
let var_args = Some(PosArg::new(unary.deconstruct().1));
Args::new(vec![], var_args, vec![], None)
}
PosOrKwArg::Pos(PosArg {
expr: Expr::TypeAsc(TypeAscription { expr, op, t_spec }),
}) if matches!(expr.as_ref(), Expr::UnaryOp(unary) if unary.op.is(PreStar)) => {
let Expr::UnaryOp(unary) = *expr else { unreachable!() };
let expr = unary.deconstruct().1;
let var_args = Some(PosArg::new(expr.type_asc_expr(op, t_spec)));
Args::new(vec![], var_args, vec![], None)
}
PosOrKwArg::Pos(pos) => Args::pos_only(vec![pos], None),
PosOrKwArg::Kw(kw) => Args::new(vec![], None, vec![kw], None),
};
#[allow(clippy::while_let_loop)]
loop {
@ -2395,14 +2434,25 @@ impl Parser {
.try_reduce_arg(false)
.map_err(|_| self.stack_dec(fn_name!()))?
{
PosOrKwArg::Pos(arg) if args.kw_is_empty() => match arg.expr {
Expr::Tuple(Tuple::Normal(tup)) if tup.elems.paren.is_none() => {
args.extend_pos(tup.elems.into_iters().0);
PosOrKwArg::Pos(arg) if args.kw_is_empty() && args.var_args.is_none() => {
match arg.expr {
Expr::UnaryOp(unary) if unary.op.is(PreStar) => {
args.set_var_args(PosArg::new(unary.deconstruct().1));
}
Expr::TypeAsc(TypeAscription { expr, op, t_spec }) if matches!(expr.as_ref(), Expr::UnaryOp(unary) if unary.op.is(PreStar)) =>
{
let Expr::UnaryOp(unary) = *expr else { unreachable!() };
let expr = unary.deconstruct().1;
args.set_var_args(PosArg::new(expr.type_asc_expr(op, t_spec)));
}
Expr::Tuple(Tuple::Normal(tup)) if tup.elems.paren.is_none() => {
args.extend_pos(tup.elems.into_iters().0);
}
other => {
args.push_pos(PosArg::new(other));
}
}
other => {
args.push_pos(PosArg::new(other));
}
},
}
PosOrKwArg::Pos(arg) => {
let err = ParseError::syntax_error(
line!() as usize,
@ -2486,7 +2536,7 @@ impl Parser {
let call = Call::new(
str_func,
None,
Args::new(vec![PosArg::new(mid_expr)], vec![], None),
Args::pos_only(vec![PosArg::new(mid_expr)], None),
);
let op = Token::new(
Plus,