1use crate::interpreter::interpreter_stack_value::RibInterpreterStackValue;
2use crate::interpreter::rib_runtime_error::{
3 empty_stack, insufficient_stack_items, type_mismatch_with_value,
4};
5use crate::wit_type::{list, option, record, str, tuple, variant};
6use crate::wit_type::{
7 NameOptionTypePair, NameTypePair, TypeEnum, TypeRecord, TypeResult, WitType,
8};
9use crate::{internal_corrupted_state, GetLiteralValue, RibInterpreterResult, TypeHint};
10use crate::{Value, ValueAndType};
11
12#[derive(Debug)]
13pub struct InterpreterStack {
14 pub stack: Vec<RibInterpreterStackValue>,
15}
16
17impl Default for InterpreterStack {
18 fn default() -> Self {
19 Self::new()
20 }
21}
22
23impl InterpreterStack {
24 pub fn new() -> Self {
25 InterpreterStack { stack: Vec::new() }
26 }
27
28 pub fn create_record(&mut self, fields: Vec<NameTypePair>) {
30 self.push_val(ValueAndType::new(
31 Value::Record(
32 vec![Value::Tuple(vec![]); fields.len()], ),
34 record(fields),
35 ));
36 }
37
38 pub fn pop(&mut self) -> Option<RibInterpreterStackValue> {
39 self.stack.pop()
40 }
41
42 pub fn try_pop(&mut self) -> RibInterpreterResult<RibInterpreterStackValue> {
43 self.pop().ok_or(empty_stack())
44 }
45
46 pub fn pop_sink(&mut self) -> Option<(Vec<ValueAndType>, WitType)> {
47 while let Some(value) = self.pop() {
48 match value {
49 RibInterpreterStackValue::Sink(vec, analysed_type) => {
50 return Some((vec.clone(), analysed_type.clone()));
52 }
53 _ => continue, }
55 }
56
57 None
58 }
59
60 pub fn pop_n(&mut self, n: usize) -> Option<Vec<RibInterpreterStackValue>> {
61 let mut results = Vec::new();
62 for _ in 0..n {
63 results.push(self.stack.pop()?);
64 }
65 Some(results)
66 }
67
68 pub fn try_pop_n(&mut self, n: usize) -> RibInterpreterResult<Vec<RibInterpreterStackValue>> {
69 self.pop_n(n).ok_or(insufficient_stack_items(n))
70 }
71
72 pub fn try_pop_n_val(&mut self, n: usize) -> RibInterpreterResult<Vec<ValueAndType>> {
73 let stack_values = self.try_pop_n(n)?;
74
75 stack_values
76 .iter()
77 .map(|interpreter_result| {
78 interpreter_result
79 .get_val()
80 .ok_or(internal_corrupted_state!(
81 "failed to convert last {} in the stack to ValueAndType",
82 n
83 ))
84 })
85 .collect::<RibInterpreterResult<Vec<ValueAndType>>>()
86 }
87
88 pub fn pop_str(&mut self) -> Option<String> {
89 self.pop_val().and_then(|v| match v {
90 ValueAndType {
91 value: Value::String(s),
92 ..
93 } => Some(s),
94 _ => None,
95 })
96 }
97
98 pub fn pop_val(&mut self) -> Option<ValueAndType> {
99 self.stack.pop().and_then(|v| v.get_val())
100 }
101
102 pub fn try_pop_val(&mut self) -> RibInterpreterResult<ValueAndType> {
103 self.try_pop().and_then(|x| {
104 x.get_val().ok_or(internal_corrupted_state!(
105 "failed to pop ValueAndType from the interpreter stack"
106 ))
107 })
108 }
109
110 pub fn try_pop_record(&mut self) -> RibInterpreterResult<(Vec<Value>, TypeRecord)> {
111 let value = self.try_pop_val()?;
112
113 match value {
114 ValueAndType {
115 value: Value::Record(field_values),
116 typ: WitType::Record(typ),
117 } => Ok((field_values, typ)),
118 _ => Err(type_mismatch_with_value(
119 vec![TypeHint::Record(None)],
120 value.value.clone(),
121 )),
122 }
123 }
124
125 pub fn try_pop_bool(&mut self) -> RibInterpreterResult<bool> {
126 self.try_pop_val().and_then(|val| {
127 val.get_literal()
128 .and_then(|x| x.get_bool())
129 .ok_or(type_mismatch_with_value(
130 vec![TypeHint::Boolean],
131 val.value.clone(),
132 ))
133 })
134 }
135
136 pub fn push(&mut self, interpreter_result: RibInterpreterStackValue) {
137 self.stack.push(interpreter_result);
138 }
139
140 pub fn create_sink(&mut self, analysed_type: WitType) {
141 self.stack
142 .push(RibInterpreterStackValue::Sink(vec![], analysed_type))
143 }
144
145 pub fn push_val(&mut self, element: ValueAndType) {
146 self.stack.push(RibInterpreterStackValue::val(element));
147 }
148
149 pub fn push_to_sink(&mut self, value_and_type: ValueAndType) -> RibInterpreterResult<()> {
150 let (mut list, analysed_type) = self.pop_sink().ok_or(internal_corrupted_state!(
151 "failed to pop a sink from the interpreter stack"
152 ))?;
153
154 list.push(value_and_type);
155 self.push(RibInterpreterStackValue::Sink(list, analysed_type));
156 Ok(())
157 }
158
159 pub fn push_variant(
160 &mut self,
161 variant_name: String,
162 optional_variant_value: Option<Value>,
163 cases: Vec<NameOptionTypePair>,
164 ) -> RibInterpreterResult<()> {
165 let case_idx = cases
166 .iter()
167 .position(|case| case.name == variant_name)
168 .ok_or(internal_corrupted_state!(
169 "failed to find the variant {}",
170 variant_name
171 ))? as u32;
172
173 let case_value = optional_variant_value.map(Box::new);
174 self.push_val(ValueAndType::new(
175 Value::Variant {
176 case_idx,
177 case_value,
178 },
179 variant(cases),
180 ));
181
182 Ok(())
183 }
184
185 pub fn push_enum(&mut self, enum_name: String, cases: Vec<String>) -> RibInterpreterResult<()> {
186 let idx = cases.iter().position(|x| x == &enum_name).ok_or_else(|| {
187 internal_corrupted_state!("failed to find the enum {} in the cases", enum_name)
188 })? as u32;
189 self.push_val(ValueAndType::new(
190 Value::Enum(idx),
191 WitType::Enum(TypeEnum {
192 cases: cases.into_iter().collect(),
193 name: None,
194 owner: None,
195 }),
196 ));
197
198 Ok(())
199 }
200
201 pub fn push_some(&mut self, inner_element: Value, inner_type: &WitType) {
202 self.push_val(ValueAndType {
203 value: Value::Option(Some(Box::new(inner_element))),
204 typ: option(inner_type.clone()),
205 });
206 }
207
208 pub fn push_none(&mut self, analysed_type: Option<WitType>) {
212 self.push_val(ValueAndType {
213 value: Value::Option(None),
214 typ: option(analysed_type.unwrap_or(str())), });
216 }
217
218 pub fn push_ok(
219 &mut self,
220 inner_element: Value,
221 ok_type: Option<&WitType>,
222 err_type: Option<&WitType>,
223 ) {
224 self.push_val(ValueAndType {
225 value: Value::Result(Ok(Some(Box::new(inner_element)))),
226 typ: WitType::Result(TypeResult {
227 ok: ok_type.map(|x| Box::new(x.clone())),
228 err: err_type.map(|x| Box::new(x.clone())),
229 name: None,
230 owner: None,
231 }),
232 });
233 }
234
235 pub fn push_err(
236 &mut self,
237 inner_element: Value,
238 ok_type: Option<&WitType>,
239 err_type: Option<&WitType>,
240 ) {
241 self.push_val(ValueAndType {
242 value: Value::Result(Err(Some(Box::new(inner_element)))),
243 typ: WitType::Result(TypeResult {
244 ok: ok_type.map(|x| Box::new(x.clone())),
245 err: err_type.map(|x| Box::new(x.clone())),
246 name: None,
247 owner: None,
248 }),
249 });
250 }
251
252 pub fn push_list(&mut self, values: Vec<Value>, list_elem_type: &WitType) {
253 self.push_val(ValueAndType {
254 value: Value::List(values),
255 typ: list(list_elem_type.clone()),
256 });
257 }
258
259 pub fn push_tuple(&mut self, values: Vec<ValueAndType>) {
260 self.push_val(ValueAndType {
261 value: Value::Tuple(values.iter().map(|x| x.value.clone()).collect()),
262 typ: tuple(values.into_iter().map(|x| x.typ).collect()),
263 });
264 }
265}