scratch_test_interpreter/
state.rs1use 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}