1pub mod hvm_to_net;
2
3use crate::fun::Name;
4pub type BendLab = u16;
5use NodeKind::*;
6
7#[derive(Debug, Clone)]
8pub struct INet {
10 nodes: Vec<Node>,
11}
12
13#[derive(Debug, Clone)]
14pub struct Node {
15 pub main: Port,
16 pub aux1: Port,
17 pub aux2: Port,
18 pub kind: NodeKind,
19}
20
21#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Default)]
22pub struct Port(pub NodeId, pub SlotId);
23
24#[derive(Debug, Clone, PartialEq, Eq)]
25pub enum NodeKind {
26 Rot,
28 Era,
30 Ctr(CtrKind),
32 Ref { def_name: Name },
34 Num { val: u32 },
36 Opr,
38 Swi,
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43pub enum CtrKind {
44 Con(Option<BendLab>),
45 Tup(Option<BendLab>),
46 Dup(BendLab),
47}
48
49impl CtrKind {
50 pub fn to_lab(self) -> BendLab {
51 #[allow(clippy::identity_op)]
52 match self {
53 CtrKind::Con(None) => 0,
54 CtrKind::Con(Some(_)) => todo!("Tagged lambdas/applications not implemented for hvm32"),
55 CtrKind::Tup(None) => 0,
56 CtrKind::Tup(Some(_)) => todo!("Tagged tuples not implemented for hvm32"),
57 CtrKind::Dup(0) => 1,
58 CtrKind::Dup(_) => todo!("Tagged dups/sups not implemented for hvm32"),
59 }
60 }
61}
62
63pub type NodeId = u64;
64pub type SlotId = u64;
65
66pub const ROOT: Port = Port(0, 1);
68pub const TAG_WIDTH: u32 = 4;
69pub const TAG: u32 = u64::BITS - TAG_WIDTH;
70pub const LABEL_MASK: u64 = (1 << TAG) - 1;
71pub const TAG_MASK: u64 = !LABEL_MASK;
72
73impl INet {
74 pub fn new() -> Self {
76 Self::default()
77 }
78
79 pub fn new_node(&mut self, kind: NodeKind) -> NodeId {
81 let idx = self.nodes.len() as NodeId;
82 let node = Node::new(Port(idx, 0), Port(idx, 1), Port(idx, 2), kind);
83 self.nodes.extend([node]);
84 idx
85 }
86
87 pub fn node(&self, node: NodeId) -> &Node {
89 &self.nodes[node as usize]
90 }
91
92 pub fn enter_port(&self, port: Port) -> Port {
94 self.node(port.node_id()).port(port.slot())
95 }
96
97 pub fn link(&mut self, a: Port, b: Port) {
99 self.set(a, b);
100 self.set(b, a);
101 }
102
103 pub fn set(&mut self, src: Port, dst: Port) {
105 *self.nodes[src.node_id() as usize].port_mut(src.slot()) = dst;
106 }
107}
108
109impl Default for INet {
110 fn default() -> Self {
111 INet {
112 nodes: vec![Node::new(Port(0, 2), Port(0, 1), Port(0, 0), Rot)], }
114 }
115}
116
117impl Node {
118 pub fn new(main: Port, aux1: Port, aux2: Port, kind: NodeKind) -> Self {
119 Node { main, aux1, aux2, kind }
120 }
121
122 pub fn port(&self, slot: SlotId) -> Port {
123 match slot {
124 0 => self.main,
125 1 => self.aux1,
126 2 => self.aux2,
127 _ => unreachable!(),
128 }
129 }
130
131 pub fn port_mut(&mut self, slot: SlotId) -> &mut Port {
132 match slot {
133 0 => &mut self.main,
134 1 => &mut self.aux1,
135 2 => &mut self.aux2,
136 _ => unreachable!(),
137 }
138 }
139}
140
141impl Port {
142 pub fn node_id(self) -> NodeId {
144 self.0
145 }
146
147 pub fn slot(self) -> SlotId {
149 self.1
150 }
151}
152
153pub type INodes = Vec<INode>;
158
159#[derive(Debug)]
160pub struct INode {
161 pub kind: NodeKind,
162 pub ports: [String; 3],
163}