tasm_lib/io/
write_to_stdout.rs1use 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}