1use crate::ast::expr::{Argument, Expr, ExprNode, FunctionCall, Op, StructExpr};
2use crate::context::Context;
3use crate::core::error::Error;
4use crate::lexer::position::Position;
5use crate::lexer::token::Token;
6use crate::parser::helper::{get_struct_from_context, is_enum};
7use crate::parser::Parser;
8use std::collections::HashMap;
9
10impl Parser {
11 pub fn parse_primary_expr(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
12 let (token, mut pos) = self.token_stream.next_token();
13 match token {
14 Token::Not => {
15 let expr = self.parse_primary_expr(ctx).unwrap();
16 Ok(ExprNode::from(Expr::Unary(Op::Not, Box::new(expr))).with_position(pos))
17 }
18 Token::Minus => {
19 let expr = self.parse_primary_expr(ctx).unwrap();
20 Ok(ExprNode::from(Expr::Unary(Op::Negate, Box::new(expr))).with_position(pos))
21 }
22 Token::Vertical => {
23 let peek = self.token_stream.peek().0;
24 let mut l = vec![];
25 if peek != Token::Vertical {
26 l = self.parse_param_list(ctx).unwrap();
27 }
28 let p1 = self.parse_special_token(Token::Vertical)?;
29 if let Token::Arrow = self.token_stream.peek().0 {
30 let _ = self.parse_special_token(Token::Arrow)?;
31 let return_type = self.parse_type()?;
32 let block = self.parse_block(ctx)?;
33 Ok(ExprNode::from(Expr::Closure {
34 args: l,
35 body: block,
36 captures: vec![],
37 return_type: Some(return_type),
38 })
39 .with_position(p1 + pos))
40 } else {
41 let block = self.parse_block(ctx).unwrap();
42 Ok(ExprNode::from(Expr::Closure {
43 args: l,
44 body: block,
45 captures: vec![],
46 return_type: None,
47 })
48 .with_position(p1 + pos))
49 }
50 }
51 Token::Identifier(id) => {
52 if is_enum(ctx, &id) && self.try_parse_token(Token::Dot) {
54 return self.parse_enum_variant(ctx, &id, pos);
55 }
56 let mut generics = vec![];
57 loop {
58 let (peek, _) = self.token_stream.peek();
59 match peek {
60 Token::ScopeSymbol => {
61 let _ = self.parse_special_token(Token::ScopeSymbol)?;
62 let list = self.parse_generic_list().unwrap();
63 let (args, _) = self.parse_fn_args(ctx).unwrap();
64 return Ok(ExprNode::from(Expr::FnCall(FunctionCall {
65 name: id,
66 args,
67 is_method: false,
68 generics: list,
69 type_generics: vec![],
70 }))
71 .with_position(pos));
72 }
73 Token::BraceLeft => {
74 let (args, p0) = self.parse_fn_args(ctx)?;
75 pos += p0;
76 return Ok(ExprNode::from(Expr::FnCall(FunctionCall {
77 name: id,
78 args,
79 is_method: false,
80 generics,
81 type_generics: vec![],
82 }))
83 .with_position(pos));
84 }
85 Token::Less => {
86 let mut flag = false;
87 ctx.apply_module(self.module, |m| {
88 let r = m.get_struct(&id);
89 if r.is_some() {
90 flag = true;
91 }
92 });
93 if flag {
94 generics = self.parse_generic_list().unwrap();
95 } else {
96 return Ok(ExprNode::from(Expr::Variable(id)).with_position(pos));
97 }
98 }
99 Token::ParenLeft => {
100 let f = ctx.get_function(&id);
101 if f.is_some() {
102 let mut args = vec![];
103 let body = self.parse_block(ctx).unwrap();
104 let expr = Expr::Closure {
105 args: vec![],
106 body,
107 captures: vec![],
108 return_type: None,
109 };
110 let expr_node = ExprNode::from(expr).with_position(pos.clone());
111 args.push(Argument::new(expr_node));
112 return Ok(ExprNode::from(Expr::FnCall(FunctionCall {
113 name: id,
114 args,
115 is_method: false,
116 generics,
117 type_generics: vec![],
118 }))
119 .with_position(pos));
120 }
121 let p0 = self.parse_special_token(Token::ParenLeft)?;
123
124 let mut fields = HashMap::new();
125 loop {
126 let (peek, p1) = self.token_stream.peek();
127 pos += p1;
128 match peek {
129 Token::ParenRight => {
130 let p2 = self.parse_special_token(Token::ParenRight)?;
131 pos += p2;
132 break;
133 }
134 Token::Comma => {
135 let p2 = self.parse_special_token(Token::Comma)?;
136 pos += p2;
137 continue;
138 }
139 Token::Identifier(ident) => {
140 let (_, _) = self.parse_identifier()?;
141 let _ = self.parse_special_token(Token::Colon)?;
142 let expr = self.parse_expr(ctx).unwrap();
143 let _ = expr.position();
144 fields.insert(ident, expr);
145 }
146 _ => todo!("parse primary expr"),
147 }
148 }
149
150 pos += p0;
151 return Ok(ExprNode::from(Expr::Struct(
152 StructExpr::new(id, fields).with_generics(generics),
153 ))
154 .with_position(pos));
155 }
156 Token::Dot if !generics.is_empty() => {
157 let _ = self.parse_special_token(Token::Dot)?;
158 let (static_method, p1) = self.parse_identifier()?;
159 pos += p1;
160 let (args, p2) = self.parse_fn_args(ctx).unwrap();
161 pos += p2;
162 return Ok(ExprNode::from(Expr::FnCall(FunctionCall {
163 name: format!("{}.{}", id, static_method),
164 args,
165 is_method: false,
166 generics: vec![],
167 type_generics: generics,
168 })));
169 }
170 _ => return Ok(ExprNode::from(Expr::Variable(id)).with_position(pos)),
171 }
172 }
173 }
174 Token::Int(n) => Ok(ExprNode::from(Expr::Int(n)).with_position(pos)),
175 Token::String(s) => Ok(ExprNode::from(Expr::String(s)).with_position(pos)),
176 Token::Boolean(b) => Ok(ExprNode::from(Expr::Boolean(b)).with_position(pos)),
177 Token::Float(n) => Ok(ExprNode::from(Expr::Double(n)).with_position(pos)),
178 Token::BraceLeft => {
179 let expr = self.parse_expr(ctx)?;
180 self.parse_special_token(Token::BraceRight)?;
181 Ok(ExprNode::from(Expr::Brace(Box::new(expr))).with_position(pos))
182 }
183 Token::BitAnd => {
184 let expr = self.parse_primary_expr(ctx).unwrap();
185 let _ = expr.position();
186 Ok(ExprNode::from(Expr::Address(Box::new(expr))).with_position(pos))
187 }
188 Token::BracketLeft => {
189 let mut v = vec![];
190 loop {
191 let expr = self.parse_expr(ctx).unwrap();
192 pos += expr.position();
193 v.push(expr);
194 let (token, p1) = self.token_stream.peek();
195 pos += p1;
196 match token {
197 Token::BracketRight => {
198 let p2 = self.parse_special_token(Token::BracketRight)?;
199 return Ok(ExprNode::from(Expr::Array(v)).with_position(pos + p2));
200 }
201 Token::Comma => {
202 let p2 = self.parse_special_token(Token::Comma)?;
203 pos += p2;
204 continue;
205 }
206 _ => {}
207 }
208 }
209 }
210 _ => Err(Error::UnexpectedToken(
211 token.to_string(),
212 "Expect Primary Expr".into(),
213 pos,
214 )),
215 }
216 }
217 fn parse_enum_variant(
218 &mut self,
219 ctx: &Context,
220 enum_name: &str,
221 pos: Position,
222 ) -> crate::core::result::Result<ExprNode> {
223 let (variant_name, variant_pos) = self.parse_identifier()?;
224
225 if self.try_parse_token(Token::BraceLeft) {
227 let value_expr = self.parse_expr(ctx)?;
229 self.parse_special_token(Token::BraceRight)?;
230
231 let enum_variant =
233 Expr::EnumVariant(enum_name.into(), variant_name, Some(Box::new(value_expr)));
234
235 Ok(ExprNode::new(enum_variant).with_position(pos + variant_pos))
236 } else {
237 let enum_variant = Expr::EnumVariant(enum_name.into(), variant_name, None);
239
240 Ok(ExprNode::new(enum_variant).with_position(pos + variant_pos))
241 }
242 }
243 pub fn parse_fact_expr(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
244 let expr = self.parse_chain_expr(ctx)?;
245 let p0 = expr.position();
246 let (token, _) = self.token_stream.peek();
247 match token {
248 Token::BraceLeft => {
249 let (mut args, p1) = self.parse_fn_args(ctx)?;
250 let p1 = p1 + p0;
251 let mut name = expr.get_member_name();
252 let mut is_method = false;
253
254 if expr.is_member() {
256 let root = expr.get_member_root();
257 if let Expr::Variable(root_name) = &root.expr {
258 if get_struct_from_context(ctx, root_name).is_some() {
260 name = format!("{}.{}", root_name, name);
261 args.insert(0, Argument::new(root));
262 is_method = true;
263 } else {
264 args.insert(0, Argument::new(root));
266 is_method = true;
267 }
268 }
269 }
270
271 Ok(ExprNode::from(Expr::FnCall(FunctionCall {
272 name,
273 generics: vec![],
274 is_method,
275 args,
276 type_generics: vec![],
277 }))
278 .with_position(p1))
279 }
280 Token::BracketLeft => {
281 let p0 = self.parse_special_token(Token::BracketLeft)?;
282 let index = self.parse_expr(ctx)?;
283 let p1 = index.position();
284 let p2 = self.parse_special_token(Token::BracketRight)?;
285 Ok(ExprNode::from(Expr::Index(Box::new(expr), Box::new(index)))
286 .with_position(p0 + p1 + p2))
287 }
288
289 _ => Ok(expr),
290 }
291 }
292 pub fn parse_term(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
293 let expr0 = self.parse_fact_expr(ctx)?;
294 let p0 = expr0.position();
295 let (token, _) = self.token_stream.peek();
296 match token {
297 Token::Star => {
298 let p1 = self.parse_special_token(Token::Star)?;
299 let expr1 = self.parse_term(ctx)?;
300 let p2 = expr1.position();
301 Ok(
302 ExprNode::from(Expr::Binary(Op::Mul, Box::new(expr0), Box::new(expr1)))
303 .with_position(p0 + p1 + p2),
304 )
305 }
306 Token::Slash => {
307 let p0 = self.parse_special_token(Token::Slash)?;
308 let expr1 = self.parse_term(ctx)?;
309 Ok(
310 ExprNode::from(Expr::Binary(Op::Div, Box::new(expr0), Box::new(expr1)))
311 .with_position(p0),
312 )
313 }
314 _ => Ok(expr0),
315 }
316 }
317
318 pub fn parse_expr0(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
319 let expr0 = self.parse_term(ctx)?;
320 let (token, _) = self.token_stream.peek();
321 match token {
322 Token::Plus => {
323 let p0 = self.parse_special_token(Token::Plus)?;
324 let expr1 = self.parse_expr(ctx)?;
325 Ok(
326 ExprNode::new(Expr::Binary(Op::Plus, Box::new(expr0), Box::new(expr1)))
327 .with_position(p0),
328 )
329 }
330 Token::Minus => {
331 let p0 = self.parse_special_token(Token::Minus)?;
332 let expr1 = self.parse_expr(ctx)?;
333 Ok(
334 ExprNode::new(Expr::Binary(Op::Minus, Box::new(expr0), Box::new(expr1)))
335 .with_position(p0),
336 )
337 }
338 _ => Ok(expr0),
339 }
340 }
341 pub fn parse_expr(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
342 let lhs = self.parse_expr1(ctx)?;
343 let (token, _) = self.token_stream.peek();
344 match token {
345 Token::Or => {
346 let p0 = self.parse_special_token(Token::Or)?;
347 let expr1 = self.parse_expr1(ctx)?;
348 Ok(
349 ExprNode::new(Expr::Binary(Op::Or, Box::new(lhs), Box::new(expr1)))
350 .with_position(p0),
351 )
352 }
353 Token::And => {
354 let p0 = self.parse_special_token(Token::And)?;
355 let expr1 = self.parse_expr1(ctx)?;
356 Ok(
357 ExprNode::new(Expr::Binary(Op::And, Box::new(lhs), Box::new(expr1)))
358 .with_position(p0),
359 )
360 }
361 _ => Ok(lhs),
362 }
363 }
364 pub fn parse_expr1(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
365 let expr0 = self.parse_expr0(ctx)?;
366 let (token, _) = self.token_stream.peek();
367 match token {
368 Token::Equal => {
369 let p0 = self.parse_special_token(Token::Equal)?;
370 let expr1 = self.parse_expr1(ctx)?;
371 Ok(
372 ExprNode::new(Expr::Binary(Op::Equal, Box::new(expr0), Box::new(expr1)))
373 .with_position(p0),
374 )
375 }
376 Token::NotEqual => {
377 let p0 = self.parse_special_token(Token::NotEqual)?;
378 let expr1 = self.parse_expr1(ctx)?;
379 Ok(
380 ExprNode::new(Expr::Binary(Op::NotEqual, Box::new(expr0), Box::new(expr1)))
381 .with_position(p0),
382 )
383 }
384 Token::Less => {
385 let p0 = self.parse_special_token(Token::Less)?;
386 let expr1 = self.parse_expr1(ctx)?;
387 Ok(
388 ExprNode::new(Expr::Binary(Op::Less, Box::new(expr0), Box::new(expr1)))
389 .with_position(p0),
390 )
391 }
392 Token::LessEqual => {
393 let p0 = self.parse_special_token(Token::LessEqual)?;
394 let expr1 = self.parse_expr1(ctx)?;
395 Ok(ExprNode::new(Expr::Binary(
396 Op::LessEqual,
397 Box::new(expr0),
398 Box::new(expr1),
399 ))
400 .with_position(p0))
401 }
402 Token::GreaterEqual => {
403 let p0 = self.parse_special_token(Token::GreaterEqual)?;
404 let expr1 = self.parse_expr1(ctx)?;
405 Ok(ExprNode::new(Expr::Binary(
406 Op::GreaterEqual,
407 Box::new(expr0),
408 Box::new(expr1),
409 ))
410 .with_position(p0))
411 }
412 Token::Greater => {
413 let p0 = self.parse_special_token(Token::Greater)?;
414 let expr1 = self.parse_expr1(ctx)?;
415 Ok(
416 ExprNode::new(Expr::Binary(Op::Greater, Box::new(expr0), Box::new(expr1)))
417 .with_position(p0),
418 )
419 }
420 _ => Ok(expr0),
421 }
422 }
423 pub fn parse_chain_expr(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
424 let mut expr = self.parse_primary_expr(ctx)?;
425
426 loop {
427 let (peek, _) = self.token_stream.peek();
428 expr = match peek {
429 Token::Dot => {
430 self.parse_special_token(Token::Dot)?;
431 let (name, pos) = self.parse_identifier()?;
432 ExprNode::from(Expr::Member(Box::new(expr), name)).with_position(pos)
433 }
434 Token::BracketLeft => {
435 self.parse_special_token(Token::BracketLeft)?;
436 let index = self.parse_expr(ctx)?;
437 let pos = index.position();
438 self.parse_special_token(Token::BracketRight)?;
439 ExprNode::from(Expr::Index(Box::new(expr), Box::new(index))).with_position(pos)
440 }
441 _ => break,
442 };
443 }
444
445 Ok(expr)
446 }
447}