1use crate::{
2 AssignOperator, BinOpAssociativity, BinOpKind, BinOperator, Expr, ParseContext, Parser, Stmt,
3 Token, TokenKind, TypeAnnotation, UnOpKind, UnOperator,
4};
5use indexmap::IndexMap;
6use roan_error::error::RoanError::{ExpectedToken, UnexpectedToken};
7use tracing::debug;
8
9impl Parser {
10 pub fn parse_expr(&mut self) -> anyhow::Result<Expr> {
18 self.parse_assignment()
19 }
20
21 pub fn expression_stmt(&mut self) -> anyhow::Result<Stmt> {
29 let expr = self.parse_expr()?;
30
31 self.possible_check(TokenKind::Semicolon);
32
33 Ok(expr.into())
34 }
35
36 pub fn parse_binary_expression(&mut self) -> anyhow::Result<Expr> {
44 let left = self.parse_unary_expression()?;
45 self.parse_binary_expression_recurse(left, 0)
46 }
47
48 fn parse_binary_operator(&mut self) -> Option<BinOperator> {
56 let token = self.peek();
57 let kind = match token.kind {
58 TokenKind::Plus => Some(BinOpKind::Plus),
59 TokenKind::Minus => Some(BinOpKind::Minus),
60 TokenKind::Asterisk => Some(BinOpKind::Multiply),
61 TokenKind::Slash => Some(BinOpKind::Divide),
62 TokenKind::Ampersand => Some(BinOpKind::BitwiseAnd),
63 TokenKind::Pipe => Some(BinOpKind::BitwiseOr),
64 TokenKind::Caret => Some(BinOpKind::BitwiseXor),
65 TokenKind::DoubleAsterisk => Some(BinOpKind::Power),
66 TokenKind::EqualsEquals => Some(BinOpKind::Equals),
67 TokenKind::BangEquals => Some(BinOpKind::BangEquals),
68 TokenKind::LessThan => Some(BinOpKind::LessThan),
69 TokenKind::LessThanEquals => Some(BinOpKind::LessThanOrEqual),
70 TokenKind::GreaterThan => Some(BinOpKind::GreaterThan),
71 TokenKind::GreaterThanEquals => Some(BinOpKind::GreaterThanOrEqual),
72 TokenKind::Percent => Some(BinOpKind::Modulo),
73 TokenKind::And => Some(BinOpKind::And),
74 TokenKind::Or => Some(BinOpKind::Or),
75 TokenKind::Increment => Some(BinOpKind::Increment),
76 TokenKind::Decrement => Some(BinOpKind::Decrement),
77 TokenKind::DoubleGreaterThan => Some(BinOpKind::ShiftRight),
78 TokenKind::DoubleLessThan => Some(BinOpKind::ShiftLeft),
79 _ => None,
80 };
81 kind.map(|kind| BinOperator::new(kind, token.clone()))
82 }
83
84 pub fn parse_binary_expression_recurse(
96 &mut self,
97 mut left: Expr,
98 precedence: u8,
99 ) -> anyhow::Result<Expr> {
100 while let Some(operator) = self.parse_binary_operator() {
101 let operator_precedence = operator.precedence();
102 if operator_precedence < precedence {
103 break;
104 }
105
106 self.consume();
107
108 let mut right = self.parse_unary_expression()?;
109
110 while let Some(next_operator) = self.parse_binary_operator() {
111 let next_precedence = next_operator.precedence();
112
113 if next_precedence > operator_precedence
114 || (next_precedence == operator_precedence
115 && next_operator.associativity() == BinOpAssociativity::Right)
116 {
117 right = self.parse_binary_expression_recurse(right, next_precedence)?;
118 } else {
119 break;
120 }
121 }
122
123 left = Expr::new_binary(left, operator, right);
124 }
125
126 Ok(left)
127 }
128
129 pub fn parse_unary_operator(&mut self) -> Option<UnOperator> {
137 let token = self.peek();
138 let kind = match token.kind {
139 TokenKind::Minus => Some(UnOpKind::Minus),
140 TokenKind::Tilde => Some(UnOpKind::BitwiseNot),
141 TokenKind::Bang => Some(UnOpKind::LogicalNot),
142 _ => None,
143 };
144 kind.map(|kind| UnOperator::new(kind, token.clone()))
145 }
146
147 pub fn parse_unary_expression(&mut self) -> anyhow::Result<Expr> {
155 if let Some(operator) = self.parse_unary_operator() {
156 let token = self.consume();
157 let operand = self.parse_unary_expression()?;
158 return Ok(Expr::new_unary(operator, operand, token));
159 }
160 self.parse_access_expression()
161 }
162
163 pub fn parse_access_expression(&mut self) -> anyhow::Result<Expr> {
165 debug!("Parsing access expression");
166 let mut expr = self.parse_primary_expression()?;
167 let mut token = self.peek();
168
169 loop {
170 if token.kind == TokenKind::Dot {
171 self.consume();
172
173 let field_token = self.consume();
174 let mut field_expr = Expr::new_variable(field_token.clone(), field_token.literal());
175
176 if self.peek().kind == TokenKind::LeftParen {
177 field_expr = self.parse_call_expr(field_token)?;
178 }
179
180 expr = Expr::new_field_access(expr, field_expr, token);
181 } else if token.kind == TokenKind::LeftBracket {
182 self.consume();
183 let index = self.parse_expr()?;
184 self.expect(TokenKind::RightBracket)?;
185 expr = Expr::new_index_access(expr, index, token);
186 } else if token.kind == TokenKind::DoubleColon {
187 let colons = self.consume();
188 let field = self.parse_expr()?;
189
190 expr = Expr::new_static_method_access(expr, field, colons);
191 } else {
192 break;
193 }
194 token = self.peek();
195 }
196
197 Ok(expr)
198 }
199
200 pub fn parse_struct_constructor(&mut self, identifier: Token) -> anyhow::Result<Expr> {
211 self.expect(TokenKind::LeftBrace)?;
212
213 let mut fields = vec![];
214
215 while self.peek().kind != TokenKind::RightBrace && !self.is_eof() {
216 let field_name = self.consume();
217 self.expect(TokenKind::Colon)?;
218 let field_value = self.parse_expr()?;
219
220 fields.push((field_name.literal(), field_value));
221
222 if self.peek().kind != TokenKind::RightBrace {
223 self.expect(TokenKind::Comma)?;
224 }
225 }
226
227 self.expect(TokenKind::RightBrace)?;
228
229 Ok(Expr::new_struct_constructor(
230 identifier.literal(),
231 fields,
232 identifier,
233 ))
234 }
235
236 pub fn parse_primary_expression(&mut self) -> anyhow::Result<Expr> {
242 let token = self.consume();
243
244 match &token.kind {
245 TokenKind::Integer(int) => Ok(Expr::new_integer(token.clone(), *int)),
246 TokenKind::Float(float) => Ok(Expr::new_float(token.clone(), *float)),
247 TokenKind::Null => Ok(Expr::new_null(token)),
248 TokenKind::True | TokenKind::False => {
249 Ok(Expr::new_bool(token.clone(), token.as_bool().unwrap()))
250 }
251 TokenKind::TripleDot => Ok(Expr::new_spread(token.clone(), self.parse_expr()?)),
252 TokenKind::LeftBracket => self.parse_vector(),
253 TokenKind::LeftBrace => {
254 let mut fields: IndexMap<String, Expr> = IndexMap::new();
255
256 while self.peek().kind != TokenKind::RightBrace && !self.is_eof() {
257 let field_name = {
258 if matches!(self.peek().kind, TokenKind::String(_)) {
259 self.consume()
260 } else {
261 return Err(ExpectedToken(
262 "string literal".to_string(),
263 "Field names in objects must be string literals.".to_string(),
264 self.peek().span.clone(),
265 )
266 .into());
267 }
268 };
269
270 self.expect(TokenKind::Colon)?;
271 let field_value = self.parse_expr()?;
272
273 fields.insert(
274 field_name
275 .literal()
276 .strip_prefix("\"")
277 .unwrap()
278 .strip_suffix("\"")
279 .unwrap()
280 .to_string(),
281 field_value,
282 );
283
284 if self.peek().kind != TokenKind::RightBrace {
285 self.expect(TokenKind::Comma)?;
286 }
287 }
288
289 let closing_brace = self.expect(TokenKind::RightBrace)?;
290
291 Ok(Expr::new_object(fields, (token, closing_brace)))
292 }
293 TokenKind::Identifier => {
294 debug!("Parsing identifier: {}", token.literal());
295
296 if self.peek().kind == TokenKind::LeftParen {
297 self.parse_call_expr(token)
298 } else if self.peek().kind == TokenKind::LeftBrace {
299 if self.is_context(&ParseContext::Normal) {
300 self.parse_struct_constructor(token)
301 } else {
302 Ok(Expr::new_variable(token.clone(), token.literal()))
303 }
304 } else {
305 Ok(Expr::new_variable(token.clone(), token.literal()))
306 }
307 }
308 TokenKind::LeftParen => {
309 let expr = self.parse_expr()?;
310
311 self.expect(TokenKind::RightParen)?;
312
313 Ok(Expr::new_parenthesized(expr))
314 }
315 TokenKind::String(s) => Ok(Expr::new_string(token.clone(), s.clone())),
316 TokenKind::Char(c) => Ok(Expr::new_char(token.clone(), *c)),
317 _ => {
318 debug!("Unexpected token: {:?}", token);
319 Err(UnexpectedToken(token.kind.to_string(), token.span.clone()).into())
320 }
321 }
322 }
323
324 pub fn parse_then_else_expr(&mut self, condition: Expr) -> anyhow::Result<Expr> {
335 debug!("Parsing then-else expression");
336 let then_token = self.expect(TokenKind::Then)?;
337
338 let then_expr = self.parse_expr()?;
339 let else_token = self.expect(TokenKind::Else)?;
340
341 let else_expr = self.parse_expr()?;
342
343 Ok(Expr::new_then_else(
344 condition, then_expr, else_expr, then_token, else_token,
345 ))
346 }
347
348 pub fn parse_call_expr(&mut self, callee: Token) -> anyhow::Result<Expr> {
359 self.expect(TokenKind::LeftParen)?;
360
361 let mut args = vec![];
362
363 if self.peek().kind != TokenKind::RightParen {
364 while self.peek().kind != TokenKind::RightParen && !self.is_eof() {
365 let arg = self.parse_expr()?;
366
367 args.push(arg);
368
369 if self.peek().kind != TokenKind::RightParen {
370 self.expect(TokenKind::Comma)?;
371 }
372 }
373 }
374
375 self.expect(TokenKind::RightParen)?;
376
377 Ok(Expr::new_call(callee.literal(), args, callee))
378 }
379
380 pub fn parse_optional_type_annotation(&mut self) -> anyhow::Result<Option<TypeAnnotation>> {
388 if self.peek().kind == TokenKind::Colon {
389 Ok(Some(self.parse_type_annotation()?))
390 } else {
391 Ok(None)
392 }
393 }
394
395 pub fn parse_vector(&mut self) -> anyhow::Result<Expr> {
403 debug!("Parsing vector");
404
405 let mut elements = vec![];
406 if self.peek().kind != TokenKind::RightBracket {
407 while self.peek().kind != TokenKind::RightBracket && !self.is_eof() {
408 let arg = self.parse_expr()?;
409
410 elements.push(arg);
411
412 if self.peek().kind != TokenKind::RightBracket {
413 self.expect(TokenKind::Comma)?;
414 }
415 }
416 }
417
418 self.expect(TokenKind::RightBracket)?;
419
420 Ok(Expr::new_vec(elements))
421 }
422
423 pub fn parse_assignment(&mut self) -> anyhow::Result<Expr> {
431 tracing::debug!("Parsing assignment");
432
433 let expr = self.parse_binary_expression()?;
434 if let Some(assign_op) = self.parse_assignment_operator() {
435 self.consume();
436 let right = self.parse_expr()?;
437
438 let operator = AssignOperator::from_token_kind(assign_op);
439 return Ok(Expr::new_assign(expr, operator, right));
440 } else if self.peek().kind == TokenKind::Then {
441 return self.parse_then_else_expr(expr);
442 }
443
444 Ok(expr)
445 }
446
447 fn parse_assignment_operator(&mut self) -> Option<TokenKind> {
455 match self.peek().kind {
456 TokenKind::Equals
457 | TokenKind::PlusEquals
458 | TokenKind::MinusEquals
459 | TokenKind::MultiplyEquals
460 | TokenKind::DivideEquals => Some(self.peek().kind.clone()),
461 _ => None,
462 }
463 }
464}