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