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