rl_lang/parser/expressions/
postfix.rs1use crate::{
2 ast::{ExprId, nodes::ExpressionKind},
3 lexer::tokentypes::TokenType,
4 parser::parser_logic::Parser,
5 utils::{errors::Error, span::Span},
6};
7
8impl Parser {
9 pub fn parse_postfix(&mut self, mut expr: ExprId, start: Span) -> Result<ExprId, Error> {
22 loop {
23 if self.match_type(&[TokenType::Dot]) {
25 if !self.match_type(&[TokenType::Identifier(String::new())]) {
26 return Err(self.err("expected name after '.'", self.peek_span()));
27 }
28 let first = if let TokenType::Identifier(name) = self.previous() {
29 name
30 } else {
31 return Err(self.err("expected name after '.'", self.peek_span()));
32 };
33
34 if self.peek() != TokenType::ColonColon && self.peek() != TokenType::LeftParen {
37 let span = start.join(self.previous_span());
38 #[cfg(feature = "debug")]
39 log::trace!(
40 "alloc FieldAccess expr: target={:?} field={:?} @ {:?}",
41 expr,
42 first,
43 span
44 );
45 expr = self.ast_arena.alloc_expr(
46 ExpressionKind::FieldAccess {
47 target: expr,
48 field: first,
49 },
50 span,
51 );
52
53 if self.match_type(&[TokenType::Assign]) {
55 let value = self.parse_expression()?;
56 let value_id = self.ast_arena.exprs.get(value);
57 let assign_span = start.join(value_id.span);
58 let expr_kind = self.ast_arena.exprs.get(expr).kind.clone();
59 if let ExpressionKind::FieldAccess { target, field } = expr_kind {
60 #[cfg(feature = "debug")]
61 log::trace!(
62 "alloc FieldAssign expr: target={:?} field={:?} value={:?} @ {:?}",
63 target,
64 field,
65 value,
66 assign_span
67 );
68 return Ok(self.ast_arena.alloc_expr(
69 ExpressionKind::FieldAssign {
70 target,
71 field,
72 value,
73 },
74 assign_span,
75 ));
76 }
77 }
78
79 continue;
80 }
81
82 let mut method = vec![first];
83 while self.match_type(&[TokenType::ColonColon]) {
84 if !self.match_type(&[TokenType::Identifier(String::new())]) {
85 return Err(
86 self.err("expected identifier name after '::'", self.peek_span())
87 );
88 }
89 if let TokenType::Identifier(seg) = self.previous() {
90 method.push(seg);
91 }
92 }
93
94 if !self.match_type(&[TokenType::LeftParen]) {
95 return Err(self.err("expected '(' after method name", self.peek_span()));
96 }
97 while self.match_type(&[TokenType::Newline]) {}
98 let mut args = Vec::new();
99 if self.peek() != TokenType::RightParen {
100 loop {
101 args.push(self.parse_expression()?);
102 while self.match_type(&[TokenType::Newline]) {}
103 if !self.match_type(&[TokenType::Comma]) {
104 break;
105 }
106 while self.match_type(&[TokenType::Newline]) {}
107 }
108 }
109 while self.match_type(&[TokenType::Newline]) {}
110 self.match_type(&[TokenType::RightParen]);
111 let span = start.join(self.previous_span());
112
113 #[cfg(feature = "debug")]
114 log::trace!(
115 "alloc MethodCall expr: caller={:?} method={:?} args={} @ {:?}",
116 expr,
117 method,
118 args.len(),
119 span
120 );
121
122 expr = self.ast_arena.alloc_expr(
123 ExpressionKind::MethodCall {
124 caller: expr,
125 method,
126 args,
127 },
128 span,
129 );
130 }
131 else if self.match_type(&[TokenType::As]) {
133 let span = self.previous_span();
134 let target_type = self
135 .parse_type(true)
136 .map_err(|_| self.err("expected type after `as`", span))?;
137 let span = start.join(self.previous_span());
138
139 #[cfg(feature = "debug")]
140 log::trace!(
141 "alloc Cast expr: value={:?} target_type={:?} @ {:?}",
142 expr,
143 target_type,
144 span
145 );
146
147 expr = self.ast_arena.alloc_expr(
148 ExpressionKind::Cast {
149 value: expr,
150 target_type,
151 },
152 span,
153 )
154 }
155 else if self.match_type(&[TokenType::Question]) {
157 let span = start.join(self.previous_span());
158
159 #[cfg(feature = "debug")]
160 log::trace!("alloc Propagate expr: inner={:?} @ {:?}", expr, span);
161
162 expr = self
163 .ast_arena
164 .alloc_expr(ExpressionKind::Propagate(expr), span)
165 } else {
166 break;
167 }
168 }
169 Ok(expr)
170 }
171}