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