1use crate::Stmt;
2use anyhow::{Result, anyhow};
3use dynamic::Dynamic;
4use smol_str::SmolStr;
5
6use super::{Parser, ParserErr, Span, Type, try_parse};
7use num_enum::{FromPrimitive, IntoPrimitive};
8
9#[repr(i32)]
10#[derive(Debug, Clone, PartialEq, IntoPrimitive, FromPrimitive)]
11pub enum UnaryOp {
12 Neg = 0,
13 Not,
14 #[num_enum(default)]
15 Unknow = 255,
16}
17
18#[repr(i32)]
19#[derive(Debug, Clone, PartialEq, IntoPrimitive, FromPrimitive)]
20pub enum BinaryOp {
21 Add = 10,
22 Sub,
23 Mul,
24 Div,
25 Mod,
26 Shr,
27 Shl,
28 BitAnd,
29 BitOr,
30 BitXor,
31 AddAssign,
32 SubAssign,
33 MulAssign,
34 DivAssign,
35 ModAssign,
36 ShrAssign,
37 ShlAssign,
38 BitAndAssign,
39 BitOrAssign,
40 BitXorAssign,
41 Assign,
42 Eq,
43 Ne,
44 Lt,
45 Gt,
46 Le,
47 Ge,
48 And,
49 Or,
50 Idx,
51 RangeOpen,
52 RangeClose,
53 #[num_enum(default)]
54 Unknow = 255,
55}
56
57impl BinaryOp {
58 pub fn is_logic(&self) -> bool {
59 matches!(self, Self::And | Self::Or | Self::Eq | Self::Ne | Self::Lt | Self::Gt | Self::Le | Self::Ge)
60 }
61
62 pub fn is_add(&self) -> bool {
63 matches!(self, Self::Add | Self::AddAssign)
64 }
65
66 pub fn is_assign(&self) -> bool {
67 matches!(
68 self,
69 Self::AddAssign | Self::Assign | Self::DivAssign | Self::ModAssign | Self::MulAssign | Self::SubAssign | Self::BitAndAssign | Self::BitOrAssign | Self::BitXorAssign | Self::ShlAssign | Self::ShrAssign
70 )
71 }
72
73 pub fn weight(&self) -> usize {
74 match self {
75 Self::Idx => 30,
76 Self::Mul | Self::Div | Self::Mod => 20,
77 Self::Add | Self::Sub => 19,
78 Self::Shl | Self::Shr => 18,
79 Self::BitAnd => 17,
80 Self::BitXor => 16,
81 Self::BitOr => 15,
82 Self::Eq | Self::Ne | Self::Lt | Self::Gt | Self::Le | Self::Ge => 10,
83 Self::And | Self::Or => 9,
84 Self::RangeOpen | Self::RangeClose => 5,
85 _ => usize::MIN,
86 }
87 }
88}
89
90#[derive(Debug, Clone)]
91pub struct Expr {
92 pub kind: ExprKind,
93 pub span: Span,
94}
95
96#[derive(Debug, Clone, Default)]
97pub enum ExprKind {
98 #[default]
99 Null,
100 Value(Dynamic),
101 Const(usize),
102 Typed {
103 value: Box<Expr>,
104 ty: Type,
105 },
106 Unary {
107 op: UnaryOp,
108 value: Box<Expr>,
109 },
110 Binary {
111 left: Box<Expr>,
112 op: BinaryOp,
113 right: Box<Expr>,
114 },
115 Ident(SmolStr),
116 Var(u32),
117 Capture(u32),
118 Id(u32, Option<Box<Expr>>),
119 Generic {
120 obj: Box<Expr>,
121 params: Vec<Type>,
122 },
123 Assoc {
124 ty: Type,
125 name: SmolStr,
126 },
127 TypedMethod {
128 obj: Box<Expr>,
129 ty: Type,
130 name: SmolStr,
131 },
132 AssocId {
133 id: u32,
134 params: Vec<Type>,
135 },
136 Tuple(Vec<Expr>),
137 List(Vec<Expr>),
138 Repeat {
139 value: Box<Expr>,
140 len: Type,
141 },
142 Dict(Vec<(SmolStr, Expr)>),
143 Range {
144 start: Box<Expr>,
145 stop: Box<Expr>,
146 inclusive: bool,
147 },
148 Call {
149 obj: Box<Expr>,
150 params: Vec<Expr>,
151 },
152 Stmt(Box<Stmt>),
153 Closure {
154 args: Vec<(SmolStr, Type)>,
155 body: Box<Stmt>,
156 },
157}
158
159#[derive(Debug, thiserror::Error)]
160pub enum ExprErr {
161 #[error("{0} 不是标识符")]
162 NotIdent(SmolStr),
163 #[error("{0} 非原生类型")]
164 NotNative(SmolStr),
165 #[error("期望表达式")]
166 ExpectExpr,
167}
168
169impl Default for Expr {
170 fn default() -> Self {
171 Self::new(ExprKind::Null, Span::default())
172 }
173}
174
175impl From<Dynamic> for Expr {
176 fn from(value: Dynamic) -> Self {
177 Self::new(ExprKind::Value(value), Span::default())
178 }
179}
180
181impl Expr {
182 pub fn new(kind: ExprKind, span: Span) -> Self {
183 Self { kind, span }
184 }
185
186 pub fn with_span(mut self, span: Span) -> Self {
187 self.span = span;
188 self
189 }
190
191 pub fn is_range(&self) -> bool {
192 matches!(self.kind, ExprKind::Range { .. })
193 }
194
195 pub fn is_typed(&self) -> bool {
196 matches!(self.kind, ExprKind::Typed { .. })
197 }
198
199 pub fn get_type(&self) -> Type {
200 match &self.kind {
201 ExprKind::Typed { ty, .. } => ty.clone(),
202 ExprKind::Value(v) => v.get_type(),
203 ExprKind::Unary { value, .. } => value.get_type(),
204 ExprKind::Tuple(list) => Type::Tuple(list.iter().map(|l| l.get_type()).collect()),
205 ExprKind::List(list) => {
206 if list.is_empty() {
207 return Type::list_any();
208 }
209 let mut elem_ty = Type::Any;
210 for item in list {
211 let item_ty = item.get_type();
212 elem_ty = if elem_ty.is_any() { item_ty } else { elem_ty + item_ty };
213 }
214 Type::Array(std::rc::Rc::new(elem_ty), list.len() as u32)
215 }
216 ExprKind::Repeat { value, len } => {
217 if let Type::ConstInt(len) = len {
218 Type::Array(std::rc::Rc::new(value.get_type()), *len as u32)
219 } else {
220 Type::ArrayParam(std::rc::Rc::new(value.get_type()), std::rc::Rc::new(len.clone()))
221 }
222 }
223 ExprKind::Range { start, .. } => start.get_type(),
224 ExprKind::Stmt(stmt) => stmt.get_type().unwrap_or(Type::Any),
225 _ => Type::Any,
226 }
227 }
228
229 pub fn id(&self) -> Option<u32> {
230 if let ExprKind::Id(id, _) = &self.kind { Some(*id) } else { None }
231 }
232
233 pub fn var(&self) -> Option<u32> {
234 if let ExprKind::Var(idx) = &self.kind { Some(*idx) } else { None }
235 }
236
237 pub fn ident(&self) -> Result<&str> {
238 if let ExprKind::Ident(ident) = &self.kind { Ok(ident.as_str()) } else { Err(ExprErr::NotIdent(SmolStr::from(format!("{:?}", self))).into()) }
239 }
240
241 pub fn binary_op(&self) -> Option<BinaryOp> {
242 if let ExprKind::Binary { op, .. } = &self.kind { Some(op.clone()) } else { None }
243 }
244
245 pub fn is_idx(&self) -> bool {
246 matches!(&self.kind, ExprKind::Binary { op, .. } if *op == BinaryOp::Idx)
247 }
248
249 pub fn is_value(&self) -> bool {
250 match &self.kind {
251 ExprKind::Value(_) => true,
252 ExprKind::Typed { value, ty } => ty.is_native() && value.is_value(),
253 _ => false,
254 }
255 }
256
257 pub fn is_const(&self) -> bool {
258 matches!(self.kind, ExprKind::Const(_))
259 }
260
261 pub fn value(self) -> Result<Dynamic> {
262 match self.kind {
263 ExprKind::Value(v) => Ok(v),
264 ExprKind::Typed { value, ty } => {
265 if ty.is_native() {
266 Ok(ty.force(value.value()?)?)
267 } else {
268 Err(anyhow!("不是 Value"))
269 }
270 }
271 _ => Err(anyhow!("不是 Value")),
272 }
273 }
274
275 pub fn binary(self) -> Option<(Expr, BinaryOp, Expr)> {
276 match self.kind {
277 ExprKind::Binary { left, op, right } => Some((*left, op, *right)),
278 _ => None,
279 }
280 }
281
282 pub fn compact(&self) -> Option<Dynamic> {
283 match &self.kind {
284 ExprKind::Value(v) => Some(v.clone()),
285 ExprKind::Unary { op, value } => {
286 if value.is_value() {
287 let v = value.clone().value().unwrap();
288 match op {
289 UnaryOp::Neg => Some(-v),
290 UnaryOp::Not => Some(!v),
291 _ => None,
292 }
293 } else {
294 None
295 }
296 }
297 ExprKind::Binary { left, op, right } => {
298 if left.is_value() && right.is_value() {
299 let left = left.clone().value().unwrap();
300 let right = right.clone().value().unwrap();
301 let r = match op {
302 BinaryOp::Add | BinaryOp::AddAssign => left + right,
303 BinaryOp::Sub | BinaryOp::SubAssign => left - right,
304 BinaryOp::Mul | BinaryOp::MulAssign => left * right,
305 BinaryOp::Div | BinaryOp::DivAssign => left / right,
306 BinaryOp::Mod | BinaryOp::ModAssign => left % right,
307 BinaryOp::And => Dynamic::Bool(left.is_true() && right.is_true()),
308 BinaryOp::Or => Dynamic::Bool(left.is_true() || right.is_true()),
309 BinaryOp::Eq => Dynamic::Bool(left == right),
310 BinaryOp::Ne => Dynamic::Bool(left != right),
311 BinaryOp::Le => Dynamic::Bool(left <= right),
312 BinaryOp::Lt => Dynamic::Bool(left < right),
313 BinaryOp::Ge => Dynamic::Bool(left >= right),
314 BinaryOp::Gt => Dynamic::Bool(left > right),
315 BinaryOp::Shl | BinaryOp::ShlAssign => left << right,
316 BinaryOp::Shr | BinaryOp::ShrAssign => left >> right,
317 BinaryOp::Assign => right,
318 BinaryOp::BitAnd | BinaryOp::BitAndAssign => left & right,
319 BinaryOp::BitXor | BinaryOp::BitXorAssign => left ^ right,
320 BinaryOp::BitOr | BinaryOp::BitOrAssign => left | right,
321 BinaryOp::Idx => {
322 if let Some(idx) = right.as_int() {
323 return left.get_idx(idx as usize);
324 } else if let Ok(key) = SmolStr::try_from(right) {
325 return left.get_dynamic(&key);
326 } else {
327 return None;
328 }
329 }
330 _ => Dynamic::Null,
331 };
332 Some(r)
333 } else {
334 None
335 }
336 }
337 _ => None,
338 }
339 }
340}
341
342impl Parser {
343 fn is_dict_item_boundary(ch: u8) -> bool {
344 matches!(ch, b',' | b'}')
345 }
346
347 fn is_shorthand_field_name(name: &str) -> bool {
348 name.as_bytes().first().is_some_and(|ch| ch.is_ascii_alphabetic() || *ch == b'_')
349 }
350
351 pub(crate) fn looks_like_dict(&mut self) -> bool {
352 let save_pos = self.pos;
353 let result = (|| -> Result<bool> {
354 self.whitespace()?;
355 if self.take(b'{').is_err() {
356 return Ok(false);
357 }
358 self.whitespace()?;
359 if self.take(b'}').is_ok() {
360 return Ok(true);
361 }
362 if self.ident().is_err() && self.string().is_err() {
363 return Ok(false);
364 }
365 self.whitespace()?;
366 Ok(matches!(self.get(), Ok(b':' | b',' | b'}')))
367 })()
368 .unwrap_or(false);
369 self.pos = save_pos;
370 result
371 }
372
373 pub(crate) fn looks_like_empty_dict(&mut self) -> bool {
374 let save_pos = self.pos;
375 let result = (|| -> Result<bool> {
376 self.whitespace()?;
377 self.take(b'{')?;
378 self.whitespace()?;
379 Ok(self.take(b'}').is_ok())
380 })()
381 .unwrap_or(false);
382 self.pos = save_pos;
383 result
384 }
385
386 fn postfix_expr(&mut self, start: usize, mut expr: Expr) -> Result<Expr> {
387 while !self.is_eof() && [b'.', b'[', b'(', b':'].contains(&self.get()?) {
388 if self.ahead()? == b'.' && self.get()? == b'.' {
389 break;
390 }
391 if self.just("::<").is_ok() {
392 let params = crate::parse_list!(self, Vec::new(), b'>', b',', self.get_type_param()?);
393 self.whitespace()?;
394 if self.just("::").is_ok() {
395 if params.len() != 1 {
396 return Err(anyhow!("类型提示只能包含一个类型参数"));
397 }
398 let name = self.ident()?;
399 expr = Expr::new(ExprKind::TypedMethod { obj: Box::new(expr), ty: params[0].clone(), name }, Span::new(start, self.current_pos()));
400 } else {
401 expr = Expr::new(ExprKind::Generic { obj: Box::new(expr), params }, Span::new(start, self.current_pos()));
402 }
403 } else if self.take(b'.').is_ok() {
404 let key_start = self.current_pos();
405 let key = self.ident()?;
406 let right = Expr::new(ExprKind::Value(Dynamic::String(key)), self.span_from(key_start));
407 let span = expr.span.merge(right.span);
408 expr = Expr::new(ExprKind::Binary { left: Box::new(expr), op: BinaryOp::Idx, right: Box::new(right) }, span);
409 } else if self.take(b'[').is_ok() {
410 let key = self.expr(None, None)?.0;
411 self.until(b']')?;
412 let span = Span::new(start, self.current_pos());
413 expr = Expr::new(ExprKind::Binary { left: Box::new(expr), op: BinaryOp::Idx, right: Box::new(key) }, span);
414 } else if self.take(b'(').is_ok() {
415 let params = crate::parse_list!(self, Vec::new(), b')', b',', self.expr(None, None)?.0);
416 expr = Expr::new(ExprKind::Call { obj: Box::new(expr), params }, Span::new(start, self.current_pos()));
417 } else {
418 break;
419 }
420 }
421 loop {
425 let save = self.pos;
426 self.whitespace()?;
427 if self.keyword("as").is_ok() {
428 let ty = self.get_type()?;
429 expr = Expr::new(ExprKind::Typed { value: Box::new(expr), ty }, Span::new(start, self.current_pos()));
430 } else {
431 self.pos = save;
432 break;
433 }
434 }
435 Ok(expr.with_span(Span::new(start, self.current_pos())))
436 }
437
438 fn binary_op(&mut self) -> Option<BinaryOp> {
439 if self.just("<<=").is_ok() {
440 Some(BinaryOp::ShlAssign)
441 } else if self.just(">>=").is_ok() {
442 Some(BinaryOp::ShrAssign)
443 } else if self.just("<<").is_ok() {
444 Some(BinaryOp::Shl)
445 } else if self.just(">>").is_ok() {
446 Some(BinaryOp::Shr)
447 } else if self.just(">=").is_ok() {
448 Some(BinaryOp::Ge)
449 } else if self.just("==").is_ok() {
450 Some(BinaryOp::Eq)
451 } else if self.just("!=").is_ok() {
452 Some(BinaryOp::Ne)
453 } else if self.just("<=").is_ok() {
454 Some(BinaryOp::Le)
455 } else if self.just("&&").is_ok() {
456 Some(BinaryOp::And)
457 } else if self.just("||").is_ok() {
458 Some(BinaryOp::Or)
459 } else if self.just("+=").is_ok() {
460 Some(BinaryOp::AddAssign)
461 } else if self.just("-=").is_ok() {
462 Some(BinaryOp::SubAssign)
463 } else if self.just("*=").is_ok() {
464 Some(BinaryOp::MulAssign)
465 } else if self.just("/=").is_ok() {
466 Some(BinaryOp::DivAssign)
467 } else if self.just("%=").is_ok() {
468 Some(BinaryOp::ModAssign)
469 } else if self.just("&=").is_ok() {
470 Some(BinaryOp::BitAndAssign)
471 } else if self.just("|=").is_ok() {
472 Some(BinaryOp::BitOrAssign)
473 } else if self.just("^=").is_ok() {
474 Some(BinaryOp::BitXorAssign)
475 } else if self.just("..=").is_ok() {
476 Some(BinaryOp::RangeClose)
477 } else if self.just("..").is_ok() {
478 Some(BinaryOp::RangeOpen)
479 } else {
480 match self.get() {
481 Ok(b'+') => {
482 self.pos += 1;
483 Some(BinaryOp::Add)
484 }
485 Ok(b'-') => {
486 self.pos += 1;
487 Some(BinaryOp::Sub)
488 }
489 Ok(b'*') => {
490 self.pos += 1;
491 Some(BinaryOp::Mul)
492 }
493 Ok(b'/') => {
494 self.pos += 1;
495 Some(BinaryOp::Div)
496 }
497 Ok(b'%') => {
498 self.pos += 1;
499 Some(BinaryOp::Mod)
500 }
501 Ok(b'<') => {
502 self.pos += 1;
503 Some(BinaryOp::Lt)
504 }
505 Ok(b'>') => {
506 self.pos += 1;
507 Some(BinaryOp::Gt)
508 }
509 Ok(b'=') => {
510 self.pos += 1;
511 Some(BinaryOp::Assign)
512 }
513 Ok(b'&') => {
514 self.pos += 1;
515 Some(BinaryOp::BitAnd)
516 }
517 Ok(b'|') => {
518 self.pos += 1;
519 Some(BinaryOp::BitOr)
520 }
521 Ok(b'^') => {
522 self.pos += 1;
523 Some(BinaryOp::BitXor)
524 }
525 _ => None,
526 }
527 }
528 }
529
530 pub fn kv(&mut self) -> Result<(SmolStr, Expr)> {
531 let start = self.current_pos();
532 if let Ok(key) = self.ident() {
533 self.whitespace()?;
534 if self.take(b':').is_ok() {
535 let value = self.expr(None, None)?.0;
536 Ok((SmolStr::from(key), value))
537 } else if Self::is_shorthand_field_name(&key) && self.get().map(Self::is_dict_item_boundary).unwrap_or(false) {
538 let span = Span::new(start, start + key.len());
539 Ok((key.clone(), Expr::new(ExprKind::Ident(key), span)))
540 } else {
541 Err(anyhow!("expect ':' after field name"))
542 }
543 } else if let Ok(key) = self.string() {
544 self.until(b':')?;
545 let value = self.expr(None, None)?.0;
546 Ok((SmolStr::from(key), value))
547 } else {
548 Err(anyhow!("expect string as key"))
549 }
550 }
551
552 pub fn base_expr(&mut self, allow_struct_literal: bool) -> Result<Expr> {
553 self.check_fatal()?;
554 let start = self.current_pos();
555 if let Ok(s) = self.text() {
556 let expr = Expr::new(ExprKind::Value(Dynamic::String(s)), self.span_from(start));
557 self.postfix_expr(start, expr)
558 } else if self.get().map(|c| c.is_ascii_digit()).unwrap_or(false) {
559 let n = self.number()?;
562 let expr = if let Ok(ty) = self.get_type() {
563 if ty.is_native() {
564 Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::Value(n), self.span_from(start))), ty }, self.span_from(start))
565 } else {
566 return Err(ExprErr::NotNative(SmolStr::from(format!("{:?}", ty))).into());
567 }
568 } else {
569 Expr::new(ExprKind::Value(n), self.span_from(start))
570 };
571 self.postfix_expr(start, expr)
572 } else if self.keyword("true").is_ok() {
573 let expr = Expr::new(ExprKind::Value(Dynamic::Bool(true)), self.span_from(start));
574 self.postfix_expr(start, expr)
575 } else if self.keyword("false").is_ok() {
576 let expr = Expr::new(ExprKind::Value(Dynamic::Bool(false)), self.span_from(start));
577 self.postfix_expr(start, expr)
578 } else if self.keyword("null").is_ok() {
579 let expr = Expr::new(ExprKind::Value(Dynamic::Null), self.span_from(start));
580 self.postfix_expr(start, expr)
581 } else if let Ok(ident) = self.ident() {
582 self.whitespace()?;
583 let save_pos = self.pos;
584 if self.take(b'<').is_ok() {
585 let typed_literal = (|| -> Result<Expr> {
586 let type_params = crate::parse_list!(self, Vec::new(), b'>', b',', self.get_type_param()?);
587 self.whitespace()?;
588 if self.just("::").is_ok() {
589 let name = self.ident()?;
590 let expr = Expr::new(ExprKind::Assoc { ty: Type::Ident { name: ident.clone(), params: type_params }, name }, self.span_from(start));
591 return self.postfix_expr(start, expr);
592 }
593 if allow_struct_literal
594 && self.looks_like_dict()
595 && let Ok(b'{') = self.get()
596 && let Ok(dict) = try_parse!(self, self.dict())
597 {
598 return Ok(Expr::new(ExprKind::Typed { value: Box::new(dict), ty: Type::Ident { name: ident.clone(), params: type_params } }, self.span_from(start)));
599 }
600 Err(ExprErr::ExpectExpr.into())
601 })();
602 if let Ok(expr) = typed_literal {
603 return Ok(expr);
604 }
605 self.pos = save_pos;
606 }
607 if allow_struct_literal
608 && self.looks_like_dict()
609 && let Ok(b'{') = self.get()
610 && let Ok(dict) = try_parse!(self, self.dict())
611 {
612 return Ok(Expr::new(ExprKind::Typed { value: Box::new(dict), ty: Type::Ident { name: ident, params: Vec::new() } }, self.span_from(start)));
613 }
614 self.postfix_expr(start, Expr::new(ExprKind::Ident(ident), self.span_from(start)))
615 } else {
616 Err(ExprErr::ExpectExpr.into())
617 }
618 }
619
620 pub(crate) fn dict(&mut self) -> Result<Expr> {
621 let start = self.current_pos();
622 self.pos += 1;
623 Ok(Expr::new(ExprKind::Dict(crate::parse_list!(self, Vec::new(), b'}', b',', self.kv()?)), self.span_from(start)))
624 }
625
626 fn static_dynamic_literal_expr(&mut self) -> Result<Expr> {
627 let start = self.current_pos();
628 let value = self.static_dynamic_value()?;
629 Ok(Expr::new(ExprKind::Value(value), self.span_from(start)))
630 }
631
632 fn static_dynamic_value(&mut self) -> Result<Dynamic> {
633 self.whitespace()?;
634 if self.get()? == b'[' {
635 return self.static_dynamic_list();
636 }
637 if self.get()? == b'{' {
638 return self.static_dynamic_map();
639 }
640 if self.take(b'-').is_ok() {
641 return Ok(-self.number()?);
642 }
643 if let Ok(text) = self.text() {
644 return Ok(Dynamic::String(text));
645 }
646 if let Ok(number) = self.number() {
647 return Ok(number);
648 }
649 if self.keyword("true").is_ok() {
650 return Ok(Dynamic::Bool(true));
651 }
652 if self.keyword("false").is_ok() {
653 return Ok(Dynamic::Bool(false));
654 }
655 if self.keyword("null").is_ok() {
656 return Ok(Dynamic::Null);
657 }
658 Err(ExprErr::ExpectExpr.into())
659 }
660
661 fn static_dynamic_list(&mut self) -> Result<Dynamic> {
662 self.take(b'[')?;
663 let mut values = Vec::new();
664 loop {
665 self.whitespace()?;
666 if self.take(b']').is_ok() {
667 break;
668 }
669 values.push(self.static_dynamic_value()?);
670 self.whitespace()?;
671 if self.take(b',').is_ok() {
672 continue;
673 }
674 self.until(b']')?;
675 break;
676 }
677 Ok(Dynamic::list(values))
678 }
679
680 fn static_dynamic_map(&mut self) -> Result<Dynamic> {
681 self.take(b'{')?;
682 let mut values = std::collections::BTreeMap::new();
683 loop {
684 self.whitespace()?;
685 if self.take(b'}').is_ok() {
686 break;
687 }
688 let key = if let Ok(key) = self.ident() { key } else { self.string()? };
689 self.until(b':')?;
690 let value = self.static_dynamic_value()?;
691 values.insert(key, value);
692 self.whitespace()?;
693 if self.take(b',').is_ok() {
694 continue;
695 }
696 self.until(b'}')?;
697 break;
698 }
699 Ok(Dynamic::map(values))
700 }
701
702 pub fn get_expr(&mut self) -> Result<Expr> {
703 self.expr(None, None).map(|(e, _)| e)
704 }
705
706 pub fn get_expr_without_struct_literal(&mut self) -> Result<Expr> {
707 self.expr_with_min_weight(None, None, 0, false).map(|(e, _)| e)
708 }
709
710 pub fn expr(&mut self, left: Option<(Expr, bool)>, left_op: Option<BinaryOp>) -> Result<(Expr, bool)> {
711 self.expr_with_min_weight(left, left_op, 0, true)
712 }
713
714 fn expr_with_min_weight(&mut self, left: Option<(Expr, bool)>, left_op: Option<BinaryOp>, min_weight: usize, allow_struct_literal: bool) -> Result<(Expr, bool)> {
715 self.check_fatal()?;
716 self.enter_depth()?;
717 let result = self.expr_with_min_weight_inner(left, left_op, min_weight, allow_struct_literal);
718 self.exit_depth();
719 result
720 }
721
722 fn expr_with_min_weight_inner(&mut self, left: Option<(Expr, bool)>, left_op: Option<BinaryOp>, min_weight: usize, allow_struct_literal: bool) -> Result<(Expr, bool)> {
723 self.whitespace()?;
724 if self.is_eof() {
725 return left.ok_or_else(|| ParserErr::at("左操作数缺失", self.current_pos()).into());
726 }
727 let start = self.current_pos();
728 let ch = self.get()?;
729 let mut expr = if ch == b'(' {
730 let start = self.current_pos();
731 self.pos += 1;
732 self.whitespace()?;
733 if self.take(b')').is_ok() {
734 let expr = Expr::new(ExprKind::Tuple(Vec::new()), Span::new(start, self.current_pos()));
735 return Ok((self.postfix_expr(start, expr)?, true));
736 }
737 let (e, _closed) = self.expr_with_min_weight(None, None, 0, true)?;
738 self.whitespace()?;
739 if self.get()? == b',' {
740 self.pos += 1;
741 let list = crate::parse_list!(self, vec![e], b')', b',', self.expr_with_min_weight(None, None, 0, true)?.0);
742 let expr = Expr::new(ExprKind::Tuple(list), Span::new(start, self.current_pos()));
743 Ok((self.postfix_expr(start, expr)?, true))
744 } else {
745 self.until(b')')?;
746 let expr = e.with_span(Span::new(start, self.current_pos()));
747 Ok((self.postfix_expr(start, expr)?, true))
748 }
749 } else if ch == b'!' && self.ahead().map(|a| a != b'=').unwrap_or(true) {
750 let start = self.current_pos();
751 self.pos += 1;
752 let value = self.expr_with_min_weight(None, None, BinaryOp::Mul.weight() + 1, allow_struct_literal)?.0;
753 Ok((Expr::new(ExprKind::Unary { op: UnaryOp::Not, value: Box::new(value) }, Span::new(start, self.current_pos())), false))
754 } else if ch == b'-' && self.ahead().map(|a| a != b'=').unwrap_or(true) && (left.is_none() || (left.is_some() && left_op.is_some())) {
755 let start = self.current_pos();
756 self.pos += 1;
757 let value = self.expr_with_min_weight(None, None, BinaryOp::Mul.weight() + 1, allow_struct_literal)?.0;
758 Ok((Expr::new(ExprKind::Unary { op: UnaryOp::Neg, value: Box::new(value) }, Span::new(start, self.current_pos())), false))
759 } else if ch == b'[' {
760 if let Ok(expr) = try_parse!(self, self.static_dynamic_literal_expr()) {
761 Ok((self.postfix_expr(start, expr)?, false))
762 } else {
763 let start = self.current_pos();
764 self.pos += 1;
765 self.whitespace()?;
766 if self.take(b']').is_ok() {
767 let expr = Expr::new(ExprKind::List(Vec::new()), Span::new(start, self.current_pos()));
768 Ok((self.postfix_expr(start, expr)?, false))
769 } else {
770 let first = self.expr_with_min_weight(None, None, 0, true)?.0;
771 self.whitespace()?;
772 if self.take(b';').is_ok() {
773 let len = self.get_type_param()?;
774 self.until(b']')?;
775 let expr = Expr::new(ExprKind::Repeat { value: Box::new(first), len }, Span::new(start, self.current_pos()));
776 Ok((self.postfix_expr(start, expr)?, false))
777 } else {
778 let mut items = vec![first];
779 let mut closed = false;
780 while self.take(b',').is_ok() {
781 self.whitespace()?;
782 if self.take(b']').is_ok() {
783 closed = true;
784 break;
785 }
786 items.push(self.expr_with_min_weight(None, None, 0, true)?.0);
787 self.whitespace()?;
788 }
789 if !closed {
790 self.until(b']')?;
791 }
792 let expr = Expr::new(ExprKind::List(items), Span::new(start, self.current_pos()));
793 Ok((self.postfix_expr(start, expr)?, false))
794 }
795 }
796 }
797 } else if ch == b'{'
798 && (left.is_none() || left_op.is_some())
799 && let Ok(expr) = try_parse!(self, self.static_dynamic_literal_expr())
800 {
801 Ok((self.postfix_expr(start, expr)?, false))
802 } else if ch == b'{'
803 && (left.is_none() || left_op.is_some())
804 && let Ok(dict) = try_parse!(self, self.dict())
805 {
806 Ok((self.postfix_expr(start, dict)?, false))
807 } else if (left.is_none() || left_op.is_some()) && self.keyword("if").is_ok() {
808 let stmt = self.if_block()?;
809 Ok((Expr::new(ExprKind::Stmt(Box::new(stmt)), Span::new(start, self.current_pos())), true))
810 } else if ch == b'|' && left.is_none() {
811 let start = self.current_pos();
812 self.pos += 1;
813 let args = crate::parse_list!(self, Vec::new(), b'|', b',', self.ident_typed()?);
814 let body = Box::new(self.function_body(&args)?);
815 let expr = Expr::new(ExprKind::Closure { args, body }, Span::new(start, self.current_pos()));
816 Ok((self.postfix_expr(start, expr)?, true))
817 } else if let Some(this_op) = self.binary_op() {
818 let (left, close) = left.ok_or(anyhow!("{:?} need left value", this_op))?;
819 if this_op == BinaryOp::RangeOpen {
820 self.whitespace()?;
821 if self.get()? == b']' {
822 let span = Span::new(left.span.start, self.current_pos());
823 let stop = Expr::new(ExprKind::Value(Dynamic::Null), Span::empty(self.current_pos()));
824 return Ok((Expr::new(ExprKind::Range { start: Box::new(left), stop: Box::new(stop), inclusive: false }, span), false));
825 }
826 }
827 if this_op.weight() < min_weight {
828 self.pos = start;
829 return Ok((left, close));
830 }
831 if matches!(this_op, BinaryOp::RangeOpen | BinaryOp::RangeClose) {
834 let stop = self.expr_with_min_weight(None, None, this_op.weight() + 1, allow_struct_literal)?.0;
835 let span = left.span.merge(stop.span);
836 let inclusive = this_op == BinaryOp::RangeClose;
837 let range = Expr::new(ExprKind::Range { start: Box::new(left), stop: Box::new(stop), inclusive }, span);
838 return self.expr_with_min_weight(Some((range, false)), None, min_weight, allow_struct_literal);
839 }
840 if this_op.is_assign() {
843 let rhs = self.expr_with_min_weight(None, None, this_op.weight(), allow_struct_literal)?.0;
844 let span = left.span.merge(rhs.span);
845 let expr = Expr::new(ExprKind::Binary { left: Box::new(left), op: this_op, right: Box::new(rhs) }, span);
846 return self.expr_with_min_weight(Some((expr, false)), None, min_weight, allow_struct_literal);
847 }
848 if left_op.is_some() {
849 return Err(anyhow!("unexpected binary op {:?}", this_op));
850 }
851 return if !close && left.binary_op().map(|op| op.weight() < this_op.weight()).unwrap_or(false) {
852 let (binary_left, op, right) = left.binary().unwrap();
853 let this_weight = this_op.weight();
854 let new_right = self.expr_with_min_weight(Some((right, false)), Some(this_op), this_weight, allow_struct_literal)?.0;
855 let span = binary_left.span.merge(new_right.span);
856 let expr = Expr::new(ExprKind::Binary { left: Box::new(binary_left), op, right: Box::new(new_right) }, span);
857 self.expr_with_min_weight(Some((expr, false)), None, min_weight, allow_struct_literal)
858 } else {
859 self.expr_with_min_weight(Some((left, false)), Some(this_op), min_weight, allow_struct_literal)
860 };
861 } else {
862 self.base_expr(allow_struct_literal).map(|e| (e, false))
864 };
865
866 if left.is_some() {
867 if let Some(op) = left_op {
868 let left = left.unwrap().0;
869 let right = expr?.0;
870 let span = left.span.merge(right.span);
871 expr = Ok((
872 match op {
873 BinaryOp::RangeOpen => Expr::new(ExprKind::Range { start: Box::new(left), stop: Box::new(right), inclusive: false }, span),
874 BinaryOp::RangeClose => Expr::new(ExprKind::Range { start: Box::new(left), stop: Box::new(right), inclusive: true }, span),
875 _ => Expr::new(ExprKind::Binary { left: Box::new(left), op, right: Box::new(right) }, span),
876 },
877 false,
878 ));
879 } else if expr.is_ok() {
880 return Err(anyhow!("unexpected {:?}", expr));
881 } else {
882 return Ok((left.unwrap().0, false));
883 }
884 }
885 let result = self.expr_with_min_weight(Some(expr?), None, min_weight, allow_struct_literal)?;
886 Ok(result)
887 }
888}