Skip to main content

scratch_test_interpreter/
state.rs

1use smodel::{
2    attrs::{List, Variable},
3    blocks::{BlockWrapper, EventBlockKind, ProceduresDefinition, ProceduresPrototype},
4};
5use std::ops::RangeInclusive;
6use svalue::{ARc, SNumber, SValue};
7
8#[derive(Debug, PartialEq, PartialOrd, Clone, Copy)]
9pub enum OutputKind {
10    Think,
11    ThinkFor(f64),
12    Say,
13    SayFor(f64),
14}
15
16pub trait State {
17    type Error;
18
19    fn set_statement_as_context(&mut self, _id: &smodel::Id) -> Result<(), Self::Error> {
20        Ok(())
21    }
22
23    fn ask_question(&mut self, question: SValue) -> Result<(), Self::Error>;
24    fn last_answer(&mut self) -> Result<&str, Self::Error>;
25    fn request_random(
26        &mut self,
27        range: RangeInclusive<SNumber>,
28    ) -> Result<svalue::SNumber, Self::Error> {
29        let (lower, upper) = range.into_inner();
30        match (lower, upper) {
31            (SNumber::Float(_), _) | (_, SNumber::Float(_)) => self
32                .request_float_random(lower.q_as_float(&mut ())..=upper.q_as_float(&mut ()))
33                .map(SNumber::Float),
34            (SNumber::Int(lower), SNumber::Int(upper)) => {
35                self.request_int_random(lower..=upper).map(SNumber::Int)
36            }
37        }
38    }
39
40    fn request_float_random(&mut self, range: RangeInclusive<f64>) -> Result<f64, Self::Error>;
41    fn request_int_random(&mut self, range: RangeInclusive<i64>) -> Result<i64, Self::Error>;
42
43    fn data_set_variable(&mut self, var_id: &Variable, value: SValue) -> Result<(), Self::Error>;
44    fn data_change_variable_by(
45        &mut self,
46        var_id: &Variable,
47        by: SValue,
48    ) -> Result<(), Self::Error> {
49        let new = self.data_read_variable(var_id)?.q_add_numbers(&by, &mut ());
50        self.data_set_variable(var_id, new)
51    }
52    fn data_read_variable(&mut self, var_id: &Variable) -> Result<&SValue, Self::Error>;
53    fn write_output(&mut self, output_kind: OutputKind, message: SValue);
54    fn wait_for_secs(&mut self, _secs: SNumber) -> Result<(), Self::Error> {
55        Ok(())
56    }
57
58    fn data_list_contains_item(
59        &mut self,
60        list_id: &List,
61        item: &SValue,
62    ) -> Result<bool, Self::Error>;
63    fn data_read_textual_list_repr(&mut self, list_id: &List) -> Result<SValue, Self::Error>;
64    fn data_append_to_list(&mut self, list_id: &List, item: SValue) -> Result<(), Self::Error>;
65    fn data_item_of_list(
66        &mut self,
67        list_id: &List,
68        one_based_index: &SValue,
69    ) -> Result<SValue, Self::Error>;
70    fn data_item_num_of_list(&mut self, list_id: &List, item: &SValue) -> Result<i64, Self::Error>;
71    fn data_length_of_list(&mut self, list_id: &List) -> Result<i64, Self::Error>;
72    fn data_delete_of_list(
73        &mut self,
74        list_id: &List,
75        one_based_index: &SValue,
76    ) -> Result<(), Self::Error>;
77    fn data_delete_all_of_list(&mut self, list_id: &List) -> Result<(), Self::Error>;
78    fn data_insert_at_list(
79        &mut self,
80        list_id: &List,
81        one_based_index: &SValue,
82        item: SValue,
83    ) -> Result<(), Self::Error>;
84    fn data_replace_list_at(
85        &mut self,
86        list_id: &List,
87        one_based_index: &SValue,
88        item: SValue,
89    ) -> Result<(), Self::Error>;
90
91    fn notice_event_block_executed(
92        &mut self,
93        _event: &EventBlockKind,
94        _block: &ARc<BlockWrapper>,
95    ) -> Result<(), Self::Error> {
96        Ok(())
97    }
98
99    fn notice_proc_def_block_executed(
100        &mut self,
101        _def: &ProceduresDefinition,
102        _block: &ARc<BlockWrapper>,
103    ) -> Result<(), Self::Error> {
104        Ok(())
105    }
106
107    fn notice_proc_proto_block_executed(
108        &mut self,
109        _proto: &ProceduresPrototype,
110        _block: &ARc<BlockWrapper>,
111    ) -> Result<(), Self::Error> {
112        Ok(())
113    }
114}