Skip to main content

parser/
expr.rs

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            Ok(Expr::new(ExprKind::Value(Dynamic::String(s)), self.span_from(start)))
523        } else if let Ok(n) = self.number() {
524            if let Ok(ty) = self.get_type() {
525                if ty.is_native() {
526                    Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::Value(n), self.span_from(start))), ty }, self.span_from(start)))
527                } else {
528                    Err(ExprErr::NotNative(SmolStr::from(format!("{:?}", ty))).into())
529                }
530            } else {
531                Ok(Expr::new(ExprKind::Value(n), self.span_from(start)))
532            }
533        } else if self.keyword("true").is_ok() {
534            Ok(Expr::new(ExprKind::Value(Dynamic::Bool(true)), self.span_from(start)))
535        } else if self.keyword("false").is_ok() {
536            Ok(Expr::new(ExprKind::Value(Dynamic::Bool(false)), self.span_from(start)))
537        } else if self.keyword("null").is_ok() {
538            Ok(Expr::new(ExprKind::Value(Dynamic::Null), self.span_from(start)))
539        } else if let Ok(ident) = self.ident() {
540            self.whitespace()?;
541            let save_pos = self.pos;
542            if self.take(b'<').is_ok() {
543                let typed_literal = (|| -> Result<Expr> {
544                    let type_params = crate::parse_list!(self, Vec::new(), b'>', b',', self.get_type_param()?);
545                    self.whitespace()?;
546                    if self.just("::").is_ok() {
547                        let name = self.ident()?;
548                        let expr = Expr::new(ExprKind::Assoc { ty: Type::Ident { name: ident.clone(), params: type_params }, name }, self.span_from(start));
549                        return self.postfix_expr(start, expr);
550                    }
551                    if allow_struct_literal
552                        && self.looks_like_dict()
553                        && let Ok(b'{') = self.get()
554                        && let Ok(dict) = try_parse!(self, self.dict())
555                    {
556                        return Ok(Expr::new(ExprKind::Typed { value: Box::new(dict), ty: Type::Ident { name: ident.clone(), params: type_params } }, self.span_from(start)));
557                    }
558                    Err(ExprErr::ExpectExpr.into())
559                })();
560                if let Ok(expr) = typed_literal {
561                    return Ok(expr);
562                }
563                self.pos = save_pos;
564            }
565            if allow_struct_literal
566                && self.looks_like_dict()
567                && let Ok(b'{') = self.get()
568                && let Ok(dict) = try_parse!(self, self.dict())
569            {
570                return Ok(Expr::new(ExprKind::Typed { value: Box::new(dict), ty: Type::Ident { name: ident, params: Vec::new() } }, self.span_from(start)));
571            }
572            self.postfix_expr(start, Expr::new(ExprKind::Ident(ident), self.span_from(start)))
573        } else {
574            Err(ExprErr::ExpectExpr.into())
575        }
576    }
577
578    pub(crate) fn dict(&mut self) -> Result<Expr> {
579        let start = self.current_pos();
580        self.pos += 1;
581        Ok(Expr::new(ExprKind::Dict(crate::parse_list!(self, Vec::new(), b'}', b',', self.kv()?)), self.span_from(start)))
582    }
583
584    fn static_dynamic_literal_expr(&mut self) -> Result<Expr> {
585        let start = self.current_pos();
586        let value = self.static_dynamic_value()?;
587        Ok(Expr::new(ExprKind::Value(value), self.span_from(start)))
588    }
589
590    fn static_dynamic_value(&mut self) -> Result<Dynamic> {
591        self.whitespace()?;
592        if self.get()? == b'[' {
593            return self.static_dynamic_list();
594        }
595        if self.get()? == b'{' {
596            return self.static_dynamic_map();
597        }
598        if self.take(b'-').is_ok() {
599            return Ok(-self.number()?);
600        }
601        if let Ok(text) = self.text() {
602            return Ok(Dynamic::String(text));
603        }
604        if let Ok(number) = self.number() {
605            return Ok(number);
606        }
607        if self.keyword("true").is_ok() {
608            return Ok(Dynamic::Bool(true));
609        }
610        if self.keyword("false").is_ok() {
611            return Ok(Dynamic::Bool(false));
612        }
613        if self.keyword("null").is_ok() {
614            return Ok(Dynamic::Null);
615        }
616        Err(ExprErr::ExpectExpr.into())
617    }
618
619    fn static_dynamic_list(&mut self) -> Result<Dynamic> {
620        self.take(b'[')?;
621        let mut values = Vec::new();
622        loop {
623            self.whitespace()?;
624            if self.take(b']').is_ok() {
625                break;
626            }
627            values.push(self.static_dynamic_value()?);
628            self.whitespace()?;
629            if self.take(b',').is_ok() {
630                continue;
631            }
632            self.until(b']')?;
633            break;
634        }
635        Ok(Dynamic::list(values))
636    }
637
638    fn static_dynamic_map(&mut self) -> Result<Dynamic> {
639        self.take(b'{')?;
640        let mut values = std::collections::BTreeMap::new();
641        loop {
642            self.whitespace()?;
643            if self.take(b'}').is_ok() {
644                break;
645            }
646            let key = if let Ok(key) = self.ident() { key } else { self.string()? };
647            self.until(b':')?;
648            let value = self.static_dynamic_value()?;
649            values.insert(key, value);
650            self.whitespace()?;
651            if self.take(b',').is_ok() {
652                continue;
653            }
654            self.until(b'}')?;
655            break;
656        }
657        Ok(Dynamic::map(values))
658    }
659
660    pub fn get_expr(&mut self) -> Result<Expr> {
661        self.expr(None, None).map(|(e, _)| e)
662    }
663
664    pub fn get_expr_without_struct_literal(&mut self) -> Result<Expr> {
665        self.expr_with_min_weight(None, None, 0, false).map(|(e, _)| e)
666    }
667
668    pub fn expr(&mut self, left: Option<(Expr, bool)>, left_op: Option<BinaryOp>) -> Result<(Expr, bool)> {
669        self.expr_with_min_weight(left, left_op, 0, true)
670    }
671
672    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)> {
673        self.whitespace()?;
674        if self.is_eof() {
675            return left.ok_or(ParserErr::EndofInput.into());
676        }
677        let start = self.current_pos();
678        let ch = self.get()?;
679        let mut expr = if ch == b'(' {
680            let start = self.current_pos();
681            self.pos += 1;
682            let (e, _closed) = self.expr_with_min_weight(None, None, 0, true)?;
683            self.whitespace()?;
684            if self.get()? == b',' {
685                self.pos += 1;
686                let list = crate::parse_list!(self, vec![e], b')', b',', self.expr_with_min_weight(None, None, 0, true)?.0);
687                let expr = Expr::new(ExprKind::Tuple(list), Span::new(start, self.current_pos()));
688                Ok((self.postfix_expr(start, expr)?, true))
689            } else {
690                self.until(b')')?;
691                let expr = e.with_span(Span::new(start, self.current_pos()));
692                Ok((self.postfix_expr(start, expr)?, true))
693            }
694        } else if ch == b'!' && self.ahead().map(|a| a != b'=').unwrap_or(true) {
695            let start = self.current_pos();
696            self.pos += 1;
697            let value = self.expr_with_min_weight(None, None, BinaryOp::Mul.weight() + 1, allow_struct_literal)?.0;
698            Ok((Expr::new(ExprKind::Unary { op: UnaryOp::Not, value: Box::new(value) }, Span::new(start, self.current_pos())), false))
699        } else if ch == b'-' && self.ahead().map(|a| a != b'=').unwrap_or(true) && (left.is_none() || (left.is_some() && left_op.is_some())) {
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::Neg, value: Box::new(value) }, Span::new(start, self.current_pos())), false))
704        } else if ch == b'[' {
705            if let Ok(expr) = try_parse!(self, self.static_dynamic_literal_expr()) {
706                return Ok((expr, false));
707            }
708            let start = self.current_pos();
709            self.pos += 1;
710            self.whitespace()?;
711            if self.take(b']').is_ok() {
712                Ok((Expr::new(ExprKind::List(Vec::new()), Span::new(start, self.current_pos())), false))
713            } else {
714                let first = self.expr_with_min_weight(None, None, 0, true)?.0;
715                self.whitespace()?;
716                if self.take(b';').is_ok() {
717                    let len = self.get_type_param()?;
718                    self.until(b']')?;
719                    Ok((Expr::new(ExprKind::Repeat { value: Box::new(first), len }, Span::new(start, self.current_pos())), false))
720                } else {
721                    let mut items = vec![first];
722                    while self.take(b',').is_ok() {
723                        self.whitespace()?;
724                        if self.take(b']').is_ok() {
725                            return Ok((Expr::new(ExprKind::List(items), Span::new(start, self.current_pos())), false));
726                        }
727                        items.push(self.expr_with_min_weight(None, None, 0, true)?.0);
728                        self.whitespace()?;
729                    }
730                    self.until(b']')?;
731                    Ok((Expr::new(ExprKind::List(items), Span::new(start, self.current_pos())), false))
732                }
733            }
734        } else if ch == b'{'
735            && (left.is_none() || left_op.is_some())
736            && let Ok(expr) = try_parse!(self, self.static_dynamic_literal_expr())
737        {
738            Ok((expr, false))
739        } else if ch == b'{'
740            && (left.is_none() || left_op.is_some())
741            && let Ok(dict) = try_parse!(self, self.dict())
742        {
743            Ok((dict, false))
744        } else if (left.is_none() || left_op.is_some()) && self.keyword("if").is_ok() {
745            let stmt = self.if_block()?;
746            Ok((Expr::new(ExprKind::Stmt(Box::new(stmt)), Span::new(start, self.current_pos())), true))
747        } else if ch == b'|' && left.is_none() {
748            let start = self.current_pos();
749            self.pos += 1;
750            let args = crate::parse_list!(self, Vec::new(), b'|', b',', self.ident_typed()?);
751            let body = Box::new(self.block()?);
752            Ok((Expr::new(ExprKind::Closure { args, body }, Span::new(start, self.current_pos())), true))
753        } else if let Some(this_op) = self.binary_op() {
754            let (left, close) = left.ok_or(anyhow!("{:?} need left value", this_op))?;
755            if this_op == BinaryOp::RangeOpen {
756                self.whitespace()?;
757                if self.get()? == b']' {
758                    let span = Span::new(left.span.start, self.current_pos());
759                    let stop = Expr::new(ExprKind::Value(Dynamic::Null), Span::empty(self.current_pos()));
760                    return Ok((Expr::new(ExprKind::Range { start: Box::new(left), stop: Box::new(stop), inclusive: false }, span), false));
761                }
762            }
763            if this_op.weight() < min_weight {
764                self.pos = start;
765                return Ok((left, close));
766            }
767            if left_op.is_some() {
768                return Err(anyhow!("unexpected binary op {:?}", this_op));
769            }
770            return if !close && left.binary_op().map(|op| op.weight() < this_op.weight()).unwrap_or(false) {
771                let (binary_left, op, right) = left.binary().unwrap();
772                let this_weight = this_op.weight();
773                let new_right = self.expr_with_min_weight(Some((right, false)), Some(this_op), this_weight, allow_struct_literal)?.0;
774                let span = binary_left.span.merge(new_right.span);
775                let expr = Expr::new(ExprKind::Binary { left: Box::new(binary_left), op, right: Box::new(new_right) }, span);
776                self.expr_with_min_weight(Some((expr, false)), None, min_weight, allow_struct_literal)
777            } else {
778                self.expr_with_min_weight(Some((left, false)), Some(this_op), min_weight, allow_struct_literal)
779            };
780        } else if self.keyword("as").is_ok() && left.is_some() {
781            let value = left.unwrap().0;
782            let start = value.span.start;
783            let ty = self.get_type()?;
784            return Ok((Expr::new(ExprKind::Typed { value: Box::new(value), ty }, Span::new(start, self.current_pos())), false));
785        } else {
786            self.base_expr(allow_struct_literal).map(|e| (e, false))
787        };
788
789        if left.is_some() {
790            if let Some(op) = left_op {
791                let left = left.unwrap().0;
792                let right = expr?.0;
793                let span = left.span.merge(right.span);
794                expr = Ok((
795                    match op {
796                        BinaryOp::RangeOpen => Expr::new(ExprKind::Range { start: Box::new(left), stop: Box::new(right), inclusive: false }, span),
797                        BinaryOp::RangeClose => Expr::new(ExprKind::Range { start: Box::new(left), stop: Box::new(right), inclusive: true }, span),
798                        _ => Expr::new(ExprKind::Binary { left: Box::new(left), op, right: Box::new(right) }, span),
799                    },
800                    false,
801                ));
802            } else if expr.is_ok() {
803                return Err(anyhow!("unexpected {:?}", expr));
804            } else {
805                return Ok((left.unwrap().0, false));
806            }
807        }
808        let result = self.expr_with_min_weight(Some(expr?), None, min_weight, allow_struct_literal)?;
809        Ok(result)
810    }
811}