logic_circus/
constructors.rs

1use crate::{
2    gate::GateKind, implemented::RustImpls, util::ContainerSizeGames, Component, ComponentBuilder,
3    Gate, GateLike, Sequal,
4};
5
6impl<Rust> Default for ComponentBuilder<Rust> {
7    fn default() -> Self {
8        Self {
9            gates: Vec::default(),
10            sequals: Vec::default(),
11            outputs: usize::default(),
12        }
13    }
14}
15
16impl<Rust> ComponentBuilder<Rust> {
17    /// Add a gate to the component
18    ///
19    /// `gate` is the gate you want to add.
20    ///
21    /// `sequals` dictate where the outputs of the gate go, in other words the
22    /// wiring, these `sequal`s are in order, so the `gate`'s first `output`
23    /// will go to the first `sequal` and so on.
24    ///
25    /// a sequal can either be another gate or one of the components outputs.
26    ///
27    /// if you want to send an output to several places it must be done
28    /// indirectly, you should take a look at [`Gate::dup`].
29    pub fn gate(mut self, gate: Gate<Rust>, sequals: Vec<Sequal>) -> Self {
30        self.push_sequals(sequals);
31        self.gates.push(gate);
32        self
33    }
34
35    fn push_sequals(&mut self, sequals: Vec<Sequal>) -> &mut Self {
36        self.outputs += sequals
37            .iter()
38            .filter(|x| matches!(x, Sequal::End { .. }))
39            .count();
40        self.sequals.push(sequals);
41        self
42    }
43
44    /// Tell the component where it's inputs should go
45    ///
46    /// after you've added many gates to your component you still need to tell
47    /// the component where to start, once you do that your component is ready
48    /// and it will be returned from the function
49    pub fn inputs(mut self, inputs: Vec<Sequal>) -> Component<Rust> {
50        self.push_sequals(inputs);
51        Component::from_raw_parts(self.gates, self.sequals, self.outputs)
52    }
53}
54
55impl<Rust> Component<Rust> {
56    /// Aquire a [`ComponentBuilder`]
57    pub fn builder() -> ComponentBuilder<Rust> {
58        ComponentBuilder::default()
59    }
60
61    /// Create a component out of a single gate
62    ///
63    /// this is mostly useless since the gate itself can probably do whatever
64    /// you need and exists mostly for tests
65    pub fn single_gate(gate: Gate<Rust>, num_of_outputs: usize) -> Self {
66        let inputs = gate.inputs.len();
67        Self::builder()
68            .gate(gate, (0..num_of_outputs).map(Sequal::end).collect())
69            .inputs((0..inputs).map(|entry| Sequal::gate(0, entry)).collect())
70    }
71
72    /// Create a component from it's raw parts
73    ///
74    /// in `sequals` each `Vec<Sequal>` corresponds to a single gates sequals
75    /// (in the same index) and the last corresponds to the components inputs
76    /// `outputs` is the amount of outputs your component has
77    pub fn from_raw_parts(
78        gates: Vec<Gate<Rust>>,
79        sequals: Vec<Vec<Sequal>>,
80        outputs: usize,
81    ) -> Self {
82        debug_assert_eq!(
83            gates.len(),
84            sequals.len() - 1,
85            "read the documentation of this function"
86        );
87
88        Self {
89            gates,
90            sequals,
91            outputs,
92        }
93    }
94}
95
96impl Sequal {
97    /// Another gate
98    pub fn gate(index: usize, entry: usize) -> Self {
99        Self::Gate { index, entry }
100    }
101
102    /// An output of the component
103    pub fn end(output: usize) -> Self {
104        Self::End { output }
105    }
106}
107
108impl<Rust> Gate<Rust>
109where
110    Rust: GateLike,
111{
112    fn new(kind: GateKind<Rust>) -> Self {
113        Self {
114            inputs: Vec::zeroed(kind.num_of_inputs()),
115            inputs_filled: 0,
116            kind,
117        }
118    }
119
120    /// Create a gate from a custom component
121    pub fn component(component: Component<Rust>) -> Self {
122        Self::new(GateKind::Custom(component))
123    }
124    /// Create a gate from logic you wrote in rust
125    pub fn rust(gate: Rust) -> Self {
126        Self::new(GateKind::Rust(RustImpls::User(gate)))
127    }
128    /// A duplicator, this is akin to a wire splitting
129    pub fn dup(amount: usize) -> Self {
130        Self::new(GateKind::Rust(RustImpls::Dup(amount)))
131    }
132    /// This holds a single bit of memory in between CPU ticks
133    pub fn mem() -> Self {
134        Self::new(GateKind::Rust(RustImpls::Mem(bool::default())))
135    }
136    /// A Not gate
137    pub fn not() -> Self {
138        Self::new(GateKind::Rust(RustImpls::Not))
139    }
140    /// A Nand gate
141    pub fn nand() -> Self {
142        Self::new(GateKind::Rust(RustImpls::Nand))
143    }
144    /// A bitwise And gate
145    pub fn and() -> Self {
146        Self::new(GateKind::Rust(RustImpls::And))
147    }
148    /// A bitwise Or gate
149    pub fn or() -> Self {
150        Self::new(GateKind::Rust(RustImpls::Or))
151    }
152    /// A Nor gate
153    pub fn nor() -> Self {
154        Self::new(GateKind::Rust(RustImpls::Nor))
155    }
156    /// An Xor gate
157    pub fn xor() -> Self {
158        Self::new(GateKind::Rust(RustImpls::Xor))
159    }
160}