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}