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            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}