mechylang/parser/expressions/
prefix_expression.rs1use std::fmt;
2use std::fmt::{Display, Formatter};
3use std::rc::Rc;
4use serde::Serialize;
5use crate::{Expression, Parser, Span, TokenKind, trace};
6use crate::parser::{
7 expressions::Precedence,
8 Error,
9 Result,
10};
11use crate::parser::expressions::ExpressionSpanExt;
12
13#[derive(Debug, PartialEq, Clone, Serialize)]
14pub struct PrefixExpression {
15 pub span: Span,
16 pub right_span: Span,
17 pub operator_span: Span,
18 pub operator: PrefixOperator,
19 pub right: Rc<Expression>,
20}
21
22impl Display for PrefixExpression {
23 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
24 write!(f, "({}{})", self.operator, self.right)
25 }
26}
27
28#[derive(Debug, Clone, PartialEq, Serialize, Copy)]
29pub enum PrefixOperator {
30 Bang,
31 Minus,
32 BitwiseNot,
33 Ampersand,
34 Asterisk,
35}
36
37impl Display for PrefixOperator {
38 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
39 match self {
40 PrefixOperator::Bang => write!(f, "!"),
41 PrefixOperator::Minus => write!(f, "-"),
42 PrefixOperator::BitwiseNot => write!(f, "~"),
43 PrefixOperator::Ampersand => write!(f, "&"),
44 PrefixOperator::Asterisk => write!(f, "*"),
45 }
46 }
47}
48
49impl Parser<'_> {
50 pub(crate) fn parse_prefix(&mut self) -> Result<Expression> {
51 let _trace = trace!("parse_prefix");
52 match self.cur_token.kind {
53 TokenKind::Identifier(_) => Ok(Expression::Identifier(self.parse_identifier()?)),
54 TokenKind::Number(_) => self.parse_number(),
55 TokenKind::True | TokenKind::False => Ok(Expression::Boolean(self.parse_boolean()?)),
56
57 TokenKind::Fn => Ok(Expression::Function(self.parse_function_literal()?)),
58
59 TokenKind::If => Ok(Expression::If(self.parse_if_expression()?)),
60
61 TokenKind::Bang |
62 TokenKind::Minus |
63 TokenKind::BitwiseNot |
64 TokenKind::Ampersand => Ok(Expression::Prefix(self.parse_prefix_expression()?)),
65
66 TokenKind::LeftSquirly => Ok(Expression::Block(self.parse_block_expression()?)),
68
69 TokenKind::Struct => Ok(Expression::StructLiteral(self.parse_struct_literal()?)),
70 TokenKind::String(_) => Ok(Expression::StringLiteral(self.parse_string()?)),
71
72 TokenKind::LeftParen => self.parse_grouped_expression(),
73
74 TokenKind::LeftSquare => Ok(Expression::ArrayLiteral(self.parse_array_expression()?)),
75
76 TokenKind::For => Ok(Expression::For(self.parse_for_expression()?)),
77 TokenKind::While => Ok(Expression::While(self.parse_while_expression()?)),
78
79 TokenKind::RangeExclusive | TokenKind::RangeInclusive => self.parse_range_prefix_expression(),
80 _ => Err(Error::InvalidPrefix {
81 span: self.cur_token.span.clone(),
82 found: self.cur_token.kind.clone(),
83 }),
84 }
85 }
86
87 pub(super) fn parse_prefix_expression(&mut self) -> Result<PrefixExpression> {
88 let _trace = trace!("parse_prefix_expression");
89 let operator_span = self.cur_token.span.clone();
90
91 let operator = match &self.cur_token.kind {
92 TokenKind::Bang => PrefixOperator::Bang,
93 TokenKind::Minus => PrefixOperator::Minus,
94 TokenKind::BitwiseNot => PrefixOperator::BitwiseNot,
95 TokenKind::Ampersand => PrefixOperator::Ampersand,
96 _ => {
97 return Err(Error::InvalidPrefix {
98 span: self.cur_token.span.clone(),
99 found: self.cur_token.kind.clone(),
100 })
101 }
102 };
103
104 self.next_token()?;
105
106 let right = self.parse_expression(Precedence::Prefix)?;
107
108 Ok(PrefixExpression {
109 span: self.span_with_start(&operator_span),
110 right_span: right.span().clone(),
111 operator_span,
112 operator,
113 right: Rc::new(right),
114 })
115 }
116}