Add: parse set literal

This commit is contained in:
GreasySlug 2022-10-03 17:00:00 +09:00
parent 9d4949c70f
commit bc63e9c9cb
2 changed files with 54 additions and 4 deletions

View file

@ -194,6 +194,10 @@ impl Args {
&self.kw_args[..] &self.kw_args[..]
} }
pub fn has_pos_arg(&self, pa: &PosArg) -> bool {
self.pos_args.contains(pa)
}
pub fn into_iters( pub fn into_iters(
self, self,
) -> ( ) -> (
@ -765,8 +769,8 @@ impl_locational_for_enum!(Record; Normal, Shortened);
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct NormalSet { pub struct NormalSet {
l_brace: Token, pub l_brace: Token,
r_brace: Token, pub r_brace: Token,
pub elems: Args, pub elems: Args,
} }

View file

@ -1790,8 +1790,54 @@ impl Parser {
todo!() todo!()
} }
fn try_reduce_set(&mut self, _l_brace: Token, _first: Expr) -> ParseResult<Set> { fn try_reduce_set(&mut self, l_brace: Token, first_elem: Expr) -> ParseResult<Set> {
todo!() debug_call_info!(self);
let mut args = Args::new(vec![PosArg::new(first_elem)], vec![], None);
loop {
match self.peek() {
Some(t) if t.is(Comma) => {
self.skip();
if self.cur_is(Comma) {
self.level -= 1;
let err = self.skip_and_throw_syntax_err(caused_by!());
self.errs.push(err);
return Err(());
} else if self.cur_is(RBrace) {
let set = Set::Normal(NormalSet::new(l_brace, self.lpop(), args));
self.level -= 1;
return Ok(set);
}
match self.try_reduce_arg(false).map_err(|_| self.stack_dec())? {
PosOrKwArg::Pos(arg) => match arg.expr {
Expr::Set(Set::Normal(set)) if set.elems.paren.is_none() => {
args.extend_pos(set.elems.into_iters().0);
}
other => {
let pos = PosArg::new(other);
if !args.has_pos_arg(&pos) {
args.push_pos(pos);
}
}
},
PosOrKwArg::Kw(arg) => {
self.level -= 1;
let err = ParseError::simple_syntax_error(line!() as usize, arg.loc());
self.errs.push(err);
return Err(());
}
}
}
Some(t) if t.is(RBrace) => {
let set = Set::Normal(NormalSet::new(l_brace, self.lpop(), args));
self.level -= 1;
return Ok(set);
}
_ => {
break;
}
}
}
Err(())
} }
fn try_reduce_tuple(&mut self, first_elem: Expr) -> ParseResult<Tuple> { fn try_reduce_tuple(&mut self, first_elem: Expr) -> ParseResult<Tuple> {