1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::{Circuit, CircuitMember, Identifier, Scope, Type, Variable};
use indexmap::IndexMap;
use std::cell::RefCell;
#[derive(Clone, Copy)]
pub struct Input<'a> {
pub registers: &'a Circuit<'a>,
pub state: &'a Circuit<'a>,
pub state_leaf: &'a Circuit<'a>,
pub record: &'a Circuit<'a>,
pub container_circuit: &'a Circuit<'a>,
pub container: &'a Variable<'a>,
}
pub const CONTAINER_PSEUDO_CIRCUIT: &str = "$InputContainer";
pub const REGISTERS_PSEUDO_CIRCUIT: &str = "$InputRegister";
pub const RECORD_PSEUDO_CIRCUIT: &str = "$InputRecord";
pub const STATE_PSEUDO_CIRCUIT: &str = "$InputState";
pub const STATE_LEAF_PSEUDO_CIRCUIT: &str = "$InputStateLeaf";
impl<'a> Input<'a> {
fn make_header(scope: &'a Scope<'a>, name: &str) -> &'a Circuit<'a> {
scope.context.alloc_circuit(Circuit {
id: scope.context.get_id(),
name: RefCell::new(Identifier::new(name.into())),
members: RefCell::new(IndexMap::new()),
core_mapping: RefCell::new(None),
scope,
span: Default::default(),
})
}
pub fn new(scope: &'a Scope<'a>) -> Self {
let input_scope = scope.make_subscope();
let registers = Self::make_header(input_scope, REGISTERS_PSEUDO_CIRCUIT);
let record = Self::make_header(input_scope, RECORD_PSEUDO_CIRCUIT);
let state = Self::make_header(input_scope, STATE_PSEUDO_CIRCUIT);
let state_leaf = Self::make_header(input_scope, STATE_LEAF_PSEUDO_CIRCUIT);
let mut container_members = IndexMap::new();
container_members.insert(
"registers".to_string(),
CircuitMember::Variable(Type::Circuit(registers)),
);
container_members.insert("record".to_string(), CircuitMember::Variable(Type::Circuit(record)));
container_members.insert("state".to_string(), CircuitMember::Variable(Type::Circuit(state)));
container_members.insert(
"state_leaf".to_string(),
CircuitMember::Variable(Type::Circuit(state_leaf)),
);
let container_circuit = input_scope.context.alloc_circuit(Circuit {
id: scope.context.get_id(),
name: RefCell::new(Identifier::new(CONTAINER_PSEUDO_CIRCUIT.into())),
members: RefCell::new(container_members),
core_mapping: RefCell::new(None),
scope: input_scope,
span: Default::default(),
});
Input {
registers,
record,
state,
state_leaf,
container_circuit,
container: input_scope.context.alloc_variable(RefCell::new(crate::InnerVariable {
id: scope.context.get_id(),
name: Identifier::new("input".into()),
type_: Type::Circuit(container_circuit),
mutable: false,
const_: false,
declaration: crate::VariableDeclaration::Input,
references: vec![],
assignments: vec![],
})),
}
}
}
impl<'a> Circuit<'a> {
pub fn is_input_pseudo_circuit(&self) -> bool {
matches!(
&*self.name.borrow().name,
REGISTERS_PSEUDO_CIRCUIT | RECORD_PSEUDO_CIRCUIT | STATE_PSEUDO_CIRCUIT | STATE_LEAF_PSEUDO_CIRCUIT
)
}
}