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