Parser - Support for blocks

This commit is contained in:
Emmanuel BENOîT 2022-12-31 17:05:58 +01:00
parent 3fe2b4256a
commit 7d22b15854

View file

@ -79,10 +79,13 @@ impl Parser {
/// statement := expression ";" /// statement := expression ";"
/// statement := "print" expression ";" /// statement := "print" expression ";"
/// statement := declaration ";" /// statement := declaration ";"
/// statement := block
/// ``` /// ```
fn parse_statement(&mut self) -> ParserResult<ast::StmtNode> { fn parse_statement(&mut self) -> ParserResult<ast::StmtNode> {
if self.expect(&[TokenType::Var]).is_some() { if self.expect(&[TokenType::Var]).is_some() {
self.parse_declaration() self.parse_declaration()
} else if self.expect(&[TokenType::LeftBrace]).is_some() {
self.parse_block()
} else if self.expect(&[TokenType::Print]).is_some() { } else if self.expect(&[TokenType::Print]).is_some() {
let expression = self.parse_expression()?; let expression = self.parse_expression()?;
self.consume(&TokenType::Semicolon, "expected ';' after value")?; self.consume(&TokenType::Semicolon, "expected ';' after value")?;
@ -115,6 +118,20 @@ impl Parser {
Ok(ast::StmtNode::VarDecl(name, initializer)) Ok(ast::StmtNode::VarDecl(name, initializer))
} }
/// Parse the following rule:
/// ```
/// block := "{" statement* "}"
/// ```
fn parse_block(&mut self) -> ParserResult<ast::StmtNode> {
let mut stmts: Vec<Box<ast::StmtNode>> = Vec::new();
while !(self.check(&TokenType::RightBrace) || self.is_at_end()) {
let stmt = self.parse_statement()?;
stmts.push(Box::new(stmt));
}
self.consume(&TokenType::RightBrace, "expected '}' after block.")?;
Ok(ast::StmtNode::Block(stmts))
}
/// Parse the following rule: /// Parse the following rule:
/// ``` /// ```
/// expression := assignment /// expression := assignment