Skip to main content

rl_lang/parser/utils/
parse_type.rs

1use std::rc::Rc;
2
3use crate::{
4    ast::statements::TypeAnnotation, lexer::tokentypes::TokenType, parser::parser_logic::Parser,
5    utils::errors::Error,
6};
7
8impl Parser {
9    /// Parses a type keyword into a [`TypeAnnotation`].
10    ///
11    /// The `is_mut` flag controls which annotation variant is produced:
12    ///
13    /// | `is_mut` | produced variant |
14    /// |---|---|
15    /// | `true` | `Int`, `Float`, `Bool`, `String`, `Byte`, `Char`, `Fn`, `Array(T)` |
16    /// | `false` | `CInt`, `CFloat`, `CBool`, `CString`, `CByte`, `CChar`, `Fn`, `CArray(T)` |
17    ///
18    /// The `C*` variants represent constant (immutable) bindings and are used by
19    /// the `const` declaration path.
20    ///
21    /// For `array[T]` the inner element type is parsed recursively.
22    ///
23    /// # Errors
24    /// Returns an error if the current token is not a recognised type keyword.
25    pub fn parse_type(&mut self, is_mut: bool) -> Result<TypeAnnotation, Error> {
26        let span = self.peek_span();
27        Ok(match is_mut {
28            true => match self.peek() {
29                TokenType::Int => {
30                    self.advance();
31                    TypeAnnotation::Int
32                }
33                TokenType::Float => {
34                    self.advance();
35                    TypeAnnotation::Float
36                }
37                TokenType::Bool => {
38                    self.advance();
39                    TypeAnnotation::Bool
40                }
41                TokenType::String => {
42                    self.advance();
43                    TypeAnnotation::String
44                }
45                TokenType::Byte => {
46                    self.advance();
47                    TypeAnnotation::Byte
48                }
49                TokenType::Char => {
50                    self.advance();
51                    TypeAnnotation::Char
52                }
53                TokenType::Fn => {
54                    self.advance();
55                    TypeAnnotation::Fn
56                }
57                TokenType::Array => {
58                    self.advance();
59                    self.match_type(&[TokenType::LeftBracket]);
60                    let inner = self.parse_type(true)?;
61                    self.match_type(&[TokenType::RightBracket]);
62                    TypeAnnotation::Array(Box::new(inner))
63                }
64                TokenType::Map => {
65                    self.advance();
66                    self.match_type(&[TokenType::LeftBracket]);
67                    let key_type = self.parse_type(true)?;
68                    if !self.match_type(&[TokenType::Comma]) {
69                        return Err(self.err(
70                            "expected `,` between map key and value types",
71                            self.peek_span(),
72                        ));
73                    }
74                    let value_type = self.parse_type(true)?;
75                    self.match_type(&[TokenType::RightBracket]);
76                    TypeAnnotation::Map(Box::new(key_type), Box::new(value_type))
77                }
78                TokenType::Set => {
79                    self.advance();
80                    self.match_type(&[TokenType::LeftBracket]);
81                    let inner = self.parse_type(true)?;
82                    self.match_type(&[TokenType::RightBracket]);
83                    TypeAnnotation::Set(Box::new(inner))
84                }
85                TokenType::LeftParen => {
86                    self.advance();
87                    let mut inner = vec![];
88                    while !self.match_type(&[TokenType::RightParen]) {
89                        let item_type = self.parse_type(true)?;
90                        inner.push(item_type);
91                        if !self.match_type(&[TokenType::Comma]) {
92                            return Err(
93                                self.err("expected `,` between tuple types", self.peek_span())
94                            );
95                        }
96                    }
97                    TypeAnnotation::Tuple(Rc::new(inner))
98                }
99                TokenType::Result => {
100                    self.advance();
101                    self.match_type(&[TokenType::LeftBracket]);
102                    let inner = self.parse_type(true)?;
103                    self.match_type(&[TokenType::RightBracket]);
104                    TypeAnnotation::Result(Box::new(inner))
105                }
106                TokenType::Error => {
107                    self.advance();
108                    TypeAnnotation::Error
109                }
110                TokenType::Identifier(name) => {
111                    self.advance();
112                    if self.tag_names.contains(&name) {
113                        TypeAnnotation::Enum(name)
114                    } else {
115                        TypeAnnotation::Record(name)
116                    }
117                }
118                _ => return Err(self.err("expected a type", span)),
119            },
120            false => match self.peek() {
121                TokenType::Int => {
122                    self.advance();
123                    TypeAnnotation::CInt
124                }
125                TokenType::Float => {
126                    self.advance();
127                    TypeAnnotation::CFloat
128                }
129                TokenType::Bool => {
130                    self.advance();
131                    TypeAnnotation::CBool
132                }
133                TokenType::String => {
134                    self.advance();
135                    TypeAnnotation::CString
136                }
137                TokenType::Byte => {
138                    self.advance();
139                    TypeAnnotation::CByte
140                }
141                TokenType::Char => {
142                    self.advance();
143                    TypeAnnotation::CChar
144                }
145                TokenType::Fn => {
146                    self.advance();
147                    TypeAnnotation::Fn
148                }
149                TokenType::Array => {
150                    self.advance();
151                    self.match_type(&[TokenType::LeftBracket]);
152                    let inner = self.parse_type(false)?;
153                    self.match_type(&[TokenType::RightBracket]);
154                    TypeAnnotation::CArray(Box::new(inner))
155                }
156                TokenType::Map => {
157                    self.advance();
158                    self.match_type(&[TokenType::LeftBracket]);
159                    let key_type = self.parse_type(false)?;
160                    if !self.match_type(&[TokenType::Comma]) {
161                        return Err(self.err(
162                            "expected `,` between map key and value types",
163                            self.peek_span(),
164                        ));
165                    }
166                    let value_type = self.parse_type(false)?;
167                    self.match_type(&[TokenType::RightBracket]);
168                    TypeAnnotation::CMap(Box::new(key_type), Box::new(value_type))
169                }
170                TokenType::Set => {
171                    self.advance();
172                    self.match_type(&[TokenType::LeftBracket]);
173                    let inner = self.parse_type(false)?;
174                    self.match_type(&[TokenType::RightBracket]);
175                    TypeAnnotation::CSet(Box::new(inner))
176                }
177                TokenType::LeftParen => {
178                    self.advance();
179                    let mut inner = vec![];
180                    while !self.match_type(&[TokenType::RightParen]) {
181                        let item_type = self.parse_type(false)?;
182                        inner.push(item_type);
183                        if !self.match_type(&[TokenType::Comma]) {
184                            return Err(
185                                self.err("expected `,` between tuple types", self.peek_span())
186                            );
187                        }
188                    }
189                    TypeAnnotation::CTuple(Rc::new(inner))
190                }
191                TokenType::Result => {
192                    self.advance();
193                    self.match_type(&[TokenType::LeftBracket]);
194                    let inner = self.parse_type(false)?;
195                    self.match_type(&[TokenType::RightBracket]);
196                    TypeAnnotation::CResult(Box::new(inner))
197                }
198                TokenType::Error => {
199                    self.advance();
200                    TypeAnnotation::CError
201                }
202                TokenType::Identifier(name) => {
203                    self.advance();
204                    if self.tag_names.contains(&name) {
205                        TypeAnnotation::CEnum(name)
206                    } else {
207                        TypeAnnotation::CRecord(name)
208                    }
209                }
210                _ => return Err(self.err("expected a type", span)),
211            },
212        })
213    }
214}