pipeline_script/parser/
helper.rs

1use crate::ast::r#struct::Struct;
2use crate::ast::stmt::StmtNode;
3use crate::context::Context;
4use crate::core::error::Error;
5use crate::lexer::position::Position;
6use crate::lexer::token::Token;
7use crate::parser::Parser;
8
9pub fn is_enum(ctx: &Context, id: &str) -> bool {
10    ctx.get_type_alias(id)
11        .map_or(false, |ty| ty.get_type().is_enum())
12}
13
14pub fn get_struct_from_context(ctx: &Context, name: &str) -> Option<Struct> {
15    let modules = ctx.get_module_slot_map();
16    let readable_modules = modules.read().unwrap();
17    for (_, module) in readable_modules.iter() {
18        let struct_ = module.get_struct(name);
19        if let Some(struct_) = struct_ {
20            return Some(struct_.clone());
21        }
22    }
23    None
24}
25
26impl Parser {
27    fn parse_token<T, F>(
28        &mut self,
29        expected: &str,
30        validator: F,
31    ) -> crate::core::result::Result<(T, Position)>
32    where
33        F: FnOnce(&Token) -> Option<T>,
34    {
35        let (token, pos) = self.token_stream.next_token();
36
37        match validator(&token) {
38            Some(value) => Ok((value, pos)),
39            None => Err(Error::UnexpectedToken(
40                token.to_string(),
41                expected.into(),
42                pos,
43            )),
44        }
45    }
46
47    pub fn parse_identifier(&mut self) -> crate::core::result::Result<(String, Position)> {
48        self.parse_token("Identifier", |token| {
49            if let Token::Identifier(id) = token {
50                Some(id.clone())
51            } else {
52                None
53            }
54        })
55    }
56
57    pub fn parse_keyword(&mut self, keyword: &str) -> crate::core::result::Result<Position> {
58        let expected = format!("Keyword({})", keyword);
59        let (_, pos) = self.parse_token(&expected, |token| {
60            if let Token::Keyword(k) = token {
61                if k == keyword {
62                    Some(())
63                } else {
64                    None
65                }
66            } else {
67                None
68            }
69        })?;
70        Ok(pos)
71    }
72
73    pub fn parse_special_token(&mut self, token: Token) -> crate::core::result::Result<Position> {
74        let expected = token.to_string();
75        let (_, pos) =
76            self.parse_token(&expected, |t| if t == &token { Some(()) } else { None })?;
77        Ok(pos)
78    }
79    pub(crate) fn parse_block(
80        &mut self,
81        ctx: &Context,
82    ) -> crate::core::result::Result<Vec<StmtNode>> {
83        let mut result = vec![];
84        self.parse_special_token(Token::ParenLeft)?;
85        loop {
86            let (token, _) = self.token_stream.peek();
87            match token {
88                Token::ParenRight => {
89                    self.parse_special_token(Token::ParenRight)?;
90                    break;
91                }
92                _ => {
93                    result.push(self.parse_stmt(ctx).unwrap());
94                }
95            }
96        }
97        Ok(result)
98    }
99    pub(crate) fn try_parse_token(&mut self, token: Token) -> bool {
100        let (token0, _) = self.token_stream.peek();
101        if token0 == token {
102            self.token_stream.next_token();
103            return true;
104        }
105        false
106    }
107    pub fn next_is(&mut self, token: Token) -> bool {
108        self.token_stream.peek().0 == token
109    }
110}