Add support for grouping statements
This commit is contained in:
parent
dc288588c8
commit
ced609265c
|
@ -123,5 +123,17 @@ fn compile_statement(statement: &Statement) -> Option<Command> {
|
|||
let content = doccomment.content();
|
||||
Some(Command::Comment(content.to_string()))
|
||||
}
|
||||
Statement::Grouping(group) => {
|
||||
let statements = group.block().statements();
|
||||
let commands = statements
|
||||
.iter()
|
||||
.filter_map(compile_statement)
|
||||
.collect::<Vec<_>>();
|
||||
if commands.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(Command::Group(commands))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ pub enum KeywordKind {
|
|||
Function,
|
||||
If,
|
||||
Else,
|
||||
Group,
|
||||
}
|
||||
|
||||
impl ToString for KeywordKind {
|
||||
|
@ -61,6 +62,7 @@ impl KeywordKind {
|
|||
Self::Function => "fn",
|
||||
Self::If => "if",
|
||||
Self::Else => "else",
|
||||
Self::Group => "group",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ use super::expression::ParenthesizedCondition;
|
|||
/// Block
|
||||
/// | LiteralCommand
|
||||
/// | Conditional
|
||||
/// | Grouping
|
||||
/// | DocComment
|
||||
/// ;
|
||||
/// ```
|
||||
|
@ -35,6 +36,7 @@ pub enum Statement {
|
|||
Block(Block),
|
||||
LiteralCommand(CommandLiteral),
|
||||
Conditional(Conditional),
|
||||
Grouping(Grouping),
|
||||
DocComment(DocComment),
|
||||
}
|
||||
|
||||
|
@ -44,6 +46,7 @@ impl SourceElement for Statement {
|
|||
Self::Block(block) => block.span(),
|
||||
Self::LiteralCommand(literal_command) => literal_command.span(),
|
||||
Self::Conditional(conditional) => conditional.span(),
|
||||
Self::Grouping(grouping) => grouping.span(),
|
||||
Self::DocComment(doc_comment) => doc_comment.span(),
|
||||
}
|
||||
}
|
||||
|
@ -136,6 +139,40 @@ impl SourceElement for Conditional {
|
|||
}
|
||||
}
|
||||
|
||||
/// Syntax Synopsis:
|
||||
///
|
||||
/// ``` ebnf
|
||||
/// Grouping:
|
||||
/// 'group' Block
|
||||
/// ;
|
||||
/// ````
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)]
|
||||
pub struct Grouping {
|
||||
/// The `group` keyword.
|
||||
#[get = "pub"]
|
||||
group_keyword: Keyword,
|
||||
/// The block of the conditional.
|
||||
#[get = "pub"]
|
||||
block: Block,
|
||||
}
|
||||
|
||||
impl Grouping {
|
||||
/// Dissolves the [`Grouping`] into its components.
|
||||
#[must_use]
|
||||
pub fn dissolve(self) -> (Keyword, Block) {
|
||||
(self.group_keyword, self.block)
|
||||
}
|
||||
}
|
||||
|
||||
impl SourceElement for Grouping {
|
||||
fn span(&self) -> Span {
|
||||
self.group_keyword
|
||||
.span()
|
||||
.join(&self.block.span())
|
||||
.expect("The span of the grouping is invalid.")
|
||||
}
|
||||
}
|
||||
|
||||
/// Syntax Synopsis:
|
||||
///
|
||||
/// ``` ebnf
|
||||
|
@ -262,11 +299,27 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// doc comment
|
||||
Reading::Atomic(Token::DocComment(doc_comment)) => {
|
||||
self.forward();
|
||||
Some(Statement::DocComment(doc_comment))
|
||||
}
|
||||
|
||||
// grouping statement
|
||||
Reading::Atomic(Token::Keyword(group_keyword))
|
||||
if group_keyword.keyword == KeywordKind::Group =>
|
||||
{
|
||||
// eat the group keyword
|
||||
self.forward();
|
||||
|
||||
let block = self.parse_block(handler)?;
|
||||
|
||||
Some(Statement::Grouping(Grouping {
|
||||
group_keyword,
|
||||
block,
|
||||
}))
|
||||
}
|
||||
|
||||
// other
|
||||
unexpected => {
|
||||
handler.receive(Error::UnexpectedSyntax(UnexpectedSyntax {
|
||||
|
|
Loading…
Reference in New Issue