1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
use crate::ast::Module;
use crate::ast::ModuleItem;
use crate::ast::Node;
use crate::error::SyntaxResult;
use crate::parse::Parser;
use crate::token::TokenType;

impl<'a> Parser<'a> {
  pub fn parse_module(&mut self) -> SyntaxResult<Module> {
    let mut items = vec![];
    while !self.consume_if(TokenType::EOF)?.is_match() {
      if self.peek()?.typ == TokenType::KeywordImpl {
        items.push(self.parse_module_impl()?);
        self.require(TokenType::Semicolon)?;
      } else {
        let statement = self.parse_stmt(true)?;
        items.push(self.new_module_item(statement.loc, ModuleItem::Statement { statement }));
      };
    }
    Ok(Module { items })
  }

  pub fn parse_module_impl(&mut self) -> SyntaxResult<Node<ModuleItem>> {
    let loc_start = self.require(TokenType::KeywordImpl)?.loc;
    let (_, name) = self.require_identifier_as_string()?;
    self.require(TokenType::BraceOpen)?;
    let mut methods = vec![];
    loop {
      if self.peek()?.typ == TokenType::BraceClose {
        break;
      };
      let (_, name) = self.require_identifier_as_string()?;
      let closure = self.parse_expr_closure()?;
      methods.push((name, closure));
      self.require(TokenType::Semicolon)?;
    }
    let loc_end = self.require(TokenType::BraceClose)?.loc;
    Ok(self.new_module_item(loc_start + loc_end, ModuleItem::Impl { name, methods }))
  }
}