Skip to main content

semantic_analyzer/types/
block_state.rs

1//! # Block State types
2//! Block state Semantic types.
3
4use super::semantic::{ExtendedSemanticContext, SemanticContextInstruction, SemanticStack};
5use super::{Constant, Function, FunctionParameter, InnerValueName, LabelName, Value, ValueName};
6use crate::types::condition::{Condition, LogicCondition};
7use crate::types::expression::{ExpressionOperations, ExpressionResult};
8use crate::types::semantic::SemanticContext;
9#[cfg(feature = "codec")]
10use serde::{Deserialize, Serialize};
11use std::cell::RefCell;
12use std::collections::{HashMap, HashSet};
13use std::rc::Rc;
14
15/// # Block state
16/// - `values` - contains unique values map for current state but not unique
17///   for parent states. The map contains key-value: `value_name` (unique
18///   only for current state); and `Value` itself - value parameters.   
19/// - `inner_values_name` - is entity that represent inner value name - it
20///   can be different from `Value` name because it should be unique for all
21///   parent states. For example, of 3 values with name `x`, inner value
22///   name will be: [`x`, `x.0`, `x.1`]. It mean, inner value name can
23///   contain `value counter` as end of the name.
24/// - `labels` - labels set, for conditional operation. Unique for current
25///   and all paren states.
26/// - `last_register_number` - represent register counter for current and
27///   all parent states for `Codegen`. Register represented as `u64` and
28///   should be linearly incremented.
29/// - `manual_return` - flag indicated, that return was invoked from
30/// other state, for example: if-flow, loop-flow
31/// - `parent` - represent parent states.  
32#[derive(Debug)]
33#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
34pub struct BlockState<I: SemanticContextInstruction> {
35    /// State values
36    pub values: HashMap<ValueName, Value>,
37    /// Used to keep all names in the block state (and parent) as unique
38    pub inner_values_name: HashSet<InnerValueName>,
39    /// State labels for conditional operations
40    pub labels: HashSet<LabelName>,
41    /// Last register for unique register representation
42    pub last_register_number: u64,
43    /// Manual return from other states
44    pub manual_return: bool,
45    /// Parent state
46    #[cfg_attr(
47        feature = "codec",
48        serde(
49            serialize_with = "rc_serializer::serialize_option",
50            deserialize_with = "rc_serializer::deserialize_option"
51        )
52    )]
53    pub parent: Option<Rc<RefCell<Self>>>,
54    /// children states
55    #[cfg_attr(
56        feature = "codec",
57        serde(
58            serialize_with = "rc_serializer::serialize_vec",
59            deserialize_with = "rc_serializer::deserialize_vec"
60        )
61    )]
62    pub children: Vec<Rc<RefCell<Self>>>,
63    /// Semantic stack context for Block state
64    context: SemanticStack<I>,
65}
66
67impl<I: SemanticContextInstruction> BlockState<I> {
68    /// Init block state with optional `parent` state
69    #[must_use]
70    pub fn new(parent: Option<Rc<RefCell<Self>>>) -> Self {
71        // Get values from parent
72        let (last_register_number, inner_values_name, labels, manual_return) =
73            parent.clone().map_or_else(
74                || (0, HashSet::new(), HashSet::new(), false),
75                |p| {
76                    let parent = p.borrow();
77                    (
78                        parent.last_register_number,
79                        parent.inner_values_name.clone(),
80                        parent.labels.clone(),
81                        parent.manual_return,
82                    )
83                },
84            );
85        Self {
86            values: HashMap::new(),
87            children: vec![],
88            inner_values_name,
89            labels,
90            last_register_number,
91            manual_return,
92            parent,
93            context: SemanticStack::new(),
94        }
95    }
96
97    #[must_use]
98    pub fn get_context(&self) -> SemanticStack<I> {
99        self.context.clone()
100    }
101
102    /// Set `last_register_number` for current and parent states
103    fn set_register(&mut self, last_register_number: u64) {
104        self.last_register_number = last_register_number;
105        // Set `last_register_number` for parents
106        if let Some(parent) = &self.parent {
107            parent.borrow_mut().set_register(last_register_number);
108        }
109    }
110
111    /// Increment register
112    pub fn inc_register(&mut self) {
113        self.set_register(self.last_register_number + 1);
114    }
115
116    /// Get child Block state
117    pub fn set_child(&mut self, child: Rc<RefCell<Self>>) {
118        self.children.push(child);
119    }
120
121    /// Set value inner name to current state and parent states
122    pub fn set_inner_value_name(&mut self, name: &InnerValueName) {
123        self.inner_values_name.insert(name.clone());
124        if let Some(parent) = &self.parent {
125            parent.borrow_mut().set_inner_value_name(name);
126        }
127    }
128
129    /// Check is `inner_value_name` exist in current and parent states
130    #[must_use]
131    pub fn is_inner_value_name_exist(&self, name: &InnerValueName) -> bool {
132        if self.inner_values_name.contains(name) {
133            return true;
134        } else if let Some(parent) = &self.parent {
135            return parent.borrow().is_inner_value_name_exist(name);
136        }
137        false
138    }
139
140    /// Get `Value` by value name from current state.
141    /// If not found on current state - recursively find in parent states.
142    #[must_use]
143    pub fn get_value_name(&self, name: &ValueName) -> Option<Value> {
144        if let Some(val) = self.values.get(name) {
145            return Some(val.clone());
146        } else if let Some(parent) = &self.parent {
147            return parent.borrow().get_value_name(name);
148        }
149        None
150    }
151
152    /// Check is label name exist in current and parent states
153    #[must_use]
154    pub fn is_label_name_exist(&self, name: &LabelName) -> bool {
155        if self.labels.contains(name) {
156            return true;
157        } else if let Some(parent) = &self.parent {
158            return parent.borrow().is_label_name_exist(name);
159        }
160        false
161    }
162
163    /// Set label name to current and all parent states
164    pub fn set_label_name(&mut self, name: &LabelName) {
165        self.labels.insert(name.clone());
166        if let Some(parent) = &self.parent {
167            parent.borrow_mut().set_label_name(name);
168        }
169    }
170
171    /// Set attribute counter - increment, if counter exist.
172    #[must_use]
173    pub fn set_attr_counter(val: &str) -> String {
174        let val_attr: Vec<&str> = val.split('.').collect();
175        if val_attr.len() == 2 {
176            let i: u64 = val_attr[1].parse().unwrap_or_default();
177            format!("{}.{:?}", val_attr[0], i + 1)
178        } else {
179            format!("{}.0", val_attr[0])
180        }
181    }
182
183    /// Get and set next label for condition operations
184    /// - If label doesn't exist in State - just insert to State and
185    ///   self return
186    /// - if label exists, get label counter
187    pub fn get_and_set_next_label(&mut self, label: &LabelName) -> LabelName {
188        // Check is label exists. If doesn't set it to State and return self
189        if !self.is_label_name_exist(label) {
190            self.set_label_name(label);
191            return label.clone();
192        }
193        // If label exists, split and get number of label counter
194        let name: LabelName = Self::set_attr_counter(&label.to_string()).into();
195        if self.is_label_name_exist(&name) {
196            self.get_and_set_next_label(&name)
197        } else {
198            self.set_label_name(&name);
199            name
200        }
201    }
202
203    /// Get next `inner_value_name` by name counter for current and
204    /// parent states. The `inner_value_name` should always be unique.
205    #[must_use]
206    pub fn get_next_inner_name(&self, val: &InnerValueName) -> InnerValueName {
207        // Increment inner value name counter for shadowed variable
208        let name: InnerValueName = Self::set_attr_counter(&val.to_string()).into();
209        if self.is_inner_value_name_exist(&name) {
210            self.get_next_inner_name(&name)
211        } else {
212            name
213        }
214    }
215
216    /// Set return status flag for current and parent states
217    pub fn set_return(&mut self) {
218        self.manual_return = true;
219        if let Some(parent) = &self.parent {
220            parent.borrow_mut().set_return();
221        }
222    }
223}
224
225impl<I: SemanticContextInstruction> SemanticContext for BlockState<I> {
226    fn expression_value(&mut self, expression: Value, register_number: u64) {
227        self.context
228            .expression_value(expression.clone(), register_number);
229        if let Some(parent) = &self.parent {
230            parent
231                .borrow_mut()
232                .expression_value(expression, register_number);
233        }
234    }
235
236    fn expression_const(&mut self, expression: Constant, register_number: u64) {
237        self.context
238            .expression_const(expression.clone(), register_number);
239        if let Some(parent) = &self.parent {
240            parent
241                .borrow_mut()
242                .expression_const(expression, register_number);
243        }
244    }
245
246    fn expression_struct_value(&mut self, expression: Value, index: u32, register_number: u64) {
247        self.context
248            .expression_struct_value(expression.clone(), index, register_number);
249        if let Some(parent) = &self.parent {
250            parent
251                .borrow_mut()
252                .expression_struct_value(expression, index, register_number);
253        }
254    }
255
256    fn expression_operation(
257        &mut self,
258        operation: ExpressionOperations,
259        left_value: ExpressionResult,
260        right_value: ExpressionResult,
261        register_number: u64,
262    ) {
263        self.context.expression_operation(
264            operation.clone(),
265            left_value.clone(),
266            right_value.clone(),
267            register_number,
268        );
269        if let Some(parent) = &self.parent {
270            parent.borrow_mut().expression_operation(
271                operation,
272                left_value,
273                right_value,
274                register_number,
275            );
276        }
277    }
278
279    fn call(&mut self, call: Function, params: Vec<ExpressionResult>, register_number: u64) {
280        self.context
281            .call(call.clone(), params.clone(), register_number);
282        if let Some(parent) = &self.parent {
283            parent.borrow_mut().call(call, params, register_number);
284        }
285    }
286
287    fn let_binding(&mut self, let_decl: Value, expr_result: ExpressionResult) {
288        self.context
289            .let_binding(let_decl.clone(), expr_result.clone());
290        if let Some(parent) = &self.parent {
291            parent.borrow_mut().let_binding(let_decl, expr_result);
292        }
293    }
294
295    fn binding(&mut self, val: Value, expr_result: ExpressionResult) {
296        self.context.binding(val.clone(), expr_result.clone());
297        if let Some(parent) = &self.parent {
298            parent.borrow_mut().binding(val, expr_result);
299        }
300    }
301
302    fn expression_function_return(&mut self, expr_result: ExpressionResult) {
303        self.context.expression_function_return(expr_result.clone());
304        if let Some(parent) = &self.parent {
305            parent.borrow_mut().expression_function_return(expr_result);
306        }
307    }
308
309    fn expression_function_return_with_label(&mut self, expr_result: ExpressionResult) {
310        self.context
311            .expression_function_return_with_label(expr_result.clone());
312        if let Some(parent) = &self.parent {
313            parent
314                .borrow_mut()
315                .expression_function_return_with_label(expr_result);
316        }
317    }
318
319    fn set_label(&mut self, label: LabelName) {
320        self.context.set_label(label.clone());
321        if let Some(parent) = &self.parent {
322            parent.borrow_mut().set_label(label);
323        }
324    }
325
326    fn jump_to(&mut self, label: LabelName) {
327        self.context.jump_to(label.clone());
328        if let Some(parent) = &self.parent {
329            parent.borrow_mut().jump_to(label);
330        }
331    }
332
333    fn if_condition_expression(
334        &mut self,
335        expr_result: ExpressionResult,
336        label_if_begin: LabelName,
337        label_if_end: LabelName,
338    ) {
339        self.context.if_condition_expression(
340            expr_result.clone(),
341            label_if_begin.clone(),
342            label_if_end.clone(),
343        );
344        if let Some(parent) = &self.parent {
345            parent
346                .borrow_mut()
347                .if_condition_expression(expr_result, label_if_begin, label_if_end);
348        }
349    }
350
351    fn condition_expression(
352        &mut self,
353        left_result: ExpressionResult,
354        right_result: ExpressionResult,
355        condition: Condition,
356        register_number: u64,
357    ) {
358        self.context.condition_expression(
359            left_result.clone(),
360            right_result.clone(),
361            condition.clone(),
362            register_number,
363        );
364        if let Some(parent) = &self.parent {
365            parent.borrow_mut().condition_expression(
366                left_result,
367                right_result,
368                condition,
369                register_number,
370            );
371        }
372    }
373
374    fn jump_function_return(&mut self, expr_result: ExpressionResult) {
375        self.context.jump_function_return(expr_result.clone());
376        if let Some(parent) = &self.parent {
377            parent.borrow_mut().jump_function_return(expr_result);
378        }
379    }
380
381    fn logic_condition(
382        &mut self,
383        logic_condition: LogicCondition,
384        left_register_result: u64,
385        right_register_result: u64,
386        register_number: u64,
387    ) {
388        self.context.logic_condition(
389            logic_condition.clone(),
390            left_register_result,
391            right_register_result,
392            register_number,
393        );
394        if let Some(parent) = &self.parent {
395            parent.borrow_mut().logic_condition(
396                logic_condition,
397                left_register_result,
398                right_register_result,
399                register_number,
400            );
401        }
402    }
403
404    fn if_condition_logic(
405        &mut self,
406        label_if_begin: LabelName,
407        label_if_end: LabelName,
408        result_register: u64,
409    ) {
410        self.context.if_condition_logic(
411            label_if_begin.clone(),
412            label_if_end.clone(),
413            result_register,
414        );
415        if let Some(parent) = &self.parent {
416            parent
417                .borrow_mut()
418                .if_condition_logic(label_if_begin, label_if_end, result_register);
419        }
420    }
421
422    fn function_arg(&mut self, value: Value, func_arg: FunctionParameter) {
423        self.context.function_arg(value.clone(), func_arg.clone());
424        if let Some(parent) = &self.parent {
425            parent.borrow_mut().function_arg(value, func_arg);
426        }
427    }
428}
429
430impl<I: SemanticContextInstruction> ExtendedSemanticContext<I> for BlockState<I> {
431    fn extended_expression(&mut self, expr: &I) {
432        self.context.extended_expression(expr);
433        if let Some(parent) = &self.parent {
434            parent.borrow_mut().extended_expression(expr);
435        }
436    }
437}
438
439/// Custom Serde serializers for `Rc<RefCell<...>>`
440#[cfg(feature = "codec")]
441pub mod rc_serializer {
442    use super::{Rc, RefCell};
443    use serde::{Deserialize, Deserializer, Serialize, Serializer, ser::SerializeSeq};
444
445    /// Serializer for `Rc<RefCell<T>`.
446    #[allow(clippy::missing_errors_doc)]
447    pub fn serialize<S, T>(rc: &Rc<RefCell<T>>, serializer: S) -> Result<S::Ok, S::Error>
448    where
449        S: Serializer,
450        T: Serialize,
451    {
452        T::serialize(&*rc.borrow(), serializer)
453    }
454
455    /// Serializer for `Option<Rc<RefCell<T>>`.
456    #[allow(clippy::missing_errors_doc)]
457    pub fn serialize_option<S, T>(
458        val: &Option<Rc<RefCell<T>>>,
459        serializer: S,
460    ) -> Result<S::Ok, S::Error>
461    where
462        S: Serializer,
463        T: Serialize,
464    {
465        match val {
466            Some(rc) => serialize(rc, serializer),
467            None => serializer.serialize_none(),
468        }
469    }
470
471    /// Serializer for `Vec<Rc<RefCell<T>>`.
472    #[allow(clippy::missing_errors_doc)]
473    pub fn serialize_vec<S, T>(val: &Vec<Rc<RefCell<T>>>, serializer: S) -> Result<S::Ok, S::Error>
474    where
475        S: Serializer,
476        T: Serialize,
477    {
478        let mut seq = serializer.serialize_seq(Some(val.len()))?;
479        for item in val {
480            seq.serialize_element(&*item.borrow())?;
481        }
482        seq.end()
483    }
484
485    /// Deserializer for `Rc<RefCell<T>`
486    #[allow(clippy::missing_errors_doc)]
487    pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Rc<RefCell<T>>, D::Error>
488    where
489        D: Deserializer<'de>,
490        T: Deserialize<'de>,
491    {
492        let value = T::deserialize(deserializer)?;
493        Ok(Rc::new(RefCell::new(value)))
494    }
495
496    /// Deserializer for `Option<Rc<RefCell<T>>`
497    #[allow(clippy::missing_errors_doc)]
498    pub fn deserialize_option<'de, D, T>(
499        deserializer: D,
500    ) -> Result<Option<Rc<RefCell<T>>>, D::Error>
501    where
502        D: Deserializer<'de>,
503        T: Deserialize<'de>,
504    {
505        let opt = Option::<T>::deserialize(deserializer)?;
506        Ok(opt.map(|value| Rc::new(RefCell::new(value))))
507    }
508
509    /// Deserializer for `Vec<Rc<RefCell<T>>`
510    #[allow(clippy::missing_errors_doc)]
511    // grcov-excl-start
512    pub fn deserialize_vec<'de, D, T>(deserializer: D) -> Result<Vec<Rc<RefCell<T>>>, D::Error>
513    where
514        D: Deserializer<'de>,
515        T: Deserialize<'de>,
516    {
517        let vec = Vec::<T>::deserialize(deserializer)?;
518        Ok(vec
519            .into_iter()
520            .map(|item| Rc::new(RefCell::new(item)))
521            .collect())
522    } // grcov-excl-end
523}