1use crate::typ::{TVar, Type};
2use anyhow::{anyhow, bail, Result};
3use arcstr::ArcStr;
4use combine::stream::position::SourcePosition;
5use compact_str::{format_compact, CompactString};
6use netidx::{
7 path::Path,
8 publisher::Typ,
9 subscriber::{Event, Subscriber, Value},
10 utils::{self, Either},
11};
12use regex::Regex;
13use serde::{
14 de::{self, Visitor},
15 Deserialize, Deserializer, Serialize, Serializer,
16};
17use smallvec::{smallvec, SmallVec};
18use std::{
19 borrow::Borrow,
20 cmp::{Ordering, PartialEq, PartialOrd},
21 fmt::{self, Display, Write},
22 future::Future,
23 ops::Deref,
24 path::PathBuf,
25 pin::Pin,
26 result,
27 str::FromStr,
28 sync::LazyLock,
29 time::Duration,
30};
31use triomphe::Arc;
32
33pub mod parser;
34#[cfg(test)]
35mod test;
36
37pub static VNAME: LazyLock<Regex> =
38 LazyLock::new(|| Regex::new("^[a-z][a-z0-9_]*$").unwrap());
39
40atomic_id!(ExprId);
41
42#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
43pub struct ModPath(pub Path);
44
45impl FromStr for ModPath {
46 type Err = anyhow::Error;
47
48 fn from_str(s: &str) -> result::Result<Self, Self::Err> {
49 parser::parse_modpath(s)
50 }
51}
52
53impl ModPath {
54 pub fn root() -> ModPath {
55 ModPath(Path::root())
56 }
57}
58
59impl Borrow<str> for ModPath {
60 fn borrow(&self) -> &str {
61 self.0.borrow()
62 }
63}
64
65impl Deref for ModPath {
66 type Target = Path;
67
68 fn deref(&self) -> &Self::Target {
69 &self.0
70 }
71}
72
73impl Display for ModPath {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 let len = Path::levels(&self.0);
76 for (i, part) in Path::parts(&self.0).enumerate() {
77 write!(f, "{part}")?;
78 if i < len - 1 {
79 write!(f, "::")?
80 }
81 }
82 Ok(())
83 }
84}
85
86impl<A> FromIterator<A> for ModPath
87where
88 A: Borrow<str>,
89{
90 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
91 ModPath(Path::from_iter(iter))
92 }
93}
94
95impl<I, A> From<I> for ModPath
96where
97 A: Borrow<str>,
98 I: IntoIterator<Item = A>,
99{
100 fn from(value: I) -> Self {
101 ModPath::from_iter(value)
102 }
103}
104
105impl PartialEq<[&str]> for ModPath {
106 fn eq(&self, other: &[&str]) -> bool {
107 Path::levels(&self.0) == other.len()
108 && Path::parts(&self.0).zip(other.iter()).all(|(s0, s1)| s0 == *s1)
109 }
110}
111
112impl<const L: usize> PartialEq<[&str; L]> for ModPath {
113 fn eq(&self, other: &[&str; L]) -> bool {
114 Path::levels(&self.0) == L
115 && Path::parts(&self.0).zip(other.iter()).all(|(s0, s1)| s0 == *s1)
116 }
117}
118
119#[derive(Debug, Clone)]
120pub enum ModuleResolver {
121 Files(PathBuf),
122 Netidx { subscriber: Subscriber, base: Path, timeout: Option<Duration> },
123}
124
125impl ModuleResolver {
126 pub fn parse_env(
133 subscriber: Subscriber,
134 timeout: Option<Duration>,
135 s: &str,
136 ) -> Result<Vec<ModuleResolver>> {
137 let mut res = vec![];
138 for l in utils::split_escaped(s, '\\', ',') {
139 let l = l.trim();
140 if let Some(s) = l.strip_prefix("netidx:") {
141 let base = Path::from_str(s);
142 let r = Self::Netidx { subscriber: subscriber.clone(), timeout, base };
143 res.push(r);
144 } else if let Some(s) = l.strip_prefix("file:") {
145 let base = PathBuf::from_str(s)?;
146 let r = Self::Files(base);
147 res.push(r);
148 } else {
149 bail!("expected netidx: or file:")
150 }
151 }
152 Ok(res)
153 }
154}
155
156#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
157pub enum StructurePattern {
158 Ignore,
159 Literal(Value),
160 Bind(ArcStr),
161 Slice {
162 all: Option<ArcStr>,
163 binds: Arc<[StructurePattern]>,
164 },
165 SlicePrefix {
166 all: Option<ArcStr>,
167 prefix: Arc<[StructurePattern]>,
168 tail: Option<ArcStr>,
169 },
170 SliceSuffix {
171 all: Option<ArcStr>,
172 head: Option<ArcStr>,
173 suffix: Arc<[StructurePattern]>,
174 },
175 Tuple {
176 all: Option<ArcStr>,
177 binds: Arc<[StructurePattern]>,
178 },
179 Variant {
180 all: Option<ArcStr>,
181 tag: ArcStr,
182 binds: Arc<[StructurePattern]>,
183 },
184 Struct {
185 exhaustive: bool,
186 all: Option<ArcStr>,
187 binds: Arc<[(ArcStr, StructurePattern)]>,
188 },
189}
190
191impl StructurePattern {
192 pub fn single_bind(&self) -> Option<&ArcStr> {
193 match self {
194 Self::Bind(s) => Some(s),
195 Self::Ignore
196 | Self::Literal(_)
197 | Self::Slice { .. }
198 | Self::SlicePrefix { .. }
199 | Self::SliceSuffix { .. }
200 | Self::Tuple { .. }
201 | Self::Struct { .. }
202 | Self::Variant { .. } => None,
203 }
204 }
205
206 pub fn with_names<'a>(&'a self, f: &mut impl FnMut(&'a ArcStr)) {
207 match self {
208 Self::Bind(n) => f(n),
209 Self::Ignore | Self::Literal(_) => (),
210 Self::Slice { all, binds } => {
211 if let Some(n) = all {
212 f(n)
213 }
214 for t in binds.iter() {
215 t.with_names(f)
216 }
217 }
218 Self::SlicePrefix { all, prefix, tail } => {
219 if let Some(n) = all {
220 f(n)
221 }
222 if let Some(n) = tail {
223 f(n)
224 }
225 for t in prefix.iter() {
226 t.with_names(f)
227 }
228 }
229 Self::SliceSuffix { all, head, suffix } => {
230 if let Some(n) = all {
231 f(n)
232 }
233 if let Some(n) = head {
234 f(n)
235 }
236 for t in suffix.iter() {
237 t.with_names(f)
238 }
239 }
240 Self::Tuple { all, binds } => {
241 if let Some(n) = all {
242 f(n)
243 }
244 for t in binds.iter() {
245 t.with_names(f)
246 }
247 }
248 Self::Variant { all, tag: _, binds } => {
249 if let Some(n) = all {
250 f(n)
251 }
252 for t in binds.iter() {
253 t.with_names(f)
254 }
255 }
256 Self::Struct { exhaustive: _, all, binds } => {
257 if let Some(n) = all {
258 f(n)
259 }
260 for (_, t) in binds.iter() {
261 t.with_names(f)
262 }
263 }
264 }
265 }
266
267 pub fn binds_uniq(&self) -> bool {
268 let mut names: SmallVec<[&ArcStr; 16]> = smallvec![];
269 self.with_names(&mut |s| names.push(s));
270 names.sort();
271 let len = names.len();
272 names.dedup();
273 names.len() == len
274 }
275
276 pub fn infer_type_predicate(&self) -> Type {
277 match self {
278 Self::Bind(_) | Self::Ignore => Type::empty_tvar(),
279 Self::Literal(v) => Type::Primitive(Typ::get(v).into()),
280 Self::Tuple { all: _, binds } => {
281 let a = binds.iter().map(|p| p.infer_type_predicate());
282 Type::Tuple(Arc::from_iter(a))
283 }
284 Self::Variant { all: _, tag, binds } => {
285 let a = binds.iter().map(|p| p.infer_type_predicate());
286 Type::Variant(tag.clone(), Arc::from_iter(a))
287 }
288 Self::Slice { all: _, binds }
289 | Self::SlicePrefix { all: _, prefix: binds, tail: _ }
290 | Self::SliceSuffix { all: _, head: _, suffix: binds } => {
291 let t = binds
292 .iter()
293 .fold(Type::Bottom, |t, p| t.union(&p.infer_type_predicate()));
294 Type::Array(Arc::new(t))
295 }
296 Self::Struct { all: _, exhaustive: _, binds } => {
297 let mut typs = binds
298 .iter()
299 .map(|(n, p)| (n.clone(), p.infer_type_predicate()))
300 .collect::<SmallVec<[(ArcStr, Type); 8]>>();
301 typs.sort_by_key(|(n, _)| n.clone());
302 Type::Struct(Arc::from_iter(typs.into_iter()))
303 }
304 }
305 }
306}
307
308impl fmt::Display for StructurePattern {
309 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310 macro_rules! with_sep {
311 ($binds:expr) => {
312 for (i, b) in $binds.iter().enumerate() {
313 write!(f, "{b}")?;
314 if i < $binds.len() - 1 {
315 write!(f, ", ")?
316 }
317 }
318 };
319 }
320 match self {
321 StructurePattern::Ignore => write!(f, "_"),
322 StructurePattern::Literal(v) => write!(f, "{v}"),
323 StructurePattern::Bind(n) => write!(f, "{n}"),
324 StructurePattern::Slice { all, binds } => {
325 if let Some(all) = all {
326 write!(f, "{all}@ ")?
327 }
328 write!(f, "[")?;
329 with_sep!(binds);
330 write!(f, "]")
331 }
332 StructurePattern::SlicePrefix { all, prefix, tail } => {
333 if let Some(all) = all {
334 write!(f, "{all}@ ")?
335 }
336 write!(f, "[")?;
337 for b in prefix.iter() {
338 write!(f, "{b}, ")?
339 }
340 match tail {
341 None => write!(f, "..]"),
342 Some(name) => write!(f, "{name}..]"),
343 }
344 }
345 StructurePattern::SliceSuffix { all, head, suffix } => {
346 if let Some(all) = all {
347 write!(f, "{all}@ ")?
348 }
349 write!(f, "[")?;
350 match head {
351 None => write!(f, ".., ")?,
352 Some(name) => write!(f, "{name}.., ")?,
353 }
354 with_sep!(suffix);
355 write!(f, "]")
356 }
357 StructurePattern::Tuple { all, binds } => {
358 if let Some(all) = all {
359 write!(f, "{all}@ ")?
360 }
361 write!(f, "(")?;
362 with_sep!(binds);
363 write!(f, ")")
364 }
365 StructurePattern::Variant { all, tag, binds } if binds.len() == 0 => {
366 if let Some(all) = all {
367 write!(f, "{all}@")?
368 }
369 write!(f, "`{tag}")
370 }
371 StructurePattern::Variant { all, tag, binds } => {
372 if let Some(all) = all {
373 write!(f, "{all}@")?
374 }
375 write!(f, "`{tag}(")?;
376 with_sep!(binds);
377 write!(f, ")")
378 }
379 StructurePattern::Struct { exhaustive, all, binds } => {
380 if let Some(all) = all {
381 write!(f, "{all}@ ")?
382 }
383 write!(f, "{{")?;
384 for (i, (name, pat)) in binds.iter().enumerate() {
385 write!(f, "{name}: {pat}")?;
386 if !exhaustive || i < binds.len() - 1 {
387 write!(f, ", ")?
388 }
389 }
390 if !exhaustive {
391 write!(f, "..")?
392 }
393 write!(f, "}}")
394 }
395 }
396 }
397}
398
399#[derive(Debug, Clone, PartialEq, PartialOrd)]
400pub struct Pattern {
401 pub type_predicate: Option<Type>,
402 pub structure_predicate: StructurePattern,
403 pub guard: Option<Expr>,
404}
405
406#[derive(Debug, Clone, PartialEq, PartialOrd)]
407pub struct Arg {
408 pub labeled: Option<Option<Expr>>,
409 pub pattern: StructurePattern,
410 pub constraint: Option<Type>,
411}
412
413#[derive(Debug, Clone, PartialEq, PartialOrd)]
414pub enum ModuleKind {
415 Inline(Arc<[Expr]>),
416 Resolved(Origin),
417 Unresolved,
418}
419
420#[derive(Debug, Clone, PartialEq, PartialOrd)]
421pub struct Bind {
422 pub doc: Option<ArcStr>,
423 pub pattern: StructurePattern,
424 pub typ: Option<Type>,
425 pub export: bool,
426 pub value: Expr,
427}
428
429#[derive(Debug, Clone, PartialEq, PartialOrd)]
430pub struct Lambda {
431 pub args: Arc<[Arg]>,
432 pub vargs: Option<Option<Type>>,
433 pub rtype: Option<Type>,
434 pub constraints: Arc<[(TVar, Type)]>,
435 pub body: Either<Expr, ArcStr>,
436}
437
438#[derive(Debug, Clone, PartialEq, PartialOrd)]
439pub enum ExprKind {
440 Constant(Value),
441 Module { name: ArcStr, export: bool, value: ModuleKind },
442 Do { exprs: Arc<[Expr]> },
443 Use { name: ModPath },
444 Bind(Arc<Bind>),
445 Ref { name: ModPath },
446 Connect { name: ModPath, value: Arc<Expr> },
447 StringInterpolate { args: Arc<[Expr]> },
448 StructRef { source: Arc<Expr>, field: ArcStr },
449 TupleRef { source: Arc<Expr>, field: usize },
450 ArrayRef { source: Arc<Expr>, i: Arc<Expr> },
451 ArraySlice { source: Arc<Expr>, start: Option<Arc<Expr>>, end: Option<Arc<Expr>> },
452 StructWith { source: Arc<Expr>, replace: Arc<[(ArcStr, Expr)]> },
453 Lambda(Arc<Lambda>),
454 TypeDef { name: ArcStr, params: Arc<[(TVar, Option<Type>)]>, typ: Type },
455 TypeCast { expr: Arc<Expr>, typ: Type },
456 Apply { args: Arc<[(Option<ArcStr>, Expr)]>, function: Arc<Expr> },
457 Any { args: Arc<[Expr]> },
458 Array { args: Arc<[Expr]> },
459 Tuple { args: Arc<[Expr]> },
460 Variant { tag: ArcStr, args: Arc<[Expr]> },
461 Struct { args: Arc<[(ArcStr, Expr)]> },
462 Select { arg: Arc<Expr>, arms: Arc<[(Pattern, Expr)]> },
463 Qop(Arc<Expr>),
464 ByRef(Arc<Expr>),
465 Deref(Arc<Expr>),
466 Eq { lhs: Arc<Expr>, rhs: Arc<Expr> },
467 Ne { lhs: Arc<Expr>, rhs: Arc<Expr> },
468 Lt { lhs: Arc<Expr>, rhs: Arc<Expr> },
469 Gt { lhs: Arc<Expr>, rhs: Arc<Expr> },
470 Lte { lhs: Arc<Expr>, rhs: Arc<Expr> },
471 Gte { lhs: Arc<Expr>, rhs: Arc<Expr> },
472 And { lhs: Arc<Expr>, rhs: Arc<Expr> },
473 Or { lhs: Arc<Expr>, rhs: Arc<Expr> },
474 Not { expr: Arc<Expr> },
475 Add { lhs: Arc<Expr>, rhs: Arc<Expr> },
476 Sub { lhs: Arc<Expr>, rhs: Arc<Expr> },
477 Mul { lhs: Arc<Expr>, rhs: Arc<Expr> },
478 Div { lhs: Arc<Expr>, rhs: Arc<Expr> },
479}
480
481impl ExprKind {
482 pub fn to_expr(self, pos: SourcePosition) -> Expr {
483 Expr { id: ExprId::new(), pos, kind: self }
484 }
485
486 pub fn to_expr_nopos(self) -> Expr {
488 Expr { id: ExprId::new(), pos: Default::default(), kind: self }
489 }
490
491 pub fn to_string_pretty(&self, col_limit: usize) -> String {
492 let mut buf = String::new();
493 self.pretty_print(0, col_limit, true, &mut buf).unwrap();
494 buf
495 }
496
497 fn pretty_print(
498 &self,
499 indent: usize,
500 limit: usize,
501 newline: bool,
502 buf: &mut String,
503 ) -> fmt::Result {
504 macro_rules! kill_newline {
505 ($buf:expr) => {
506 if let Some('\n') = $buf.chars().next_back() {
507 $buf.pop();
508 }
509 };
510 }
511 macro_rules! try_single_line {
512 ($trunc:ident) => {{
513 let len = buf.len();
514 let (start, indent) = if newline {
515 push_indent(indent, buf);
516 (len, indent)
517 } else {
518 (buf.rfind('\n').unwrap_or(0), 0)
519 };
520 writeln!(buf, "{}", self)?;
521 if buf.len() - start <= limit {
522 return Ok(());
523 } else {
524 if $trunc {
525 buf.truncate(len + indent)
526 }
527 len + indent
528 }
529 }};
530 }
531 macro_rules! binop {
532 ($sep:literal, $lhs:expr, $rhs:expr) => {{
533 try_single_line!(true);
534 write!(buf, "(")?;
535 writeln!(buf, "{} {}", $lhs, $sep)?;
536 $rhs.kind.pretty_print(indent, limit, true, buf)?;
537 write!(buf, ")")
538 }};
539 }
540 let mut tbuf = CompactString::new("");
541 macro_rules! typ {
542 ($typ:expr) => {{
543 match $typ {
544 None => "",
545 Some(typ) => {
546 tbuf.clear();
547 write!(tbuf, ": {typ}")?;
548 tbuf.as_str()
549 }
550 }
551 }};
552 }
553 fn push_indent(indent: usize, buf: &mut String) {
554 buf.extend((0..indent).into_iter().map(|_| ' '));
555 }
556 fn pretty_print_exprs_int<'a, A, F: Fn(&'a A) -> &'a Expr>(
557 indent: usize,
558 limit: usize,
559 buf: &mut String,
560 exprs: &'a [A],
561 open: &str,
562 close: &str,
563 sep: &str,
564 f: F,
565 ) -> fmt::Result {
566 writeln!(buf, "{}", open)?;
567 for i in 0..exprs.len() {
568 f(&exprs[i]).kind.pretty_print(indent + 2, limit, true, buf)?;
569 if i < exprs.len() - 1 {
570 kill_newline!(buf);
571 writeln!(buf, "{}", sep)?
572 }
573 }
574 push_indent(indent, buf);
575 writeln!(buf, "{}", close)
576 }
577 fn pretty_print_exprs(
578 indent: usize,
579 limit: usize,
580 buf: &mut String,
581 exprs: &[Expr],
582 open: &str,
583 close: &str,
584 sep: &str,
585 ) -> fmt::Result {
586 pretty_print_exprs_int(indent, limit, buf, exprs, open, close, sep, |a| a)
587 }
588 let exp = |export| if export { "pub " } else { "" };
589 match self {
590 ExprKind::Constant(_)
591 | ExprKind::Use { .. }
592 | ExprKind::Ref { .. }
593 | ExprKind::StructRef { .. }
594 | ExprKind::TupleRef { .. }
595 | ExprKind::TypeDef { .. }
596 | ExprKind::ArrayRef { .. }
597 | ExprKind::ArraySlice { .. }
598 | ExprKind::StringInterpolate { .. }
599 | ExprKind::Module {
600 name: _,
601 export: _,
602 value: ModuleKind::Unresolved | ModuleKind::Resolved(_),
603 } => {
604 if newline {
605 push_indent(indent, buf);
606 }
607 writeln!(buf, "{self}")
608 }
609 ExprKind::Bind(b) => {
610 let Bind { doc, pattern, typ, export, value } = &**b;
611 try_single_line!(true);
612 if let Some(doc) = doc {
613 if doc == "" {
614 writeln!(buf, "///")?;
615 } else {
616 for line in doc.lines() {
617 writeln!(buf, "///{line}")?;
618 }
619 }
620 }
621 writeln!(buf, "{}let {pattern}{} = ", exp(*export), typ!(typ))?;
622 value.kind.pretty_print(indent + 2, limit, false, buf)
623 }
624 ExprKind::StructWith { source, replace } => {
625 try_single_line!(true);
626 match &source.kind {
627 ExprKind::Ref { .. }
628 | ExprKind::Do { .. }
629 | ExprKind::Apply { .. } => writeln!(buf, "{{ {source} with")?,
630 _ => writeln!(buf, "{{ ({source}) with")?,
631 }
632 let indent = indent + 2;
633 for (i, (name, e)) in replace.iter().enumerate() {
634 push_indent(indent, buf);
635 write!(buf, "{name}: ")?;
636 e.kind.pretty_print(indent + 2, limit, false, buf)?;
637 if i < replace.len() - 1 {
638 kill_newline!(buf);
639 writeln!(buf, ",")?
640 }
641 }
642 writeln!(buf, "}}")
643 }
644 ExprKind::Module { name, export, value: ModuleKind::Inline(exprs) } => {
645 try_single_line!(true);
646 write!(buf, "{}mod {name} ", exp(*export))?;
647 pretty_print_exprs(indent, limit, buf, exprs, "{", "}", ";")
648 }
649 ExprKind::Do { exprs } => {
650 try_single_line!(true);
651 pretty_print_exprs(indent, limit, buf, exprs, "{", "}", ";")
652 }
653 ExprKind::Connect { name, value } => {
654 try_single_line!(true);
655 writeln!(buf, "{name} <- ")?;
656 value.kind.pretty_print(indent + 2, limit, false, buf)
657 }
658 ExprKind::TypeCast { expr, typ } => {
659 try_single_line!(true);
660 writeln!(buf, "cast<{typ}>(")?;
661 expr.kind.pretty_print(indent + 2, limit, true, buf)?;
662 writeln!(buf, ")")
663 }
664 ExprKind::Array { args } => {
665 try_single_line!(true);
666 pretty_print_exprs(indent, limit, buf, args, "[", "]", ",")
667 }
668 ExprKind::Any { args } => {
669 try_single_line!(true);
670 write!(buf, "any")?;
671 pretty_print_exprs(indent, limit, buf, args, "(", ")", ",")
672 }
673 ExprKind::Tuple { args } => {
674 try_single_line!(true);
675 pretty_print_exprs(indent, limit, buf, args, "(", ")", ",")
676 }
677 ExprKind::Variant { tag: _, args } if args.len() == 0 => {
678 if newline {
679 push_indent(indent, buf)
680 }
681 write!(buf, "{self}")
682 }
683 ExprKind::Variant { tag, args } => {
684 try_single_line!(true);
685 write!(buf, "`{tag}")?;
686 pretty_print_exprs(indent, limit, buf, args, "(", ")", ",")
687 }
688 ExprKind::Struct { args } => {
689 try_single_line!(true);
690 writeln!(buf, "{{")?;
691 for (i, (n, e)) in args.iter().enumerate() {
692 push_indent(indent + 2, buf);
693 write!(buf, "{n}: ")?;
694 e.kind.pretty_print(indent + 2, limit, false, buf)?;
695 if i < args.len() - 1 {
696 kill_newline!(buf);
697 writeln!(buf, ", ")?
698 }
699 }
700 push_indent(indent, buf);
701 writeln!(buf, "}}")
702 }
703 ExprKind::Qop(e) => {
704 try_single_line!(true);
705 e.kind.pretty_print(indent, limit, true, buf)?;
706 kill_newline!(buf);
707 writeln!(buf, "?")
708 }
709 ExprKind::Apply { function, args } => {
710 try_single_line!(true);
711 match &function.kind {
712 ExprKind::Ref { .. } | ExprKind::Do { .. } => {
713 function.kind.pretty_print(indent, limit, true, buf)?
714 }
715 e => {
716 write!(buf, "(")?;
717 e.pretty_print(indent, limit, true, buf)?;
718 kill_newline!(buf);
719 write!(buf, ")")?;
720 }
721 }
722 kill_newline!(buf);
723 writeln!(buf, "(")?;
724 for i in 0..args.len() {
725 match &args[i].0 {
726 None => {
727 args[i].1.kind.pretty_print(indent + 2, limit, true, buf)?
728 }
729 Some(name) => match &args[i].1.kind {
730 ExprKind::Ref { name: n }
731 if Path::dirname(&n.0).is_none()
732 && Path::basename(&n.0) == Some(name.as_str()) =>
733 {
734 writeln!(buf, "#{name}")?
735 }
736 _ => {
737 write!(buf, "#{name}: ")?;
738 args[i].1.kind.pretty_print(
739 indent + 2,
740 limit,
741 false,
742 buf,
743 )?
744 }
745 },
746 }
747 if i < args.len() - 1 {
748 kill_newline!(buf);
749 writeln!(buf, ",")?
750 }
751 }
752 writeln!(buf, ")")
753 }
754 ExprKind::Lambda(l) => {
755 let Lambda { args, vargs, rtype, constraints, body } = &**l;
756 try_single_line!(true);
757 for (i, (tvar, typ)) in constraints.iter().enumerate() {
758 write!(buf, "{tvar}: {typ}")?;
759 if i < constraints.len() - 1 {
760 write!(buf, ", ")?;
761 }
762 }
763 write!(buf, "|")?;
764 for (i, a) in args.iter().enumerate() {
765 match &a.labeled {
766 None => {
767 write!(buf, "{}", a.pattern)?;
768 buf.push_str(typ!(&a.constraint));
769 }
770 Some(def) => {
771 write!(buf, "#{}", a.pattern)?;
772 buf.push_str(typ!(&a.constraint));
773 if let Some(def) = def {
774 write!(buf, " = {def}")?;
775 }
776 }
777 }
778 if vargs.is_some() || i < args.len() - 1 {
779 write!(buf, ", ")?
780 }
781 }
782 if let Some(typ) = vargs {
783 write!(buf, "@args{}", typ!(typ))?;
784 }
785 write!(buf, "| ")?;
786 if let Some(t) = rtype {
787 write!(buf, "-> {t} ")?
788 }
789 match body {
790 Either::Right(builtin) => {
791 writeln!(buf, "'{builtin}")
792 }
793 Either::Left(body) => match &body.kind {
794 ExprKind::Do { exprs } => {
795 pretty_print_exprs(indent, limit, buf, exprs, "{", "}", ";")
796 }
797 _ => body.kind.pretty_print(indent, limit, false, buf),
798 },
799 }
800 }
801 ExprKind::Eq { lhs, rhs } => binop!("==", lhs, rhs),
802 ExprKind::Ne { lhs, rhs } => binop!("!=", lhs, rhs),
803 ExprKind::Lt { lhs, rhs } => binop!("<", lhs, rhs),
804 ExprKind::Gt { lhs, rhs } => binop!(">", lhs, rhs),
805 ExprKind::Lte { lhs, rhs } => binop!("<=", lhs, rhs),
806 ExprKind::Gte { lhs, rhs } => binop!(">=", lhs, rhs),
807 ExprKind::And { lhs, rhs } => binop!("&&", lhs, rhs),
808 ExprKind::Or { lhs, rhs } => binop!("||", lhs, rhs),
809 ExprKind::Add { lhs, rhs } => binop!("+", lhs, rhs),
810 ExprKind::Sub { lhs, rhs } => binop!("-", lhs, rhs),
811 ExprKind::Mul { lhs, rhs } => binop!("*", lhs, rhs),
812 ExprKind::Div { lhs, rhs } => binop!("/", lhs, rhs),
813 ExprKind::Not { expr } => {
814 try_single_line!(true);
815 match &expr.kind {
816 ExprKind::Do { exprs } => {
817 pretty_print_exprs(indent, limit, buf, exprs, "!{", "}", ";")
818 }
819 _ => {
820 writeln!(buf, "!(")?;
821 expr.kind.pretty_print(indent + 2, limit, true, buf)?;
822 push_indent(indent, buf);
823 writeln!(buf, ")")
824 }
825 }
826 }
827 ExprKind::ByRef(e) => {
828 try_single_line!(true);
829 write!(buf, "&")?;
830 e.kind.pretty_print(indent + 2, limit, false, buf)
831 }
832 ExprKind::Deref(e) => {
833 try_single_line!(true);
834 write!(buf, "*")?;
835 e.kind.pretty_print(indent + 2, limit, false, buf)
836 }
837 ExprKind::Select { arg, arms } => {
838 try_single_line!(true);
839 write!(buf, "select ")?;
840 arg.kind.pretty_print(indent, limit, false, buf)?;
841 kill_newline!(buf);
842 writeln!(buf, " {{")?;
843 for (i, (pat, expr)) in arms.iter().enumerate() {
844 if let Some(tp) = &pat.type_predicate {
845 write!(buf, "{tp} as ")?;
846 }
847 write!(buf, "{} ", pat.structure_predicate)?;
848 if let Some(guard) = &pat.guard {
849 write!(buf, "if ")?;
850 guard.kind.pretty_print(indent + 2, limit, false, buf)?;
851 kill_newline!(buf);
852 write!(buf, " ")?;
853 }
854 write!(buf, "=> ")?;
855 if let ExprKind::Do { exprs } = &expr.kind {
856 let term = if i < arms.len() - 1 { "}," } else { "}" };
857 pretty_print_exprs(
858 indent + 2,
859 limit,
860 buf,
861 exprs,
862 "{",
863 term,
864 ";",
865 )?;
866 } else if i < arms.len() - 1 {
867 expr.kind.pretty_print(indent + 2, limit, false, buf)?;
868 kill_newline!(buf);
869 writeln!(buf, ",")?
870 } else {
871 expr.kind.pretty_print(indent, limit, false, buf)?;
872 }
873 }
874 push_indent(indent, buf);
875 writeln!(buf, "}}")
876 }
877 }
878 }
879}
880
881impl fmt::Display for ExprKind {
882 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
883 fn write_binop(
884 f: &mut fmt::Formatter,
885 op: &str,
886 lhs: &Expr,
887 rhs: &Expr,
888 ) -> fmt::Result {
889 write!(f, "(")?;
890 write!(f, "{lhs} {op} {rhs}")?;
891 write!(f, ")")
892 }
893 fn print_exprs(
894 f: &mut fmt::Formatter,
895 exprs: &[Expr],
896 open: &str,
897 close: &str,
898 sep: &str,
899 ) -> fmt::Result {
900 write!(f, "{open}")?;
901 for i in 0..exprs.len() {
902 write!(f, "{}", &exprs[i])?;
903 if i < exprs.len() - 1 {
904 write!(f, "{sep}")?
905 }
906 }
907 write!(f, "{close}")
908 }
909 let mut tbuf = CompactString::new("");
910 macro_rules! typ {
911 ($typ:expr) => {{
912 match $typ {
913 None => "",
914 Some(typ) => {
915 tbuf.clear();
916 write!(tbuf, ": {typ}")?;
917 tbuf.as_str()
918 }
919 }
920 }};
921 }
922 let exp = |export| if export { "pub " } else { "" };
923 match self {
924 ExprKind::Constant(v) => v.fmt_ext(f, &parser::BSCRIPT_ESC, true),
925 ExprKind::Bind(b) => {
926 let Bind { doc, pattern, typ, export, value } = &**b;
927 if let Some(doc) = doc {
928 if doc == "" {
929 writeln!(f, "///")?
930 } else {
931 for line in doc.lines() {
932 writeln!(f, "///{line}")?
933 }
934 }
935 }
936 write!(f, "{}let {pattern}{} = {value}", exp(*export), typ!(typ))
937 }
938 ExprKind::StructWith { source, replace } => {
939 match &source.kind {
940 ExprKind::Ref { .. }
941 | ExprKind::Do { .. }
942 | ExprKind::Apply { .. } => write!(f, "{{ {source} with ")?,
943 _ => write!(f, "{{ ({source}) with ")?,
944 }
945 for (i, (name, e)) in replace.iter().enumerate() {
946 write!(f, "{name}: {e}")?;
947 if i < replace.len() - 1 {
948 write!(f, ", ")?
949 }
950 }
951 write!(f, " }}")
952 }
953 ExprKind::Connect { name, value } => write!(f, "{name} <- {value}"),
954 ExprKind::Use { name } => {
955 write!(f, "use {name}")
956 }
957 ExprKind::Ref { name } => {
958 write!(f, "{name}")
959 }
960 ExprKind::StructRef { source, field } => match &source.kind {
961 ExprKind::Do { .. } | ExprKind::Ref { .. } | ExprKind::Apply { .. } => {
962 write!(f, "{source}.{field}")
963 }
964 source => write!(f, "({source}).{field}"),
965 },
966 ExprKind::TupleRef { source, field } => match &source.kind {
967 ExprKind::Do { .. } | ExprKind::Ref { .. } | ExprKind::Apply { .. } => {
968 write!(f, "{source}.{field}")
969 }
970 source => write!(f, "({source}).{field}"),
971 },
972 ExprKind::Module { name, export, value } => {
973 write!(f, "{}mod {name}", exp(*export))?;
974 match value {
975 ModuleKind::Resolved(_) | ModuleKind::Unresolved => write!(f, ";"),
976 ModuleKind::Inline(exprs) => print_exprs(f, &**exprs, "{", "}", "; "),
977 }
978 }
979 ExprKind::TypeCast { expr, typ } => write!(f, "cast<{typ}>({expr})"),
980 ExprKind::TypeDef { name, params, typ } => {
981 write!(f, "type {name}")?;
982 if !params.is_empty() {
983 write!(f, "<")?;
984 for (i, (tv, ct)) in params.iter().enumerate() {
985 write!(f, "{tv}")?;
986 if let Some(ct) = ct {
987 write!(f, ": {ct}")?;
988 }
989 if i < params.len() - 1 {
990 write!(f, ", ")?;
991 }
992 }
993 write!(f, ">")?;
994 }
995 write!(f, " = {typ}")
996 }
997 ExprKind::Do { exprs } => print_exprs(f, &**exprs, "{", "}", "; "),
998 ExprKind::Lambda(l) => {
999 let Lambda { args, vargs, rtype, constraints, body } = &**l;
1000 for (i, (tvar, typ)) in constraints.iter().enumerate() {
1001 write!(f, "{tvar}: {typ}")?;
1002 if i < constraints.len() - 1 {
1003 write!(f, ", ")?;
1004 }
1005 }
1006 write!(f, "|")?;
1007 for (i, a) in args.iter().enumerate() {
1008 match &a.labeled {
1009 None => {
1010 write!(f, "{}", a.pattern)?;
1011 write!(f, "{}", typ!(&a.constraint))?;
1012 }
1013 Some(def) => {
1014 write!(f, "#{}", a.pattern)?;
1015 write!(f, "{}", typ!(&a.constraint))?;
1016 if let Some(def) = def {
1017 write!(f, " = {def}")?;
1018 }
1019 }
1020 }
1021 if vargs.is_some() || i < args.len() - 1 {
1022 write!(f, ", ")?
1023 }
1024 }
1025 if let Some(typ) = vargs {
1026 write!(f, "@args{}", typ!(typ))?;
1027 }
1028 write!(f, "| ")?;
1029 if let Some(t) = rtype {
1030 write!(f, "-> {t} ")?
1031 }
1032 match body {
1033 Either::Right(builtin) => write!(f, "'{builtin}"),
1034 Either::Left(body) => write!(f, "{body}"),
1035 }
1036 }
1037 ExprKind::Array { args } => print_exprs(f, args, "[", "]", ", "),
1038 ExprKind::Any { args } => {
1039 write!(f, "any")?;
1040 print_exprs(f, args, "(", ")", ", ")
1041 }
1042 ExprKind::Tuple { args } => print_exprs(f, args, "(", ")", ", "),
1043 ExprKind::Variant { tag, args } if args.len() == 0 => {
1044 write!(f, "`{tag}")
1045 }
1046 ExprKind::Variant { tag, args } => {
1047 write!(f, "`{tag}")?;
1048 print_exprs(f, args, "(", ")", ", ")
1049 }
1050 ExprKind::Struct { args } => {
1051 write!(f, "{{ ")?;
1052 for (i, (n, e)) in args.iter().enumerate() {
1053 write!(f, "{n}: {e}")?;
1054 if i < args.len() - 1 {
1055 write!(f, ", ")?
1056 }
1057 }
1058 write!(f, " }}")
1059 }
1060 ExprKind::Qop(e) => write!(f, "{}?", e),
1061 ExprKind::StringInterpolate { args } => {
1062 write!(f, "\"")?;
1063 for s in args.iter() {
1064 match &s.kind {
1065 ExprKind::Constant(Value::String(s)) if s.len() > 0 => {
1066 let es = utils::escape(&*s, '\\', &parser::BSCRIPT_ESC);
1067 write!(f, "{es}",)?;
1068 }
1069 s => {
1070 write!(f, "[{s}]")?;
1071 }
1072 }
1073 }
1074 write!(f, "\"")
1075 }
1076 ExprKind::ArrayRef { source, i } => match &source.kind {
1077 ExprKind::Ref { .. } | ExprKind::Do { .. } | ExprKind::Apply { .. } => {
1078 write!(f, "{}[{}]", source, i)
1079 }
1080 _ => write!(f, "({})[{}]", &source, &i),
1081 },
1082 ExprKind::ArraySlice { source, start, end } => {
1083 let s = match start.as_ref() {
1084 None => "",
1085 Some(e) => &format_compact!("{e}"),
1086 };
1087 let e = match &end.as_ref() {
1088 None => "",
1089 Some(e) => &format_compact!("{e}"),
1090 };
1091 match &source.kind {
1092 ExprKind::Ref { .. }
1093 | ExprKind::Do { .. }
1094 | ExprKind::Apply { .. } => {
1095 write!(f, "{}[{}..{}]", source, s, e)
1096 }
1097 _ => write!(f, "({})[{}..{}]", source, s, e),
1098 }
1099 }
1100 ExprKind::Apply { args, function } => {
1101 match &function.kind {
1102 ExprKind::Ref { name: _ } | ExprKind::Do { exprs: _ } => {
1103 write!(f, "{function}")?
1104 }
1105 function => write!(f, "({function})")?,
1106 }
1107 write!(f, "(")?;
1108 for i in 0..args.len() {
1109 match &args[i].0 {
1110 None => write!(f, "{}", &args[i].1)?,
1111 Some(name) => match &args[i].1.kind {
1112 ExprKind::Ref { name: n }
1113 if Path::dirname(&n.0).is_none()
1114 && Path::basename(&n.0) == Some(name.as_str()) =>
1115 {
1116 write!(f, "#{name}")?
1117 }
1118 _ => write!(f, "#{name}: {}", &args[i].1)?,
1119 },
1120 }
1121 if i < args.len() - 1 {
1122 write!(f, ", ")?
1123 }
1124 }
1125 write!(f, ")")
1126 }
1127 ExprKind::Select { arg, arms } => {
1128 write!(f, "select {arg} {{")?;
1129 for (i, (pat, rhs)) in arms.iter().enumerate() {
1130 if let Some(tp) = &pat.type_predicate {
1131 write!(f, "{tp} as ")?;
1132 }
1133 write!(f, "{} ", pat.structure_predicate)?;
1134 if let Some(guard) = &pat.guard {
1135 write!(f, "if {guard} ")?;
1136 }
1137 write!(f, "=> {rhs}")?;
1138 if i < arms.len() - 1 {
1139 write!(f, ", ")?
1140 }
1141 }
1142 write!(f, "}}")
1143 }
1144 ExprKind::Eq { lhs, rhs } => write_binop(f, "==", lhs, rhs),
1145 ExprKind::Ne { lhs, rhs } => write_binop(f, "!=", lhs, rhs),
1146 ExprKind::Gt { lhs, rhs } => write_binop(f, ">", lhs, rhs),
1147 ExprKind::Lt { lhs, rhs } => write_binop(f, "<", lhs, rhs),
1148 ExprKind::Gte { lhs, rhs } => write_binop(f, ">=", lhs, rhs),
1149 ExprKind::Lte { lhs, rhs } => write_binop(f, "<=", lhs, rhs),
1150 ExprKind::And { lhs, rhs } => write_binop(f, "&&", lhs, rhs),
1151 ExprKind::Or { lhs, rhs } => write_binop(f, "||", lhs, rhs),
1152 ExprKind::Add { lhs, rhs } => write_binop(f, "+", lhs, rhs),
1153 ExprKind::Sub { lhs, rhs } => write_binop(f, "-", lhs, rhs),
1154 ExprKind::Mul { lhs, rhs } => write_binop(f, "*", lhs, rhs),
1155 ExprKind::Div { lhs, rhs } => write_binop(f, "/", lhs, rhs),
1156 ExprKind::ByRef(e) => write!(f, "&{e}"),
1157 ExprKind::Deref(e) => write!(f, "*{e}"),
1158 ExprKind::Not { expr } => {
1159 write!(f, "(!{expr})")
1160 }
1161 }
1162 }
1163}
1164
1165#[derive(Debug, Clone)]
1166pub struct Expr {
1167 pub id: ExprId,
1168 pub pos: SourcePosition,
1169 pub kind: ExprKind,
1170}
1171
1172impl PartialOrd for Expr {
1173 fn partial_cmp(&self, rhs: &Expr) -> Option<Ordering> {
1174 self.kind.partial_cmp(&rhs.kind)
1175 }
1176}
1177
1178impl PartialEq for Expr {
1179 fn eq(&self, rhs: &Expr) -> bool {
1180 self.kind.eq(&rhs.kind)
1181 }
1182}
1183
1184impl Eq for Expr {}
1185
1186impl Serialize for Expr {
1187 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1188 where
1189 S: Serializer,
1190 {
1191 serializer.serialize_str(&self.to_string())
1192 }
1193}
1194
1195impl Default for Expr {
1196 fn default() -> Self {
1197 ExprKind::Constant(Value::Null).to_expr(Default::default())
1198 }
1199}
1200
1201impl FromStr for Expr {
1202 type Err = anyhow::Error;
1203
1204 fn from_str(s: &str) -> result::Result<Self, Self::Err> {
1205 parser::parse_one(s)
1206 }
1207}
1208
1209#[derive(Debug, Clone, PartialEq, PartialOrd)]
1211pub struct Origin {
1212 pub name: Option<ArcStr>,
1213 pub source: ArcStr,
1214 pub exprs: Arc<[Expr]>,
1215}
1216
1217impl fmt::Display for Origin {
1218 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1219 match &self.name {
1220 None => write!(f, "in expr {}", self.source),
1221 Some(n) => {
1222 if n.ends_with(".bs") {
1223 write!(f, "in file {n}")
1224 } else {
1225 write!(f, "in module {n}")
1226 }
1227 }
1228 }
1229 }
1230}
1231
1232#[derive(Clone, Copy)]
1233struct ExprVisitor;
1234
1235impl<'de> Visitor<'de> for ExprVisitor {
1236 type Value = Expr;
1237
1238 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1239 write!(formatter, "expected expression")
1240 }
1241
1242 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
1243 where
1244 E: de::Error,
1245 {
1246 Expr::from_str(s).map_err(de::Error::custom)
1247 }
1248
1249 fn visit_borrowed_str<E>(self, s: &'de str) -> Result<Self::Value, E>
1250 where
1251 E: de::Error,
1252 {
1253 Expr::from_str(s).map_err(de::Error::custom)
1254 }
1255
1256 fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
1257 where
1258 E: de::Error,
1259 {
1260 Expr::from_str(&s).map_err(de::Error::custom)
1261 }
1262}
1263
1264impl<'de> Deserialize<'de> for Expr {
1265 fn deserialize<D>(de: D) -> Result<Self, D::Error>
1266 where
1267 D: Deserializer<'de>,
1268 {
1269 de.deserialize_str(ExprVisitor)
1270 }
1271}
1272
1273impl Expr {
1274 pub fn new(kind: ExprKind, pos: SourcePosition) -> Self {
1275 Expr { id: ExprId::new(), pos, kind }
1276 }
1277
1278 pub fn to_string_pretty(&self, col_limit: usize) -> String {
1279 self.kind.to_string_pretty(col_limit)
1280 }
1281
1282 pub fn fold<T, F: FnMut(T, &Self) -> T>(&self, init: T, f: &mut F) -> T {
1284 let init = f(init, self);
1285 match &self.kind {
1286 ExprKind::Constant(_)
1287 | ExprKind::Use { .. }
1288 | ExprKind::Ref { .. }
1289 | ExprKind::StructRef { .. }
1290 | ExprKind::TupleRef { .. }
1291 | ExprKind::TypeDef { .. } => init,
1292 ExprKind::Module { value: ModuleKind::Inline(e), .. } => {
1293 e.iter().fold(init, |init, e| e.fold(init, f))
1294 }
1295 ExprKind::Module { value: ModuleKind::Resolved(o), .. } => {
1296 o.exprs.iter().fold(init, |init, e| e.fold(init, f))
1297 }
1298 ExprKind::Module { value: ModuleKind::Unresolved, .. } => init,
1299 ExprKind::Do { exprs } => exprs.iter().fold(init, |init, e| e.fold(init, f)),
1300 ExprKind::Bind(b) => b.value.fold(init, f),
1301 ExprKind::StructWith { replace, .. } => {
1302 replace.iter().fold(init, |init, (_, e)| e.fold(init, f))
1303 }
1304 ExprKind::Connect { value, .. } => value.fold(init, f),
1305 ExprKind::Lambda(l) => match &l.body {
1306 Either::Left(e) => e.fold(init, f),
1307 Either::Right(_) => init,
1308 },
1309 ExprKind::TypeCast { expr, .. } => expr.fold(init, f),
1310 ExprKind::Apply { args, function: _ } => {
1311 args.iter().fold(init, |init, (_, e)| e.fold(init, f))
1312 }
1313 ExprKind::Any { args }
1314 | ExprKind::Array { args }
1315 | ExprKind::Tuple { args }
1316 | ExprKind::Variant { args, .. }
1317 | ExprKind::StringInterpolate { args } => {
1318 args.iter().fold(init, |init, e| e.fold(init, f))
1319 }
1320 ExprKind::ArrayRef { source, i } => {
1321 let init = source.fold(init, f);
1322 i.fold(init, f)
1323 }
1324 ExprKind::ArraySlice { source, start, end } => {
1325 let init = source.fold(init, f);
1326 let init = match start {
1327 None => init,
1328 Some(e) => e.fold(init, f),
1329 };
1330 match end {
1331 None => init,
1332 Some(e) => e.fold(init, f),
1333 }
1334 }
1335 ExprKind::Struct { args } => {
1336 args.iter().fold(init, |init, (_, e)| e.fold(init, f))
1337 }
1338 ExprKind::Select { arg, arms } => {
1339 let init = arg.fold(init, f);
1340 arms.iter().fold(init, |init, (p, e)| {
1341 let init = match p.guard.as_ref() {
1342 None => init,
1343 Some(g) => g.fold(init, f),
1344 };
1345 e.fold(init, f)
1346 })
1347 }
1348 ExprKind::Qop(e)
1349 | ExprKind::ByRef(e)
1350 | ExprKind::Deref(e)
1351 | ExprKind::Not { expr: e } => e.fold(init, f),
1352 ExprKind::Add { lhs, rhs }
1353 | ExprKind::Sub { lhs, rhs }
1354 | ExprKind::Mul { lhs, rhs }
1355 | ExprKind::Div { lhs, rhs }
1356 | ExprKind::And { lhs, rhs }
1357 | ExprKind::Or { lhs, rhs }
1358 | ExprKind::Eq { lhs, rhs }
1359 | ExprKind::Ne { lhs, rhs }
1360 | ExprKind::Gt { lhs, rhs }
1361 | ExprKind::Lt { lhs, rhs }
1362 | ExprKind::Gte { lhs, rhs }
1363 | ExprKind::Lte { lhs, rhs } => {
1364 let init = lhs.fold(init, f);
1365 rhs.fold(init, f)
1366 }
1367 }
1368 }
1369
1370 pub fn has_unresolved_modules(&self) -> bool {
1371 self.fold(false, &mut |acc, e| {
1372 acc || match &e.kind {
1373 ExprKind::Module { value: ModuleKind::Unresolved, .. } => true,
1374 _ => false,
1375 }
1376 })
1377 }
1378
1379 pub async fn resolve_modules<'a>(
1384 &'a self,
1385 scope: &'a ModPath,
1386 resolvers: &'a [ModuleResolver],
1387 ) -> Result<Expr> {
1388 if self.has_unresolved_modules() {
1389 self.resolve_modules_inner(scope, resolvers).await
1390 } else {
1391 Ok(self.clone())
1392 }
1393 }
1394
1395 fn resolve_modules_inner<'a>(
1396 &'a self,
1397 scope: &'a ModPath,
1398 resolvers: &'a [ModuleResolver],
1399 ) -> Pin<Box<dyn Future<Output = Result<Expr>> + Send + Sync + 'a>> {
1400 macro_rules! subexprs {
1401 ($args:expr) => {{
1402 let mut tmp = vec![];
1403 for e in $args.iter() {
1404 tmp.push(e.resolve_modules(scope, resolvers).await?);
1405 }
1406 tmp
1407 }};
1408 }
1409 macro_rules! subtuples {
1410 ($args:expr) => {{
1411 let mut tmp = vec![];
1412 for (k, e) in $args.iter() {
1413 let e = e.resolve_modules(scope, resolvers).await?;
1414 tmp.push((k.clone(), e));
1415 }
1416 tmp
1417 }};
1418 }
1419 macro_rules! only_args {
1420 ($kind:ident, $args:expr) => {
1421 Box::pin(async move {
1422 let args = Arc::from(subexprs!($args));
1423 Ok(Expr {
1424 id: self.id,
1425 pos: self.pos,
1426 kind: ExprKind::$kind { args },
1427 })
1428 })
1429 };
1430 }
1431 macro_rules! bin_op {
1432 ($kind:ident, $lhs:expr, $rhs:expr) => {
1433 Box::pin(async move {
1434 let lhs = Arc::from($lhs.resolve_modules(scope, resolvers).await?);
1435 let rhs = Arc::from($rhs.resolve_modules(scope, resolvers).await?);
1436 Ok(Expr {
1437 id: self.id,
1438 pos: self.pos,
1439 kind: ExprKind::$kind { lhs, rhs },
1440 })
1441 })
1442 };
1443 }
1444 if !self.has_unresolved_modules() {
1445 return Box::pin(async { Ok(self.clone()) });
1446 }
1447 match self.kind.clone() {
1448 ExprKind::Module { value: ModuleKind::Unresolved, export, name } => {
1449 Box::pin(async move {
1450 let full_name = scope.append(&name);
1451 let full_name = full_name.trim_start_matches(Path::SEP);
1452 let mut errors = vec![];
1453 for r in resolvers {
1454 let (filename, s) = match r {
1455 ModuleResolver::Files(base) => {
1456 let full_path = base.join(full_name).with_extension("bs");
1457 match tokio::fs::read_to_string(&full_path).await {
1458 Ok(s) => (
1459 ArcStr::from(full_path.to_string_lossy()),
1460 ArcStr::from(s),
1461 ),
1462 Err(e) => {
1463 errors.push(anyhow::Error::from(e));
1464 continue;
1465 }
1466 }
1467 }
1468 ModuleResolver::Netidx { subscriber, base, timeout } => {
1469 let full_path = base.append(full_name);
1470 let name: ArcStr = full_path.clone().into();
1471 let sub = subscriber
1472 .subscribe_nondurable_one(full_path, *timeout)
1473 .await;
1474 match sub {
1475 Err(e) => {
1476 errors.push(e);
1477 continue;
1478 }
1479 Ok(v) => match v.last() {
1480 Event::Update(Value::String(s)) => (name, s),
1481 Event::Unsubscribed | Event::Update(_) => {
1482 errors.push(anyhow!("expected string"));
1483 continue;
1484 }
1485 },
1486 }
1487 }
1488 };
1489 let value =
1490 ModuleKind::Resolved(parser::parse(Some(filename), s)?);
1491 return Ok(Expr {
1492 id: self.id,
1493 pos: self.pos,
1494 kind: ExprKind::Module { name, export, value },
1495 });
1496 }
1497 bail!("module {name} could not be found {errors:?}")
1498 })
1499 }
1500 ExprKind::Constant(_)
1501 | ExprKind::Use { .. }
1502 | ExprKind::Ref { .. }
1503 | ExprKind::StructRef { .. }
1504 | ExprKind::TupleRef { .. }
1505 | ExprKind::TypeDef { .. } => Box::pin(async move { Ok(self.clone()) }),
1506 ExprKind::Module { value: ModuleKind::Inline(exprs), export, name } => {
1507 Box::pin(async move {
1508 let scope = ModPath(scope.append(&name));
1509 let mut tmp = vec![];
1510 for e in exprs.iter() {
1511 tmp.push(e.resolve_modules(&scope, resolvers).await?);
1512 }
1513 Ok(Expr {
1514 id: self.id,
1515 pos: self.pos,
1516 kind: ExprKind::Module {
1517 value: ModuleKind::Inline(Arc::from(tmp)),
1518 name,
1519 export,
1520 },
1521 })
1522 })
1523 }
1524 ExprKind::Module { value: ModuleKind::Resolved(o), export, name } => {
1525 Box::pin(async move {
1526 let scope = ModPath(scope.append(&name));
1527 let mut tmp = vec![];
1528 for e in o.exprs.iter() {
1529 tmp.push(e.resolve_modules(&scope, resolvers).await?);
1530 }
1531 Ok(Expr {
1532 id: self.id,
1533 pos: self.pos,
1534 kind: ExprKind::Module {
1535 value: ModuleKind::Resolved(Origin {
1536 exprs: Arc::from(tmp),
1537 ..o.clone()
1538 }),
1539 name,
1540 export,
1541 },
1542 })
1543 })
1544 }
1545 ExprKind::Do { exprs } => Box::pin(async move {
1546 let exprs = Arc::from(subexprs!(exprs));
1547 Ok(Expr { id: self.id, pos: self.pos, kind: ExprKind::Do { exprs } })
1548 }),
1549 ExprKind::Bind(b) => Box::pin(async move {
1550 let Bind { doc, pattern, typ, export, value } = &*b;
1551 let value = value.resolve_modules(scope, resolvers).await?;
1552 Ok(Expr {
1553 id: self.id,
1554 pos: self.pos,
1555 kind: ExprKind::Bind(Arc::new(Bind {
1556 doc: doc.clone(),
1557 pattern: pattern.clone(),
1558 typ: typ.clone(),
1559 export: *export,
1560 value,
1561 })),
1562 })
1563 }),
1564 ExprKind::StructWith { source, replace } => Box::pin(async move {
1565 Ok(Expr {
1566 id: self.id,
1567 pos: self.pos,
1568 kind: ExprKind::StructWith {
1569 source: Arc::new(source.resolve_modules(scope, resolvers).await?),
1570 replace: Arc::from(subtuples!(replace)),
1571 },
1572 })
1573 }),
1574 ExprKind::Connect { name, value } => Box::pin(async move {
1575 let value = value.resolve_modules(scope, resolvers).await?;
1576 Ok(Expr {
1577 id: self.id,
1578 pos: self.pos,
1579 kind: ExprKind::Connect { name, value: Arc::new(value) },
1580 })
1581 }),
1582 ExprKind::Lambda(l) => Box::pin(async move {
1583 let Lambda { args, vargs, rtype, constraints, body } = &*l;
1584 let body = match body {
1585 Either::Right(s) => Either::Right(s.clone()),
1586 Either::Left(e) => {
1587 Either::Left(e.resolve_modules(scope, resolvers).await?)
1588 }
1589 };
1590 let l = Lambda {
1591 args: args.clone(),
1592 vargs: vargs.clone(),
1593 rtype: rtype.clone(),
1594 constraints: constraints.clone(),
1595 body,
1596 };
1597 let kind = ExprKind::Lambda(Arc::new(l));
1598 Ok(Expr { id: self.id, pos: self.pos, kind })
1599 }),
1600 ExprKind::TypeCast { expr, typ } => Box::pin(async move {
1601 let expr = expr.resolve_modules(scope, resolvers).await?;
1602 Ok(Expr {
1603 id: self.id,
1604 pos: self.pos,
1605 kind: ExprKind::TypeCast { expr: Arc::new(expr), typ },
1606 })
1607 }),
1608 ExprKind::Apply { args, function } => Box::pin(async move {
1609 Ok(Expr {
1610 id: self.id,
1611 pos: self.pos,
1612 kind: ExprKind::Apply { args: Arc::from(subtuples!(args)), function },
1613 })
1614 }),
1615 ExprKind::Any { args } => only_args!(Any, args),
1616 ExprKind::Array { args } => only_args!(Array, args),
1617 ExprKind::Tuple { args } => only_args!(Tuple, args),
1618 ExprKind::StringInterpolate { args } => only_args!(StringInterpolate, args),
1619 ExprKind::Struct { args } => Box::pin(async move {
1620 let args = Arc::from(subtuples!(args));
1621 Ok(Expr { id: self.id, pos: self.pos, kind: ExprKind::Struct { args } })
1622 }),
1623 ExprKind::ArrayRef { source, i } => Box::pin(async move {
1624 let source = Arc::new(source.resolve_modules(scope, resolvers).await?);
1625 let i = Arc::new(i.resolve_modules(scope, resolvers).await?);
1626 Ok(Expr {
1627 id: self.id,
1628 pos: self.pos,
1629 kind: ExprKind::ArrayRef { source, i },
1630 })
1631 }),
1632 ExprKind::ArraySlice { source, start, end } => Box::pin(async move {
1633 let source = Arc::new(source.resolve_modules(scope, resolvers).await?);
1634 let start = match start {
1635 None => None,
1636 Some(e) => Some(Arc::new(e.resolve_modules(scope, resolvers).await?)),
1637 };
1638 let end = match end {
1639 None => None,
1640 Some(e) => Some(Arc::new(e.resolve_modules(scope, resolvers).await?)),
1641 };
1642 Ok(Expr {
1643 id: self.id,
1644 pos: self.pos,
1645 kind: ExprKind::ArraySlice { source, start, end },
1646 })
1647 }),
1648 ExprKind::Variant { tag, args } => Box::pin(async move {
1649 let args = Arc::from(subexprs!(args));
1650 Ok(Expr {
1651 id: self.id,
1652 pos: self.pos,
1653 kind: ExprKind::Variant { tag, args },
1654 })
1655 }),
1656 ExprKind::Select { arg, arms } => Box::pin(async move {
1657 let arg = Arc::new(arg.resolve_modules(scope, resolvers).await?);
1658 let mut tmp = vec![];
1659 for (p, e) in arms.iter() {
1660 let p = match &p.guard {
1661 None => p.clone(),
1662 Some(e) => {
1663 let e = e.resolve_modules(scope, resolvers).await?;
1664 Pattern {
1665 guard: Some(e),
1666 type_predicate: p.type_predicate.clone(),
1667 structure_predicate: p.structure_predicate.clone(),
1668 }
1669 }
1670 };
1671 let e = e.resolve_modules(scope, resolvers).await?;
1672 tmp.push((p, e));
1673 }
1674 Ok(Expr {
1675 id: self.id,
1676 pos: self.pos,
1677 kind: ExprKind::Select { arg, arms: Arc::from(tmp) },
1678 })
1679 }),
1680 ExprKind::Qop(e) => Box::pin(async move {
1681 let e = e.resolve_modules(scope, resolvers).await?;
1682 Ok(Expr { id: self.id, pos: self.pos, kind: ExprKind::Qop(Arc::new(e)) })
1683 }),
1684 ExprKind::ByRef(e) => Box::pin(async move {
1685 let e = e.resolve_modules(scope, resolvers).await?;
1686 Ok(Expr {
1687 id: self.id,
1688 pos: self.pos,
1689 kind: ExprKind::ByRef(Arc::new(e)),
1690 })
1691 }),
1692 ExprKind::Deref(e) => Box::pin(async move {
1693 let e = e.resolve_modules(scope, resolvers).await?;
1694 Ok(Expr {
1695 id: self.id,
1696 pos: self.pos,
1697 kind: ExprKind::Deref(Arc::new(e)),
1698 })
1699 }),
1700 ExprKind::Not { expr: e } => Box::pin(async move {
1701 let e = e.resolve_modules(scope, resolvers).await?;
1702 Ok(Expr {
1703 id: self.id,
1704 pos: self.pos,
1705 kind: ExprKind::Not { expr: Arc::new(e) },
1706 })
1707 }),
1708 ExprKind::Add { lhs, rhs } => bin_op!(Add, lhs, rhs),
1709 ExprKind::Sub { lhs, rhs } => bin_op!(Sub, lhs, rhs),
1710 ExprKind::Mul { lhs, rhs } => bin_op!(Mul, lhs, rhs),
1711 ExprKind::Div { lhs, rhs } => bin_op!(Div, lhs, rhs),
1712 ExprKind::And { lhs, rhs } => bin_op!(And, lhs, rhs),
1713 ExprKind::Or { lhs, rhs } => bin_op!(Or, lhs, rhs),
1714 ExprKind::Eq { lhs, rhs } => bin_op!(Eq, lhs, rhs),
1715 ExprKind::Ne { lhs, rhs } => bin_op!(Ne, lhs, rhs),
1716 ExprKind::Gt { lhs, rhs } => bin_op!(Gt, lhs, rhs),
1717 ExprKind::Lt { lhs, rhs } => bin_op!(Lt, lhs, rhs),
1718 ExprKind::Gte { lhs, rhs } => bin_op!(Gte, lhs, rhs),
1719 ExprKind::Lte { lhs, rhs } => bin_op!(Lte, lhs, rhs),
1720 }
1721 }
1722}
1723
1724impl fmt::Display for Expr {
1725 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1726 write!(f, "{}", self.kind)
1727 }
1728}