1use crate::{
2 expr::{
3 parser, read_to_arcstr, ApplyExpr, BindExpr, CouldNotResolve, Expr, ExprId,
4 ExprKind, LambdaExpr, ModPath, ModuleKind, Origin, Pattern, SelectExpr, Sig,
5 SigItem, SigKind, Source, StructExpr, StructWithExpr, StructurePattern,
6 TryCatchExpr, TypeDefExpr,
7 },
8 format_with_flags, PrintFlag,
9};
10use ahash::AHashMap;
11use anyhow::{anyhow, bail, Context, Result};
12use arcstr::ArcStr;
13use combine::stream::position::SourcePosition;
14use compact_str::format_compact;
15use futures::future::try_join_all;
16use indexmap::IndexSet;
17use log::info;
18use netidx::{
19 path::Path,
20 subscriber::{Event, Subscriber},
21 utils::Either,
22};
23use netidx_value::Value;
24use parking_lot::Mutex;
25use poolshark::local::LPooled;
26use std::{hash::Hash, path::PathBuf, pin::Pin, str::FromStr, time::Duration};
27use tokio::{join, task, time::Instant, try_join};
28use triomphe::Arc;
29
30pub type BufferOverrides = Arc<Mutex<AHashMap<PathBuf, ArcStr>>>;
31
32#[derive(Debug, Clone)]
33pub enum ModuleResolver {
34 VFS(AHashMap<Path, ArcStr>),
35 Files { base: PathBuf, overrides: Option<BufferOverrides> },
36 Netidx { subscriber: Subscriber, base: Path, timeout: Option<Duration> },
37}
38
39impl ModuleResolver {
40 pub fn parse_env(
41 subscriber: Subscriber,
42 timeout: Option<Duration>,
43 s: &str,
44 ) -> Result<Vec<Self>> {
45 let mut res = vec![];
46 for l in escaping::split(s, '\\', ',') {
47 let l = l.trim();
48 if let Some(s) = l.strip_prefix("netidx:") {
49 let base = Path::from_str(s);
50 let r = Self::Netidx { subscriber: subscriber.clone(), timeout, base };
51 res.push(r);
52 } else if let Some(s) = l.strip_prefix("file:") {
53 let base = PathBuf::from_str(s)?;
54 let r = Self::Files { base, overrides: None };
55 res.push(r);
56 } else {
57 bail!("expected netidx: or file:")
58 }
59 }
60 Ok(res)
61 }
62}
63
64enum Resolution {
65 Resolved { interface: Option<Origin>, implementation: Origin },
66 TryNextMethod,
67}
68
69fn resolve_from_vfs(
70 scope: &ModPath,
71 parent: &Arc<Origin>,
72 name: &Path,
73 vfs: &AHashMap<Path, ArcStr>,
74) -> Resolution {
75 macro_rules! ori {
76 ($s:expr) => {
77 Origin {
78 parent: Some(parent.clone()),
79 source: Source::Internal(name.clone().into()),
80 text: $s.clone(),
81 }
82 };
83 }
84 let scoped_intf = scope.append(&format_compact!("{name}.gxi"));
85 let scoped_impl = scope.append(&format_compact!("{name}.gx"));
86 let implementation = match vfs.get(&scoped_impl) {
87 Some(s) => ori!(s),
88 None => {
89 let mod_impl = scope.append(&format_compact!("{name}/mod.gx"));
91 match vfs.get(&mod_impl) {
92 Some(s) => ori!(s),
93 None => return Resolution::TryNextMethod,
94 }
95 }
96 };
97 let interface = vfs
98 .get(&scoped_intf)
99 .or_else(|| {
100 let mod_intf = scope.append(&format_compact!("{name}/mod.gxi"));
101 vfs.get(&mod_intf)
102 })
103 .map(|s| ori!(s));
104 Resolution::Resolved { interface, implementation }
105}
106
107async fn resolve_from_files(
108 parent: &Arc<Origin>,
109 name: &Path,
110 base: &PathBuf,
111 overrides: Option<&BufferOverrides>,
112 errors: &mut Vec<anyhow::Error>,
113) -> Resolution {
114 macro_rules! ori {
115 ($s:expr, $path:expr) => {
116 Origin {
117 parent: Some(parent.clone()),
118 source: Source::File($path),
119 text: ArcStr::from($s),
120 }
121 };
122 }
123 async fn read(overrides: Option<&BufferOverrides>, path: &PathBuf) -> Result<ArcStr> {
124 match overrides.and_then(|o| o.lock().get(path).cloned()) {
125 Some(s) => Ok(s),
126 None => read_to_arcstr(path).await,
127 }
128 }
129 let mut impl_path = base.clone();
130 for part in Path::parts(&name) {
131 impl_path.push(part);
132 }
133 impl_path.set_extension("gx");
134 let mut intf_path = impl_path.with_extension("gxi");
135 let implementation = match read(overrides, &impl_path).await {
136 Ok(s) => ori!(s, impl_path),
137 Err(_) => {
138 impl_path.set_extension("");
139 impl_path.push("mod.gx");
140 intf_path.set_extension("");
141 intf_path.push("mod.gxi");
142 match read(overrides, &impl_path).await {
143 Ok(s) => ori!(s, impl_path.clone()),
144 Err(e) => {
145 errors.push(anyhow::Error::from(e));
146 return Resolution::TryNextMethod;
147 }
148 }
149 }
150 };
151 let interface = match read(overrides, &intf_path).await {
152 Ok(s) => Some(ori!(s, intf_path)),
153 Err(_) => None,
154 };
155 Resolution::Resolved { interface, implementation }
156}
157
158async fn resolve_from_netidx(
159 parent: &Arc<Origin>,
160 name: &Path,
161 subscriber: &Subscriber,
162 base: &Path,
163 timeout: &Option<Duration>,
164 errors: &mut Vec<anyhow::Error>,
165) -> Resolution {
166 macro_rules! ori {
167 ($v:expr, $p:expr) => {
168 match $v.last() {
169 Event::Update(Value::String(text)) => Origin {
170 parent: Some(parent.clone()),
171 source: Source::Netidx($p.clone()),
172 text,
173 },
174 Event::Unsubscribed | Event::Update(_) => {
175 errors.push(anyhow!("expected string"));
176 return Resolution::TryNextMethod;
177 }
178 }
179 };
180 }
181 let impl_path = base.append(&format_compact!("{name}.gx"));
182 let intf_path = base.append(&format_compact!("{name}.gxi"));
183 let impl_sub = subscriber.subscribe_nondurable_one(impl_path.clone(), *timeout);
184 let intf_sub = subscriber.subscribe_nondurable_one(intf_path.clone(), *timeout);
185 let (impl_sub, intf_sub) = join!(impl_sub, intf_sub);
186 let implementation = match impl_sub {
187 Ok(v) => ori!(v, impl_path),
188 Err(e) => {
189 errors.push(e);
190 return Resolution::TryNextMethod;
191 }
192 };
193 let interface = match intf_sub {
194 Ok(v) => Some(ori!(v, intf_path)),
195 Err(_) => None,
196 };
197 Resolution::Resolved { interface, implementation }
198}
199
200pub fn add_interface_modules(exprs: Arc<[Expr]>, sig: &Sig) -> Arc<[Expr]> {
203 #[derive(Clone, Copy)]
204 struct Item<'a> {
205 kind: ItemKind<'a>,
206 pos: SourcePosition,
207 ori: Option<&'a Arc<Origin>>,
208 }
209 #[derive(Clone, Copy)]
210 enum ItemKind<'a> {
211 Module(&'a ArcStr),
212 TypeDef(&'a TypeDefExpr),
213 Use(&'a ModPath),
214 }
215 impl<'a> PartialEq for Item<'a> {
216 fn eq(&self, other: &Self) -> bool {
217 match (&self.kind, &other.kind) {
218 (ItemKind::Module(a), ItemKind::Module(b)) => a == b,
219 (ItemKind::TypeDef(a), ItemKind::TypeDef(b)) => a.name == b.name,
220 (ItemKind::Use(a), ItemKind::Use(b)) => a == b,
221 (_, _) => false,
222 }
223 }
224 }
225 impl<'a> Eq for Item<'a> {}
226 impl<'a> Hash for Item<'a> {
227 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
228 match &self.kind {
229 ItemKind::Module(m) => {
230 0u8.hash(state);
231 m.hash(state);
232 }
233 ItemKind::TypeDef(td) => {
234 1u8.hash(state);
235 td.name.hash(state);
236 }
237 ItemKind::Use(m) => {
238 2u8.hash(state);
239 m.hash(state);
240 }
241 }
242 }
243 }
244 impl<'a> Item<'a> {
245 fn synth(self) -> Expr {
246 let kind = match self.kind {
247 ItemKind::Module(name) => ExprKind::Module {
248 name: name.clone(),
249 value: ModuleKind::Unresolved { from_interface: true },
250 },
251 ItemKind::TypeDef(td) => ExprKind::TypeDef(td.clone()),
252 ItemKind::Use(m) => ExprKind::Use { name: m.clone() },
253 };
254 let ori = self.ori.cloned().unwrap_or_else(crate::expr::get_origin);
255 Expr { id: ExprId::new(), ori, pos: self.pos, kind }
256 }
257 }
258 let mut in_sig: LPooled<IndexSet<Item>> = LPooled::take();
259 let mut after_bind: LPooled<AHashMap<&ArcStr, Item>> = LPooled::take();
260 let mut after_td: LPooled<AHashMap<&ArcStr, Item>> = LPooled::take();
261 let mut after_mod: LPooled<AHashMap<&ArcStr, Item>> = LPooled::take();
262 let mut after_use: LPooled<AHashMap<&ModPath, Item>> = LPooled::take();
263 let mut first: Option<Item> = None;
264 let mut last: Option<&SigItem> = None;
265 macro_rules! push {
266 ($kind:ident, $name:expr, $si:expr) => {{
267 let name = Item {
268 kind: ItemKind::$kind($name),
269 pos: $si.pos,
270 ori: $si.ori.as_ref(),
271 };
272 in_sig.insert(name);
273 match last {
274 None => first = Some(name),
275 Some(si) => {
276 match &si.kind {
277 SigKind::Bind(v) => after_bind.insert(&v.name, name),
278 SigKind::Module(m) => after_mod.insert(m, name),
279 SigKind::TypeDef(td) => after_td.insert(&td.name, name),
280 SigKind::Use(n) => after_use.insert(n, name),
281 };
282 }
283 }
284 }};
285 }
286 for si in &*sig.items {
287 match &si.kind {
288 SigKind::Module(name) => push!(Module, name, si),
289 SigKind::TypeDef(td) => push!(TypeDef, td, si),
290 SigKind::Use(m) => push!(Use, m, si),
291 SigKind::Bind(_) => (),
292 }
293 last = Some(si);
294 }
295 for e in &*exprs {
296 if let ExprKind::Module { name, .. } = &e.kind {
297 let probe = Item {
298 kind: ItemKind::Module(name),
299 pos: SourcePosition::default(),
300 ori: None,
301 };
302 in_sig.shift_remove(&probe);
303 }
304 if let ExprKind::TypeDef(td) = &e.kind {
305 let probe = Item {
306 kind: ItemKind::TypeDef(td),
307 pos: SourcePosition::default(),
308 ori: None,
309 };
310 in_sig.shift_remove(&probe);
311 }
312 if let ExprKind::Use { name } = &e.kind {
313 let probe = Item {
314 kind: ItemKind::Use(name),
315 pos: SourcePosition::default(),
316 ori: None,
317 };
318 in_sig.shift_remove(&probe);
319 }
320 }
321 if in_sig.is_empty() {
322 drop(in_sig);
323 drop(after_bind);
324 drop(after_td);
325 drop(after_mod);
326 drop(after_use);
327 return exprs;
328 }
329 let mut res: LPooled<Vec<Expr>> = LPooled::take();
330 if let Some(name) = first.take() {
331 if in_sig.shift_remove(&name) {
332 res.push(name.synth());
333 }
334 }
335 let mut iter = exprs.iter();
336 loop {
337 match res.last().map(|e| &e.kind) {
338 Some(ExprKind::Bind(v)) => match &v.pattern {
339 StructurePattern::Bind(n) => {
340 if let Some(name) = after_bind.remove(n)
341 && in_sig.shift_remove(&name)
342 {
343 res.push(name.synth());
344 continue;
345 }
346 }
347 _ => (),
348 },
349 Some(ExprKind::TypeDef(td)) => {
350 if let Some(name) = after_td.remove(&td.name)
351 && in_sig.shift_remove(&name)
352 {
353 res.push(name.synth());
354 continue;
355 }
356 }
357 Some(ExprKind::Module { name, .. }) => {
358 if let Some(name) = after_mod.remove(name)
359 && in_sig.shift_remove(&name)
360 {
361 res.push(name.synth());
362 continue;
363 }
364 }
365 Some(ExprKind::Use { name }) => {
366 if let Some(name) = after_use.remove(name)
367 && in_sig.shift_remove(&name)
368 {
369 res.push(name.synth());
370 continue;
371 }
372 }
373 _ => (),
374 };
375 match iter.next() {
376 None => break,
377 Some(e) => res.push(e.clone()),
378 }
379 }
380 for name in in_sig.drain(..) {
381 res.push(name.synth());
382 }
383 Arc::from_iter(res.drain(..))
384}
385
386async fn resolve(
387 scope: ModPath,
388 prepend: Option<Arc<ModuleResolver>>,
389 resolvers: Arc<[ModuleResolver]>,
390 id: ExprId,
391 parent: Arc<Origin>,
392 pos: SourcePosition,
393 name: ArcStr,
394 from_interface: bool,
395) -> Result<Expr> {
396 macro_rules! check {
397 ($res:expr) => {
398 match $res {
399 Resolution::TryNextMethod => continue,
400 Resolution::Resolved { interface, implementation } => {
401 (interface, implementation)
402 }
403 }
404 };
405 }
406 let ts = Instant::now();
407 let name = Path::from(name);
408 let mut errors: LPooled<Vec<anyhow::Error>> = LPooled::take();
409 for r in prepend.iter().map(|r| r.as_ref()).chain(resolvers.iter()) {
410 let (interface, implementation) = match r {
411 ModuleResolver::VFS(vfs) => {
412 check!(resolve_from_vfs(&scope, &parent, &name, vfs))
413 }
414 ModuleResolver::Files { base, overrides } => {
415 check!(
416 resolve_from_files(
417 &parent,
418 &name,
419 base,
420 overrides.as_ref(),
421 &mut errors
422 )
423 .await
424 )
425 }
426 ModuleResolver::Netidx { subscriber, base, timeout } => {
427 let r = resolve_from_netidx(
428 &parent,
429 &name,
430 subscriber,
431 base,
432 timeout,
433 &mut errors,
434 )
435 .await;
436 check!(r)
437 }
438 };
439 let exprs = task::spawn_blocking({
440 let ori = implementation.clone();
441 move || parser::parse(ori)
442 });
443 let sig = match &interface {
444 None => None,
445 Some(ori) => {
446 let ori = ori.clone();
447 let sig = task::spawn_blocking(move || parser::parse_sig(ori))
448 .await?
449 .with_context(|| format!("parsing file {interface:?}"))?;
450 Some(sig)
451 }
452 };
453 let exprs =
454 exprs.await?.with_context(|| format!("parsing file {implementation:?}"))?;
455 let exprs = match &sig {
456 Some(sig) => add_interface_modules(exprs, &sig),
457 None => exprs,
458 };
459 let value = ModuleKind::Resolved { exprs, sig, from_interface };
460 let kind = ExprKind::Module { name: name.clone().into(), value };
461 format_with_flags(PrintFlag::NoSource | PrintFlag::NoParents, || {
462 info!(
463 "load and parse {implementation:?} and {interface:?} {:?}",
464 ts.elapsed()
465 )
466 });
467 let _ = implementation; return Ok(Expr { id, ori: parent, pos, kind });
469 }
470 let mut msg = format_compact!("module {name} could not be found");
471 use std::fmt::Write as _;
472 let mut first = true;
473 for e in errors.iter() {
474 let _ = write!(&mut msg, "{}{e}", if first { ": " } else { "; " });
475 first = false;
476 }
477 bail!("{msg}")
478}
479
480impl Expr {
481 pub fn has_unresolved_modules(&self) -> bool {
482 self.fold(false, &mut |acc, e| {
483 acc || match &e.kind {
484 ExprKind::Module { value: ModuleKind::Unresolved { .. }, .. } => true,
485 _ => false,
486 }
487 })
488 }
489
490 pub async fn resolve_modules<'a>(
495 &'a self,
496 resolvers: &'a Arc<[ModuleResolver]>,
497 ) -> Result<Expr> {
498 self.resolve_modules_in_scope(&ModPath::root(), resolvers).await
499 }
500
501 pub async fn resolve_modules_in_scope<'a>(
505 &'a self,
506 scope: &'a ModPath,
507 resolvers: &'a Arc<[ModuleResolver]>,
508 ) -> Result<Expr> {
509 self.resolve_modules_int(scope, &None, resolvers).await
510 }
511
512 async fn resolve_modules_int<'a>(
513 &'a self,
514 scope: &ModPath,
515 prepend: &'a Option<Arc<ModuleResolver>>,
516 resolvers: &'a Arc<[ModuleResolver]>,
517 ) -> Result<Expr> {
518 if self.has_unresolved_modules() {
519 self.resolve_modules_inner(scope, prepend, resolvers).await
520 } else {
521 Ok(self.clone())
522 }
523 }
524
525 fn resolve_modules_inner<'a>(
526 &'a self,
527 scope: &'a ModPath,
528 prepend: &'a Option<Arc<ModuleResolver>>,
529 resolvers: &'a Arc<[ModuleResolver]>,
530 ) -> Pin<Box<dyn Future<Output = Result<Expr>> + Send + Sync + 'a>> {
531 macro_rules! subexprs {
532 ($args:expr) => {{
533 try_join_all($args.iter().map(|e| async {
534 e.resolve_modules_int(scope, prepend, resolvers).await
535 }))
536 .await?
537 }};
538 }
539 macro_rules! subtuples {
540 ($args:expr) => {{
541 try_join_all($args.iter().map(|(k, e)| async {
542 Ok::<_, anyhow::Error>((
543 k.clone(),
544 e.resolve_modules_int(scope, prepend, resolvers).await?,
545 ))
546 }))
547 .await?
548 }};
549 }
550 macro_rules! expr {
551 ($kind:expr) => {
552 Ok(Expr {
553 id: self.id,
554 ori: self.ori.clone(),
555 pos: self.pos,
556 kind: $kind,
557 })
558 };
559 }
560 macro_rules! only_args {
561 ($kind:ident, $args:expr) => {
562 Box::pin(async move {
563 let args = Arc::from(subexprs!($args));
564 expr!(ExprKind::$kind { args })
565 })
566 };
567 }
568 macro_rules! bin_op {
569 ($kind:ident, $lhs:expr, $rhs:expr) => {
570 Box::pin(async move {
571 let (lhs, rhs) = try_join!(
572 $lhs.resolve_modules_int(scope, prepend, resolvers),
573 $rhs.resolve_modules_int(scope, prepend, resolvers)
574 )?;
575 expr!(ExprKind::$kind { lhs: Arc::from(lhs), rhs: Arc::from(rhs) })
576 })
577 };
578 }
579 if !self.has_unresolved_modules() {
580 return Box::pin(async { Ok(self.clone()) });
581 }
582 match self.kind.clone() {
583 ExprKind::Constant(_)
584 | ExprKind::NoOp
585 | ExprKind::Use { .. }
586 | ExprKind::Ref { .. }
587 | ExprKind::StructRef { .. }
588 | ExprKind::TupleRef { .. }
589 | ExprKind::TypeDef { .. } => Box::pin(async move { Ok(self.clone()) }),
590 ExprKind::Module {
591 value: ModuleKind::Unresolved { from_interface },
592 name,
593 } => {
594 let (id, pos, prepend, resolvers) =
595 (self.id, self.pos, prepend.clone(), Arc::clone(resolvers));
596 Box::pin(async move {
597 let e = resolve(
598 scope.clone(),
599 prepend.clone(),
600 resolvers.clone(),
601 id,
602 self.ori.clone(),
603 pos,
604 name.clone(),
605 from_interface,
606 )
607 .await
608 .with_context(|| CouldNotResolve(name.clone()))?;
609 let scope = ModPath(scope.append(&*name));
610 e.resolve_modules_int(&scope, &prepend, &resolvers).await
611 })
612 }
613 ExprKind::Module {
614 value: ModuleKind::Resolved { exprs, sig, from_interface },
615 name,
616 } => Box::pin(async move {
617 let impl_path: Option<&std::path::Path> =
627 exprs.iter().find_map(|e| match &e.ori.source {
628 Source::File(p) => Some(p.as_path()),
629 _ => None,
630 });
631 let prepend = match impl_path {
632 Some(p) => {
633 let parent = match p.parent() {
634 Some(par) => par,
635 None => return Ok(self.clone()),
636 };
637 let dir = match p.file_stem().and_then(|s| s.to_str()) {
638 Some("mod") => parent.to_path_buf(),
639 Some(stem) => parent.join(stem),
640 None => parent.to_path_buf(),
641 };
642 let overrides = resolvers.iter().find_map(|m| match m {
643 ModuleResolver::Files { overrides: Some(o), .. } => {
644 Some(o.clone())
645 }
646 _ => None,
647 });
648 Some(Arc::new(ModuleResolver::Files { base: dir, overrides }))
649 }
650 None => match &self.ori.source {
651 Source::Unspecified | Source::Internal(_) => None,
652 Source::File(p) => p.parent().map(|p| {
653 let overrides = resolvers.iter().find_map(|m| match m {
654 ModuleResolver::Files { overrides: Some(o), .. } => {
655 Some(o.clone())
656 }
657 _ => None,
658 });
659 Arc::new(ModuleResolver::Files { base: p.into(), overrides })
660 }),
661 Source::Netidx(p) => resolvers.iter().find_map(|m| match m {
662 ModuleResolver::Netidx { subscriber, timeout, .. } => {
663 Some(Arc::new(ModuleResolver::Netidx {
664 subscriber: subscriber.clone(),
665 base: p.clone(),
666 timeout: *timeout,
667 }))
668 }
669 ModuleResolver::Files { .. } | ModuleResolver::VFS(_) => None,
670 }),
671 },
672 };
673 let exprs = try_join_all(exprs.iter().map(|e| async {
674 e.resolve_modules_int(&scope, &prepend, resolvers).await
675 }))
676 .await?;
677 expr!(ExprKind::Module {
678 value: ModuleKind::Resolved {
679 exprs: Arc::from(exprs),
680 sig,
681 from_interface
682 },
683 name,
684 })
685 }),
686 ExprKind::Module {
687 name,
688 value: ModuleKind::Dynamic { sandbox, sig, source },
689 } => Box::pin(async move {
690 let source = Arc::new(
691 source.resolve_modules_int(scope, prepend, resolvers).await?,
692 );
693 expr!(ExprKind::Module {
694 name,
695 value: ModuleKind::Dynamic { sandbox, sig, source },
696 })
697 }),
698 ExprKind::ExplicitParens(e) => Box::pin(async move {
699 let e = e.resolve_modules_int(scope, prepend, resolvers).await?;
700 expr!(ExprKind::ExplicitParens(Arc::new(e)))
701 }),
702 ExprKind::Do { exprs } => Box::pin(async move {
703 let exprs = Arc::from(subexprs!(exprs));
704 expr!(ExprKind::Do { exprs })
705 }),
706 ExprKind::Bind(b) => Box::pin(async move {
707 let BindExpr { rec, pattern, typ, value } = &*b;
708 let value = value.resolve_modules_int(scope, prepend, resolvers).await?;
709 expr!(ExprKind::Bind(Arc::new(BindExpr {
710 rec: *rec,
711 pattern: pattern.clone(),
712 typ: typ.clone(),
713 value,
714 })))
715 }),
716 ExprKind::StructWith(StructWithExpr { source, replace }) => {
717 Box::pin(async move {
718 expr!(ExprKind::StructWith(StructWithExpr {
719 source: Arc::new(
720 source.resolve_modules_int(scope, prepend, resolvers).await?,
721 ),
722 replace: Arc::from(subtuples!(replace)),
723 }))
724 })
725 }
726 ExprKind::Connect { name, value, deref } => Box::pin(async move {
727 let value = value.resolve_modules_int(scope, prepend, resolvers).await?;
728 expr!(ExprKind::Connect { name, value: Arc::new(value), deref })
729 }),
730 ExprKind::Lambda(l) => Box::pin(async move {
731 let LambdaExpr { args, vargs, rtype, constraints, throws, body } = &*l;
732 let body = match body {
733 Either::Right(s) => Either::Right(s.clone()),
734 Either::Left(e) => Either::Left(
735 e.resolve_modules_int(scope, prepend, resolvers).await?,
736 ),
737 };
738 let l = LambdaExpr {
739 args: args.clone(),
740 vargs: vargs.clone(),
741 rtype: rtype.clone(),
742 throws: throws.clone(),
743 constraints: constraints.clone(),
744 body,
745 };
746 expr!(ExprKind::Lambda(Arc::new(l)))
747 }),
748 ExprKind::TypeCast { expr, typ } => Box::pin(async move {
749 let expr = expr.resolve_modules_int(scope, prepend, resolvers).await?;
750 expr!(ExprKind::TypeCast { expr: Arc::new(expr), typ })
751 }),
752 ExprKind::Apply(ApplyExpr { args, function }) => Box::pin(async move {
753 expr!(ExprKind::Apply(ApplyExpr {
754 args: Arc::from(subtuples!(args)),
755 function
756 }))
757 }),
758 ExprKind::Any { args } => only_args!(Any, args),
759 ExprKind::Array { args } => only_args!(Array, args),
760 ExprKind::Map { args } => Box::pin(async move {
761 let args = Arc::from(subtuples!(args));
762 expr!(ExprKind::Map { args })
763 }),
764 ExprKind::MapRef { source, key } => Box::pin(async move {
765 let source = Arc::new(
766 source.resolve_modules_int(scope, prepend, resolvers).await?,
767 );
768 let key =
769 Arc::new(key.resolve_modules_inner(scope, prepend, resolvers).await?);
770 expr!(ExprKind::MapRef { source, key })
771 }),
772 ExprKind::Tuple { args } => only_args!(Tuple, args),
773 ExprKind::StringInterpolate { args } => only_args!(StringInterpolate, args),
774 ExprKind::Struct(StructExpr { args }) => Box::pin(async move {
775 let args = Arc::from(subtuples!(args));
776 expr!(ExprKind::Struct(StructExpr { args }))
777 }),
778 ExprKind::ArrayRef { source, i } => Box::pin(async move {
779 let source = Arc::new(
780 source.resolve_modules_int(scope, prepend, resolvers).await?,
781 );
782 let i = Arc::new(i.resolve_modules_int(scope, prepend, resolvers).await?);
783 expr!(ExprKind::ArrayRef { source, i })
784 }),
785 ExprKind::ArraySlice { source, start, end } => Box::pin(async move {
786 let source = Arc::new(
787 source.resolve_modules_int(scope, prepend, resolvers).await?,
788 );
789 let start = match start {
790 None => None,
791 Some(e) => Some(Arc::new(
792 e.resolve_modules_int(scope, prepend, resolvers).await?,
793 )),
794 };
795 let end = match end {
796 None => None,
797 Some(e) => Some(Arc::new(
798 e.resolve_modules_int(scope, prepend, resolvers).await?,
799 )),
800 };
801 expr!(ExprKind::ArraySlice { source, start, end })
802 }),
803 ExprKind::Variant { tag, args } => Box::pin(async move {
804 let args = Arc::from(subexprs!(args));
805 expr!(ExprKind::Variant { tag, args })
806 }),
807 ExprKind::Select(SelectExpr { arg, arms }) => Box::pin(async move {
808 let arg =
809 Arc::new(arg.resolve_modules_int(scope, prepend, resolvers).await?);
810 let arms = try_join_all(arms.iter().map(|(p, e)| async {
811 let p = match &p.guard {
812 None => p.clone(),
813 Some(e) => {
814 let e =
815 e.resolve_modules_int(scope, prepend, resolvers).await?;
816 Pattern {
817 guard: Some(e),
818 type_predicate: p.type_predicate.clone(),
819 structure_predicate: p.structure_predicate.clone(),
820 }
821 }
822 };
823 let e = e.resolve_modules_int(scope, prepend, resolvers).await?;
824 Ok::<_, anyhow::Error>((p, e))
825 }))
826 .await?;
827 expr!(ExprKind::Select(SelectExpr { arg, arms: Arc::from(arms) }))
828 }),
829 ExprKind::Qop(e) => Box::pin(async move {
830 let e = e.resolve_modules_int(scope, prepend, resolvers).await?;
831 expr!(ExprKind::Qop(Arc::new(e)))
832 }),
833 ExprKind::OrNever(e) => Box::pin(async move {
834 let e = e.resolve_modules_int(scope, prepend, resolvers).await?;
835 expr!(ExprKind::OrNever(Arc::new(e)))
836 }),
837 ExprKind::TryCatch(tc) => Box::pin(async move {
838 let exprs = try_join_all(tc.exprs.iter().map(|e| async {
839 e.resolve_modules_int(&scope, &prepend, resolvers).await
840 }))
841 .await?;
842 let handler =
843 tc.handler.resolve_modules_int(scope, prepend, resolvers).await?;
844 expr!(ExprKind::TryCatch(Arc::new(TryCatchExpr {
845 bind: tc.bind.clone(),
846 constraint: tc.constraint.clone(),
847 handler: Arc::new(handler),
848 exprs: Arc::from_iter(exprs),
849 })))
850 }),
851 ExprKind::ByRef(e) => Box::pin(async move {
852 let e = e.resolve_modules_int(scope, prepend, resolvers).await?;
853 expr!(ExprKind::ByRef(Arc::new(e)))
854 }),
855 ExprKind::Deref(e) => Box::pin(async move {
856 let e = e.resolve_modules_int(scope, prepend, resolvers).await?;
857 expr!(ExprKind::Deref(Arc::new(e)))
858 }),
859 ExprKind::Not { expr: e } => Box::pin(async move {
860 let e = e.resolve_modules_int(scope, prepend, resolvers).await?;
861 expr!(ExprKind::Not { expr: Arc::new(e) })
862 }),
863 ExprKind::Add { lhs, rhs } => bin_op!(Add, lhs, rhs),
864 ExprKind::CheckedAdd { lhs, rhs } => bin_op!(CheckedAdd, lhs, rhs),
865 ExprKind::Sub { lhs, rhs } => bin_op!(Sub, lhs, rhs),
866 ExprKind::CheckedSub { lhs, rhs } => bin_op!(CheckedSub, lhs, rhs),
867 ExprKind::Mul { lhs, rhs } => bin_op!(Mul, lhs, rhs),
868 ExprKind::CheckedMul { lhs, rhs } => bin_op!(CheckedMul, lhs, rhs),
869 ExprKind::Div { lhs, rhs } => bin_op!(Div, lhs, rhs),
870 ExprKind::CheckedDiv { lhs, rhs } => bin_op!(CheckedDiv, lhs, rhs),
871 ExprKind::Mod { lhs, rhs } => bin_op!(Mod, lhs, rhs),
872 ExprKind::CheckedMod { lhs, rhs } => bin_op!(CheckedMod, lhs, rhs),
873 ExprKind::And { lhs, rhs } => bin_op!(And, lhs, rhs),
874 ExprKind::Or { lhs, rhs } => bin_op!(Or, lhs, rhs),
875 ExprKind::Eq { lhs, rhs } => bin_op!(Eq, lhs, rhs),
876 ExprKind::Ne { lhs, rhs } => bin_op!(Ne, lhs, rhs),
877 ExprKind::Gt { lhs, rhs } => bin_op!(Gt, lhs, rhs),
878 ExprKind::Lt { lhs, rhs } => bin_op!(Lt, lhs, rhs),
879 ExprKind::Gte { lhs, rhs } => bin_op!(Gte, lhs, rhs),
880 ExprKind::Lte { lhs, rhs } => bin_op!(Lte, lhs, rhs),
881 ExprKind::Sample { lhs, rhs } => bin_op!(Sample, lhs, rhs),
882 }
883 }
884}