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