diff --git a/cl-parser/src/error.rs b/cl-parser/src/error.rs index 6b628f8..6988bae 100644 --- a/cl-parser/src/error.rs +++ b/cl-parser/src/error.rs @@ -22,10 +22,13 @@ pub enum ErrorKind { UnmatchedCurlyBraces, UnmatchedSquareBrackets, Unexpected(TokenKind), - Expected { + ExpectedToken { want: TokenKind, got: TokenKind, }, + ExpectedParsing { + want: Parsing, + }, /// No rules matched Nothing, /// Indicates unfinished code @@ -67,6 +70,7 @@ pub enum Parsing { Variant, VariantKind, Impl, + ImplKind, Ty, TyKind, @@ -129,9 +133,12 @@ impl Display for ErrorKind { ErrorKind::UnmatchedCurlyBraces => write!(f, "Unmatched curly braces"), ErrorKind::UnmatchedSquareBrackets => write!(f, "Unmatched square brackets"), ErrorKind::Unexpected(t) => write!(f, "Encountered unexpected token `{t}`"), - ErrorKind::Expected { want: e, got: g } => { + ErrorKind::ExpectedToken { want: e, got: g } => { write!(f, "Expected `{e}`, got `{g}`") } + ErrorKind::ExpectedParsing { want } => { + write!(f, "Expected {want}") + } ErrorKind::Nothing => write!(f, "Nothing found"), ErrorKind::Todo => write!(f, "TODO:"), } @@ -164,6 +171,7 @@ impl Display for Parsing { Parsing::Variant => "an enum variant", Parsing::VariantKind => "an enum variant", Parsing::Impl => "an impl block", + Parsing::ImplKind => "the target of an impl block", Parsing::Ty => "a type", Parsing::TyKind => "a type", diff --git a/cl-parser/src/parser.rs b/cl-parser/src/parser.rs index 862ed5f..4afedb6 100644 --- a/cl-parser/src/parser.rs +++ b/cl-parser/src/parser.rs @@ -80,7 +80,7 @@ impl<'t> Parser<'t> { if got == want { Ok(self.consume_peeked().expect("should not fail after peek")) } else { - Err(self.error(Expected { want, got }, while_parsing)) + Err(self.error(ExpectedToken { want, got }, while_parsing)) } } #[inline] @@ -263,9 +263,11 @@ impl<'t> Parser<'t> { ); Ok(Attrs { meta: meta(self)? }) } + /// Parses a single [attribute](Meta) pub fn meta(&mut self) -> PResult { Ok(Meta { name: self.identifier()?, kind: self.meta_kind()? }) } + /// Parses data associated with a [Meta] attribute pub fn meta_kind(&mut self) -> PResult { const PARSING: Parsing = Parsing::Meta; let lit_tuple = delim( @@ -303,9 +305,11 @@ impl<'t> Parser<'t> { }) } + /// Parses a [`type` alias](Alias) pub fn parse_alias(&mut self) -> PResult { const PARSING: Parsing = Parsing::Alias; self.match_type(TokenKind::Type, PARSING)?; + let out = Ok(Alias { to: self.identifier()?, from: if self.match_op(Punct::Eq, PARSING).is_ok() { @@ -318,9 +322,11 @@ impl<'t> Parser<'t> { out } + /// Parses a [compile-time constant](Const) pub fn parse_const(&mut self) -> PResult { const PARSING: Parsing = Parsing::Const; self.match_type(TokenKind::Const, PARSING)?; + let out = Ok(Const { name: self.identifier()?, ty: { @@ -335,9 +341,12 @@ impl<'t> Parser<'t> { self.match_op(Punct::Semi, PARSING)?; out } + + /// Parses a [`static` item](Static) pub fn parse_static(&mut self) -> PResult { const PARSING: Parsing = Parsing::Static; self.match_type(TokenKind::Static, PARSING)?; + let out = Ok(Static { mutable: self.mutability()?, name: self.identifier()?, @@ -353,11 +362,16 @@ impl<'t> Parser<'t> { self.match_op(Punct::Semi, PARSING)?; out } + + /// Parses a [Module] pub fn parse_module(&mut self) -> PResult { const PARSING: Parsing = Parsing::Module; self.match_type(TokenKind::Mod, PARSING)?; + Ok(Module { name: self.identifier()?, kind: self.modulekind()? }) } + + /// Parses the item list associated with a [Module], if present pub fn modulekind(&mut self) -> PResult { const PARSING: Parsing = Parsing::ModuleKind; let inline = delim(Self::file, CURLIES, PARSING); @@ -369,14 +383,17 @@ impl<'t> Parser<'t> { Ok(ModuleKind::Outline) } got => Err(self.error( - Expected { want: TokenKind::Punct(Punct::Semi), got }, + ExpectedToken { want: TokenKind::Punct(Punct::Semi), got }, PARSING, )), } } + + /// Parses a [Function] definition pub fn parse_function(&mut self) -> PResult { const PARSING: Parsing = Parsing::Function; self.match_type(TokenKind::Fn, PARSING)?; + Ok(Function { name: self.identifier()?, args: self.parse_params()?, @@ -387,7 +404,7 @@ impl<'t> Parser<'t> { Some(self.ty()?.into()) } got => Err(self.error( - Expected { want: TokenKind::Punct(Punct::Arrow), got }, + ExpectedToken { want: TokenKind::Punct(Punct::Arrow), got }, PARSING, ))?, }, @@ -401,6 +418,8 @@ impl<'t> Parser<'t> { }, }) } + + /// Parses the [parameters](Param) associated with a Function pub fn parse_params(&mut self) -> PResult> { const PARSING: Parsing = Parsing::Function; delim( @@ -409,6 +428,8 @@ impl<'t> Parser<'t> { PARSING, )(self) } + + /// Parses a single function [parameter](Param) pub fn parse_param(&mut self) -> PResult { Ok(Param { mutability: self.mutability()?, @@ -419,9 +440,12 @@ impl<'t> Parser<'t> { }, }) } + + /// Parses a [`struct` definition](Struct) pub fn parse_struct(&mut self) -> PResult { const PARSING: Parsing = Parsing::Struct; self.match_type(TokenKind::Struct, PARSING)?; + Ok(Struct { name: self.identifier()?, kind: match self.peek_kind(PARSING)? { @@ -432,12 +456,14 @@ impl<'t> Parser<'t> { StructKind::Empty } got => Err(self.error( - Expected { want: TokenKind::Punct(Punct::Semi), got }, + ExpectedToken { want: TokenKind::Punct(Punct::Semi), got }, PARSING, ))?, }, }) } + + /// Parses a [tuple-`struct`](StructKind::Tuple)'s members pub fn structkind_tuple(&mut self) -> PResult { const PARSING: Parsing = Parsing::StructKind; @@ -447,14 +473,19 @@ impl<'t> Parser<'t> { PARSING, )(self)?)) } + + /// Parses a [`struct`](StructKind::Struct)s members pub fn structkind_struct(&mut self) -> PResult { const PARSING: Parsing = Parsing::StructKind; + Ok(StructKind::Struct(delim( sep(Self::struct_member, Punct::Comma, CURLIES.1, PARSING), CURLIES, PARSING, )(self)?)) } + + /// Parses a single [StructMember] pub fn struct_member(&mut self) -> PResult { const PARSING: Parsing = Parsing::StructMember; Ok(StructMember { @@ -466,10 +497,13 @@ impl<'t> Parser<'t> { }, }) } + + /// Parses an [`enum`](Enum) definition pub fn parse_enum(&mut self) -> PResult { - // Enum = "enum" Identifier '{' (Variant ',')* Variant? '}' ; const PARSING: Parsing = Parsing::Enum; + self.match_type(TokenKind::Enum, PARSING)?; + Ok(Enum { name: self.identifier()?, kind: match self.peek_kind(PARSING)? { @@ -487,8 +521,10 @@ impl<'t> Parser<'t> { }) } + /// Parses an [`enum`](Enum) [Variant] pub fn enum_variant(&mut self) -> PResult { const PARSING: Parsing = Parsing::Variant; + Ok(Variant { name: self.identifier()?, kind: match self.peek_kind(PARSING)? { @@ -499,15 +535,21 @@ impl<'t> Parser<'t> { }, }) } + + /// Parses a [C-like](VariantKind::CLike) [`enum`](Enum) [Variant] pub fn variantkind_clike(&mut self) -> PResult { const PARSING: Parsing = Parsing::VariantKind; + self.match_op(Punct::Eq, PARSING)?; let tok = self.match_type(TokenKind::Literal, PARSING)?; + Ok(VariantKind::CLike(match tok.data() { TokenData::Integer(i) => *i, _ => panic!("Expected token data for {tok:?} while parsing {PARSING}"), })) } + + /// Parses a [struct-like](VariantKind::Struct) [`enum`](Enum) [Variant] pub fn variantkind_struct(&mut self) -> PResult { const PARSING: Parsing = Parsing::VariantKind; Ok(VariantKind::Struct(delim( @@ -516,6 +558,8 @@ impl<'t> Parser<'t> { PARSING, )(self)?)) } + + /// Parses a [tuple-like](VariantKind::Tuple) [`enum`](Enum) [Variant] pub fn variantkind_tuple(&mut self) -> PResult { const PARSING: Parsing = Parsing::VariantKind; Ok(VariantKind::Tuple(delim( @@ -527,6 +571,7 @@ impl<'t> Parser<'t> { pub fn parse_impl(&mut self) -> PResult { const PARSING: Parsing = Parsing::Impl; + self.match_type(TokenKind::Impl, PARSING)?; Err(self.error(Todo, PARSING)) }