bend/net/
mod.rs

1pub mod hvm_to_net;
2
3use crate::fun::Name;
4pub type BendLab = u16;
5use NodeKind::*;
6
7#[derive(Debug, Clone)]
8/// Net representation used only as an intermediate for converting to hvm-core format
9pub 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  /// Root node
27  Rot,
28  /// Erasure nodes
29  Era,
30  /// Binary combinators
31  Ctr(CtrKind),
32  /// Reference to function definitions
33  Ref { def_name: Name },
34  /// Numbers
35  Num { val: u32 },
36  /// Numeric operations
37  Opr,
38  /// Pattern matching on numbers
39  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
66/// The ROOT port is on the deadlocked root node at address 0.
67pub 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  /// Create a new net, with a deadlocked root node.
75  pub fn new() -> Self {
76    Self::default()
77  }
78
79  /// Allocates a new node with its ports disconnected.
80  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  /// Returns a reference to a node.
88  pub fn node(&self, node: NodeId) -> &Node {
89    &self.nodes[node as usize]
90  }
91
92  /// Returns the value stored at a port, the port on the other side of the given one.
93  pub fn enter_port(&self, port: Port) -> Port {
94    self.node(port.node_id()).port(port.slot())
95  }
96
97  /// Links two ports.
98  pub fn link(&mut self, a: Port, b: Port) {
99    self.set(a, b);
100    self.set(b, a);
101  }
102
103  /// Sets a port to point to another port
104  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)], // p2 points to p0, p1 points to net
113    }
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  /// Returns the node address of a port.
143  pub fn node_id(self) -> NodeId {
144    self.0
145  }
146
147  /// Returns the slot of a port.
148  pub fn slot(self) -> SlotId {
149    self.1
150  }
151}
152
153/* INodes representation: */
154
155/// A flat inet representation where links are represented by shared wire names.
156// TODO: Find a better name
157pub type INodes = Vec<INode>;
158
159#[derive(Debug)]
160pub struct INode {
161  pub kind: NodeKind,
162  pub ports: [String; 3],
163}