diff --git a/src/item.rs b/src/item.rs index 72c9185..08d723f 100644 --- a/src/item.rs +++ b/src/item.rs @@ -13,6 +13,7 @@ pub(crate) enum Item<'src> { relative: StringLiteral<'src>, }, Module { + attributes: BTreeSet>, absolute: Option, doc: Option<&'src str>, name: Name<'src>, diff --git a/src/parser.rs b/src/parser.rs index 6a18d5f..59a3d0e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -373,27 +373,7 @@ impl<'run, 'src> Parser<'run, 'src> { || self.next_are(&[Identifier, QuestionMark]) => { let doc = pop_doc_comment(&mut items, eol_since_last_comment); - - self.presume_keyword(Keyword::Mod)?; - - let optional = self.accepted(QuestionMark)?; - - let name = self.parse_name()?; - - let relative = if self.next_is(StringToken) || self.next_are(&[Identifier, StringToken]) - { - Some(self.parse_string_literal()?) - } else { - None - }; - - items.push(Item::Module { - absolute: None, - doc, - name, - optional, - relative, - }); + items.push(self.parse_module(BTreeSet::new(), doc)?); } Some(Keyword::Set) if self.next_are(&[Identifier, Identifier, ColonEquals]) @@ -430,6 +410,17 @@ impl<'run, 'src> Parser<'run, 'src> { Some(Keyword::Alias) if self.next_are(&[Identifier, Identifier, ColonEquals]) => { items.push(Item::Alias(self.parse_alias(attributes)?)); } + Some(Keyword::Mod) + if self.next_are(&[Identifier, Identifier, Comment]) + || self.next_are(&[Identifier, Identifier, Eof]) + || self.next_are(&[Identifier, Identifier, Eol]) + || self.next_are(&[Identifier, Identifier, Identifier, StringToken]) + || self.next_are(&[Identifier, Identifier, StringToken]) + || self.next_are(&[Identifier, QuestionMark]) => + { + let doc = pop_doc_comment(&mut items, eol_since_last_comment); + items.push(self.parse_module(attributes, doc)?); + } _ => { let quiet = self.accepted(At)?; let doc = pop_doc_comment(&mut items, eol_since_last_comment); @@ -454,6 +445,33 @@ impl<'run, 'src> Parser<'run, 'src> { } } + fn parse_module( + &mut self, + attributes: BTreeSet>, + doc: Option<&'src str>, + ) -> CompileResult<'src, Item<'src>> { + self.presume_keyword(Keyword::Mod)?; + + let optional = self.accepted(QuestionMark)?; + + let name = self.parse_name()?; + + let relative = if self.next_is(StringToken) || self.next_are(&[Identifier, StringToken]) { + Some(self.parse_string_literal()?) + } else { + None + }; + + Ok(Item::Module { + attributes, + absolute: None, + doc, + name, + optional, + relative, + }) + } + /// Parse an alias, e.g `alias name := target` fn parse_alias( &mut self,