arrow_parser/
parse_stmt.rs

1use crate::ast::Expression;
2use crate::ast::Node;
3use crate::ast::Statement;
4use crate::error::SyntaxErrorType;
5use crate::error::SyntaxResult;
6use crate::parse::Parser;
7use crate::symbol::ScopeType;
8use crate::token::TokenType;
9use crate::token::TokenTypeSet;
10
11impl<'a> Parser<'a> {
12  pub fn parse_stmt(&mut self, require_semicolon: bool) -> SyntaxResult<Node<Statement>> {
13    let stmt = match self.peek()?.typ {
14      TokenType::KeywordBreak => self.parse_stmt_break(),
15      TokenType::KeywordContinue => self.parse_stmt_continue(),
16      TokenType::KeywordFor => self.parse_stmt_for(),
17      TokenType::KeywordLet => self.parse_stmt_let(),
18      TokenType::KeywordLoop => self.parse_stmt_loop(),
19      TokenType::KeywordReturn => self.parse_stmt_return(),
20      _ => {
21        let expr = self.parse_expr_until(TokenTypeSet::new(&[
22          TokenType::Equals,
23          TokenType::Semicolon,
24          TokenType::BraceClose,
25        ]))?;
26        let stmt = if self.consume_if(TokenType::Equals)?.is_match() {
27          let value = self.parse_expr(TokenType::Semicolon)?;
28          self.new_statement(expr.loc + value.loc, match *expr.stx {
29            Expression::Field {
30              object,
31              field,
32              optional,
33            } => Statement::FieldAssign {
34              object,
35              field,
36              value,
37              optional,
38            },
39            Expression::Index {
40              object,
41              index,
42              optional,
43            } => Statement::IndexAssign {
44              object,
45              index,
46              value,
47              optional,
48            },
49            Expression::Var { name } => Statement::VarAssign {
50              variable: name,
51              value,
52            },
53            _ => {
54              return Err(
55                expr
56                  .loc
57                  .error(SyntaxErrorType::InvalidAssigmentTarget, None),
58              )
59            }
60          })
61        } else {
62          self.new_statement(expr.loc, Statement::Expression { expression: expr })
63        };
64        Ok(stmt)
65      }
66    }?;
67    if require_semicolon {
68      self.require(TokenType::Semicolon)?;
69    };
70    Ok(stmt)
71  }
72
73  pub fn parse_stmt_break(&mut self) -> SyntaxResult<Node<Statement>> {
74    let loc = self.require(TokenType::KeywordBreak)?.loc;
75    Ok(self.new_statement(loc, Statement::Break))
76  }
77
78  pub fn parse_stmt_continue(&mut self) -> SyntaxResult<Node<Statement>> {
79    let loc = self.require(TokenType::KeywordContinue)?.loc;
80    Ok(self.new_statement(loc, Statement::Continue))
81  }
82
83  pub fn parse_stmt_for(&mut self) -> SyntaxResult<Node<Statement>> {
84    let parent_scope = self.enter_new_scope(ScopeType::Block);
85    let loc_start = self.require(TokenType::KeywordFor)?.loc;
86    let (_, variable) = self.require_identifier_as_string()?;
87    assert!(self.scope.add_symbol(variable.clone()));
88    self.require(TokenType::KeywordIn)?;
89    let iterable = self.parse_expr(TokenType::BraceOpen)?;
90    let body = self.parse_expr_block_without_new_scope()?;
91    match body.stx.as_ref() {
92      Expression::Block {
93        result: Some(..), ..
94      } => return Err(body.loc.error(SyntaxErrorType::LoopCannotResult, None)),
95      _ => {}
96    };
97    let stmt = self.new_statement(loc_start + body.loc, Statement::For {
98      variable,
99      iterable,
100      body,
101    });
102    self.return_to_scope(parent_scope);
103    Ok(stmt)
104  }
105
106  pub fn parse_stmt_let(&mut self) -> SyntaxResult<Node<Statement>> {
107    let loc_start = self.require(TokenType::KeywordLet)?.loc;
108    let (variable_loc, variable) = self.require_identifier_as_string()?;
109    if !self.scope.add_symbol(variable.clone()) {
110      return Err(variable_loc.error(SyntaxErrorType::RedeclaredVar, None));
111    };
112    self.require(TokenType::Equals)?;
113    let value = self.parse_expr(TokenType::Semicolon)?;
114    Ok(self.new_statement(loc_start + value.loc, Statement::Let { variable, value }))
115  }
116
117  pub fn parse_stmt_loop(&mut self) -> SyntaxResult<Node<Statement>> {
118    let loc_start = self.require(TokenType::KeywordLoop)?.loc;
119    let body = self.parse_expr_block()?;
120    match body.stx.as_ref() {
121      Expression::Block {
122        result: Some(..), ..
123      } => return Err(body.loc.error(SyntaxErrorType::LoopCannotResult, None)),
124      _ => {}
125    };
126    Ok(self.new_statement(loc_start + body.loc, Statement::Loop { body }))
127  }
128
129  pub fn parse_stmt_return(&mut self) -> SyntaxResult<Node<Statement>> {
130    let loc_start = self.require(TokenType::KeywordReturn)?.loc;
131    let value = if self.peek()?.typ == TokenType::Semicolon {
132      None
133    } else {
134      Some(self.parse_expr(TokenType::Semicolon)?)
135    };
136    Ok(self.new_statement(loc_start, Statement::Return { value }))
137  }
138}