tasm_lib/io/
write_to_stdout.rs

1use std::collections::HashMap;
2
3use rand::prelude::*;
4use triton_vm::prelude::*;
5
6use crate::empty_stack;
7use crate::prelude::*;
8use crate::traits::procedure::Procedure;
9use crate::traits::procedure::ProcedureInitialState;
10
11#[derive(Debug, Clone, Eq, PartialEq, Hash)]
12pub struct WriteToStdout {
13    pub data_type: DataType,
14}
15
16impl BasicSnippet for WriteToStdout {
17    fn inputs(&self) -> Vec<(DataType, String)> {
18        vec![(self.data_type.clone(), "value".to_string())]
19    }
20
21    fn outputs(&self) -> Vec<(DataType, String)> {
22        vec![]
23    }
24
25    fn entrypoint(&self) -> String {
26        format!(
27            "tasmlib_io_write_to_stdout___{}",
28            self.data_type.label_friendly_name()
29        )
30    }
31
32    fn code(&self, _: &mut Library) -> Vec<LabelledInstruction> {
33        triton_asm!(
34            {self.entrypoint()}:
35                {&self.data_type.write_value_to_stdout()}
36                return
37        )
38    }
39}
40
41impl Procedure for WriteToStdout {
42    fn rust_shadow(
43        &self,
44        stack: &mut Vec<BFieldElement>,
45        _: &mut HashMap<BFieldElement, BFieldElement>,
46        _: &NonDeterminism,
47        _: &[BFieldElement],
48        _: &mut Option<Tip5>,
49    ) -> Vec<BFieldElement> {
50        let mut ret = vec![];
51        for _ in 0..self.data_type.stack_size() {
52            let value = stack.pop().unwrap();
53            ret.push(value);
54        }
55        ret
56    }
57
58    fn pseudorandom_initial_state(
59        &self,
60        seed: [u8; 32],
61        _bench_case: Option<crate::snippet_bencher::BenchmarkCase>,
62    ) -> ProcedureInitialState {
63        let mut rng = StdRng::from_seed(seed);
64        let mut stack = empty_stack();
65        let random_value = self.data_type.seeded_random_element(&mut rng);
66        stack.extend(random_value.into_iter().rev());
67
68        ProcedureInitialState {
69            stack,
70            ..Default::default()
71        }
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78    use crate::test_prelude::*;
79
80    #[test]
81    fn rust_shadow() {
82        for data_type in DataType::big_random_generatable_type_collection() {
83            ShadowedProcedure::new(WriteToStdout { data_type }).test();
84        }
85    }
86}
87
88#[cfg(test)]
89mod benches {
90    use super::*;
91    use crate::test_prelude::*;
92
93    #[test]
94    fn benchmark_digest_writing() {
95        ShadowedProcedure::new(WriteToStdout {
96            data_type: DataType::Digest,
97        })
98        .bench();
99    }
100}