sva_engine/instantiate/
resolved.rs1use std::collections::BTreeMap;
4
5use sva_ast::{Arg, Expr};
6
7use crate::instantiate::{Cx, Instances, Node, Thunk};
8
9impl<'g> Instances<'g> {
10 pub(crate) fn display_name(&self, file: &str, binds: &[(String, Thunk<'g>)]) -> String {
11 if binds.is_empty() {
12 return file.to_string();
13 }
14 let args: Vec<String> = binds
15 .iter()
16 .map(|(k, v)| format!("{k}={}", self.render(v.expr, self.cx(v.scope))))
17 .collect();
18 format!("{file}({})", args.join(", "))
19 }
20
21 pub fn render(&self, e: &Expr, cx: Cx) -> String {
23 sva_ast::render_expr(&self.copy(e, cx))
24 }
25
26 pub fn exprs(&self) -> BTreeMap<String, Expr> {
28 self.nodes
29 .keys()
30 .map(|path| {
31 let (e, cx) = self.at(path).expect("a key of the map it indexes");
32 (path.clone(), self.copy(e, cx))
33 })
34 .collect()
35 }
36
37 fn copy(&self, e: &Expr, cx: Cx) -> Expr {
38 if let Some(r) = self.follow(e, cx, |e2, cx2| self.copy(e2, cx2)) {
39 return r;
40 }
41 match self.node(e, cx) {
42 Node::Lit(l) => Expr::Lit(l.clone()),
43 Node::Name(name) => Expr::Var(name.to_string()),
44 Node::Bin(op, l, r) => {
45 Expr::Bin(op, Box::new(self.copy(l, cx)), Box::new(self.copy(r, cx)))
46 }
47 Node::Call { name, args, span } => Expr::Call {
48 name: name.to_string(),
49 args: args
50 .iter()
51 .map(|a| match a {
52 Arg::Pos(x) => Arg::Pos(self.copy(x, cx)),
53 Arg::Named(k, x) => Arg::Named(k.clone(), self.copy(x, cx)),
54 })
55 .collect(),
56 span,
57 },
58 Node::Read {
59 path,
60 arg,
61 address,
62 span,
63 } => Expr::Ref {
64 address,
65 path: path.to_string(),
66 arg: Box::new(self.copy(arg, cx)),
67 binds: Vec::new(),
68 span,
69 },
70 Node::Own { arg, address, span } => Expr::SelfRef {
71 arg: Box::new(self.copy(arg, cx)),
72 address,
73 span,
74 },
75 Node::Signal {
77 name,
78 of,
79 arg,
80 span,
81 } => {
82 let arg = Box::new(self.copy(arg, cx));
83 match self.copy(of.expr, self.signal(of, cx)) {
84 Expr::Ref {
85 path,
86 arg: now,
87 binds,
88 address: sva_ast::Address::Time,
89 ..
90 } if binds.is_empty() && *now == Expr::Var("t".to_string()) => Expr::Ref {
91 path,
92 arg,
93 binds,
94 address: sva_ast::Address::Index,
95 span,
96 },
97 _ => Expr::Indexed {
98 name: name.to_string(),
99 arg,
100 span,
101 },
102 }
103 }
104 }
105 }
106}