semantic_analyzer/types/
mod.rs

1//! # Types
2//! Semantic analyzer type.
3//! Contains basic entities:
4//! - Semantic types system
5//! - Semantic basic elements types
6//! - Block state types
7//! - Error types
8
9#![allow(clippy::module_inception)]
10
11/// Block state types
12pub mod block_state;
13/// Condition types
14pub mod condition;
15/// Error types
16pub mod error;
17/// Expression types
18pub mod expression;
19/// Basic semantic types
20pub mod semantic;
21/// Types for type system
22pub mod types;
23
24use self::condition::{IfStatement, LoopBodyStatement};
25use self::expression::{Expression, ExpressionOperations};
26use self::types::Type;
27use crate::ast;
28use crate::ast::GetName;
29use crate::types::semantic::{ExtendedExpression, SemanticContextInstruction};
30#[cfg(feature = "codec")]
31use serde::{Deserialize, Serialize};
32use std::fmt::Display;
33
34/// Value name type
35#[derive(Debug, Clone, Eq, Hash, PartialEq)]
36#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
37pub struct ValueName(String);
38
39impl From<ast::ValueName<'_>> for ValueName {
40    fn from(value: ast::ValueName<'_>) -> Self {
41        Self(value.name())
42    }
43}
44
45impl From<String> for ValueName {
46    fn from(value: String) -> Self {
47        Self(value)
48    }
49}
50
51impl From<&str> for ValueName {
52    fn from(value: &str) -> Self {
53        Self(value.to_string())
54    }
55}
56
57impl Display for ValueName {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        write!(f, "{}", self.0.clone())
60    }
61}
62
63/// Inner value name type
64#[derive(Debug, Clone, Eq, Hash, PartialEq)]
65#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
66pub struct InnerValueName(String);
67
68impl From<ValueName> for InnerValueName {
69    fn from(value: ValueName) -> Self {
70        Self(value.0)
71    }
72}
73
74impl From<String> for InnerValueName {
75    fn from(value: String) -> Self {
76        Self(value)
77    }
78}
79
80impl From<&str> for InnerValueName {
81    fn from(value: &str) -> Self {
82        Self(value.to_string())
83    }
84}
85
86impl Display for InnerValueName {
87    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88        write!(f, "{}", self.0.clone())
89    }
90}
91
92/// Label name type
93#[derive(Debug, Clone, Eq, Hash, PartialEq)]
94#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
95pub struct LabelName(String);
96
97impl From<String> for LabelName {
98    fn from(value: String) -> Self {
99        Self(value)
100    }
101}
102
103impl Display for LabelName {
104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105        write!(f, "{}", self.0.clone())
106    }
107}
108
109/// Function name type
110#[derive(Debug, Clone, Eq, Hash, PartialEq)]
111#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
112pub struct FunctionName(String);
113
114impl From<String> for FunctionName {
115    fn from(value: String) -> Self {
116        Self(value)
117    }
118}
119
120impl From<ast::FunctionName<'_>> for FunctionName {
121    fn from(value: ast::FunctionName<'_>) -> Self {
122        Self(value.to_string())
123    }
124}
125
126impl Display for FunctionName {
127    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128        write!(f, "{}", self.0.clone())
129    }
130}
131
132/// Constant name type
133#[derive(Debug, Clone, Eq, Hash, PartialEq)]
134#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
135pub struct ConstantName(String);
136
137impl From<ast::ConstantName<'_>> for ConstantName {
138    fn from(value: ast::ConstantName<'_>) -> Self {
139        Self(value.name())
140    }
141}
142
143impl From<String> for ConstantName {
144    fn from(value: String) -> Self {
145        Self(value)
146    }
147}
148
149impl Display for ConstantName {
150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151        write!(f, "{}", self.0.clone())
152    }
153}
154
155/// Constant value can contain other constant or primitive value
156#[derive(Debug, Clone, PartialEq)]
157#[cfg_attr(
158    feature = "codec",
159    derive(Serialize, Deserialize),
160    serde(tag = "type", content = "content")
161)]
162pub enum ConstantValue {
163    Constant(ConstantName),
164    Value(PrimitiveValue),
165}
166
167impl From<ast::ConstantValue<'_>> for ConstantValue {
168    fn from(value: ast::ConstantValue<'_>) -> Self {
169        match value {
170            ast::ConstantValue::Constant(v) => Self::Constant(v.into()),
171            ast::ConstantValue::Value(v) => Self::Value(v.into()),
172        }
173    }
174}
175
176/// Constant expression represent expression operation between
177/// constant values, and represent flat tree
178#[derive(Debug, Clone, PartialEq)]
179#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
180pub struct ConstantExpression {
181    /// Constant value for expression operation
182    pub value: ConstantValue,
183    /// Optional expression operation and next constant expression entry point
184    pub operation: Option<(ExpressionOperations, Box<ConstantExpression>)>,
185}
186
187impl From<ast::ConstantExpression<'_>> for ConstantExpression {
188    fn from(value: ast::ConstantExpression<'_>) -> Self {
189        Self {
190            value: value.value.into(),
191            operation: value
192                .operation
193                .map(|(op, expr)| (op.into(), Box::new(expr.as_ref().clone().into()))),
194        }
195    }
196}
197
198/// # Constant
199/// Can contain: name, type
200#[derive(Debug, Clone, PartialEq)]
201#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
202pub struct Constant {
203    /// Constant name
204    pub name: ConstantName,
205    /// Constant type
206    pub constant_type: Type,
207    /// Constant value represented through constant expression
208    pub constant_value: ConstantExpression,
209}
210
211impl From<ast::Constant<'_>> for Constant {
212    fn from(value: ast::Constant<'_>) -> Self {
213        Self {
214            name: value.name.into(),
215            constant_type: value.constant_type.into(),
216            constant_value: value.constant_value.into(),
217        }
218    }
219}
220
221/// # Values
222/// Can contain inner data: name, type, memory allocation status:
223/// - alloca - stack allocation
224/// - malloc - malloc allocation
225#[derive(Debug, Clone, Eq, PartialEq)]
226#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
227pub struct Value {
228    /// Inner value name
229    pub inner_name: InnerValueName,
230    /// Inner value type
231    pub inner_type: Type,
232    /// Mutability flag
233    pub mutable: bool,
234    /// Stack allocation flag
235    pub alloca: bool,
236    /// Memory allocation flag
237    pub malloc: bool,
238}
239
240/// # Function
241/// Function declaration analyze contains:
242/// - function name
243/// - function type
244/// - parameters of functions (with types only)
245///
246/// It used to detect functions in state and
247/// their parameters to use in normal execution
248/// flog.
249#[derive(Debug, Clone, Eq, PartialEq)]
250#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
251pub struct Function {
252    /// Inner function name
253    pub inner_name: FunctionName,
254    /// Inner (return) type
255    pub inner_type: Type,
256    /// Function parameters types
257    pub parameters: Vec<Type>,
258}
259
260/// Parameter name type for Functions parameter
261#[derive(Debug, Clone, PartialEq, Eq)]
262#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
263pub struct ParameterName(String);
264
265impl From<ast::ParameterName<'_>> for ParameterName {
266    fn from(value: ast::ParameterName<'_>) -> Self {
267        Self(value.to_string())
268    }
269}
270
271/// Function parameter one of the basic entity for `FunctionStatement`
272#[derive(Debug, Clone, Eq, PartialEq)]
273#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
274pub struct FunctionParameter {
275    /// Function parameter name
276    pub name: ParameterName,
277    /// Function parameter type
278    pub parameter_type: Type,
279}
280
281impl From<ast::FunctionParameter<'_>> for FunctionParameter {
282    fn from(value: ast::FunctionParameter<'_>) -> Self {
283        Self {
284            name: value.name.into(),
285            parameter_type: value.parameter_type.into(),
286        }
287    }
288}
289
290impl Display for FunctionParameter {
291    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
292        write!(f, "{}", self.name.0.clone())
293    }
294}
295
296/// # Function statement
297/// Function statement is basic type that represent function itself.
298/// The basic function struct elements:
299/// - function name
300/// - function parameters
301/// - function result type
302/// - function body statements
303#[derive(Debug, PartialEq, Clone)]
304#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
305pub struct FunctionStatement {
306    /// Function name
307    pub name: FunctionName,
308    /// Function parameters
309    pub parameters: Vec<FunctionParameter>,
310    /// Function result type
311    pub result_type: Type,
312    /// Function body statements
313    pub body: Vec<BodyStatement>,
314}
315
316impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::FunctionStatement<'_, I, E>>
317    for FunctionStatement
318{
319    fn from(value: ast::FunctionStatement<'_, I, E>) -> Self {
320        Self {
321            name: value.name.into(),
322            parameters: value.parameters.iter().map(|v| v.clone().into()).collect(),
323            result_type: value.result_type.into(),
324            body: value.body.iter().map(|v| v.clone().into()).collect(),
325        }
326    }
327}
328
329/// # Body statement
330/// Statement of body. Body is basic entity for functions and
331/// represent basic functions elements.
332#[derive(Debug, Clone, PartialEq)]
333#[cfg_attr(
334    feature = "codec",
335    derive(Serialize, Deserialize),
336    serde(tag = "type", content = "content")
337)]
338pub enum BodyStatement {
339    LetBinding(LetBinding),
340    Binding(Binding),
341    FunctionCall(FunctionCall),
342    If(IfStatement),
343    Loop(Vec<LoopBodyStatement>),
344    Expression(Expression),
345    Return(Expression),
346}
347
348impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::BodyStatement<'_, I, E>>
349    for BodyStatement
350{
351    fn from(value: ast::BodyStatement<'_, I, E>) -> Self {
352        match value {
353            ast::BodyStatement::LetBinding(v) => Self::LetBinding(v.into()),
354            ast::BodyStatement::Binding(v) => Self::Binding(v.into()),
355            ast::BodyStatement::FunctionCall(v) => Self::FunctionCall(v.into()),
356            ast::BodyStatement::If(v) => Self::If(v.into()),
357            ast::BodyStatement::Loop(v) => Self::Loop(v.iter().map(|v| v.clone().into()).collect()),
358            ast::BodyStatement::Expression(v) => Self::Expression(v.into()),
359            ast::BodyStatement::Return(v) => Self::Return(v.into()),
360        }
361    }
362}
363
364/// # Let binding
365/// Value initialization through binding.
366#[derive(Debug, Clone, PartialEq)]
367#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
368pub struct LetBinding {
369    /// Value name
370    pub name: ValueName,
371    /// Value mutability flag
372    pub mutable: bool,
373    /// Value type
374    pub value_type: Option<Type>,
375    /// Value bind expression
376    pub value: Box<Expression>,
377}
378
379impl Display for LetBinding {
380    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
381        write!(f, "{}", self.name)
382    }
383}
384
385impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::LetBinding<'_, I, E>>
386    for LetBinding
387{
388    fn from(value: ast::LetBinding<'_, I, E>) -> Self {
389        Self {
390            name: value.name.into(),
391            mutable: value.mutable,
392            value_type: value.value_type.map(Into::into),
393            value: Box::new(value.value.as_ref().clone().into()),
394        }
395    }
396}
397
398/// Primitive value is most primitive and basic values entity.
399/// It's basic elements for all other values elements.
400#[derive(Debug, Clone, PartialEq)]
401#[cfg_attr(
402    feature = "codec",
403    derive(Serialize, Deserialize),
404    serde(tag = "type", content = "content")
405)]
406pub enum PrimitiveValue {
407    U8(u8),
408    U16(u16),
409    U32(u32),
410    U64(u64),
411    I8(i8),
412    I16(i16),
413    I32(i32),
414    I64(i64),
415    F32(f32),
416    F64(f64),
417    Bool(bool),
418    Char(char),
419    Ptr,
420    None,
421}
422
423impl From<ast::PrimitiveValue> for PrimitiveValue {
424    fn from(value: ast::PrimitiveValue) -> Self {
425        match value {
426            ast::PrimitiveValue::U8(v) => Self::U8(v),
427            ast::PrimitiveValue::U16(v) => Self::U16(v),
428            ast::PrimitiveValue::U32(v) => Self::U32(v),
429            ast::PrimitiveValue::U64(v) => Self::U64(v),
430            ast::PrimitiveValue::I8(v) => Self::I8(v),
431            ast::PrimitiveValue::I16(v) => Self::I16(v),
432            ast::PrimitiveValue::I32(v) => Self::I32(v),
433            ast::PrimitiveValue::I64(v) => Self::I64(v),
434            ast::PrimitiveValue::F32(v) => Self::F32(v),
435            ast::PrimitiveValue::F64(v) => Self::F64(v),
436            ast::PrimitiveValue::Bool(v) => Self::Bool(v),
437            ast::PrimitiveValue::Char(v) => Self::Char(v),
438            ast::PrimitiveValue::Ptr => Self::Ptr,
439            ast::PrimitiveValue::None => Self::None,
440        }
441    }
442}
443
444impl Display for PrimitiveValue {
445    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
446        let str = match self {
447            Self::U8(val) => val.clone().to_string(),
448            Self::U16(val) => val.clone().to_string(),
449            Self::U32(val) => val.clone().to_string(),
450            Self::U64(val) => val.clone().to_string(),
451            Self::I8(val) => val.clone().to_string(),
452            Self::I16(val) => val.clone().to_string(),
453            Self::I32(val) => val.clone().to_string(),
454            Self::I64(val) => val.clone().to_string(),
455            Self::F32(val) => val.clone().to_string(),
456            Self::F64(val) => val.clone().to_string(),
457            Self::Bool(val) => val.to_string(),
458            Self::Char(c) => format!("{c}"),
459            Self::Ptr => "ptr".to_string(),
460            Self::None => "None".to_string(),
461        };
462        write!(f, "{str}")
463    }
464}
465
466/// # Function call
467/// Basic struct for function call representation
468#[derive(Debug, Clone, PartialEq)]
469#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
470pub struct FunctionCall {
471    /// Call function name
472    pub name: FunctionName,
473    /// Call function parameters contains expressions
474    pub parameters: Vec<Expression>,
475}
476
477impl Display for FunctionCall {
478    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
479        write!(f, "{}", self.name)
480    }
481}
482
483impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::FunctionCall<'_, I, E>>
484    for FunctionCall
485{
486    fn from(value: ast::FunctionCall<'_, I, E>) -> Self {
487        Self {
488            name: value.name.into(),
489            parameters: value.parameters.iter().map(|v| v.clone().into()).collect(),
490        }
491    }
492}
493
494/// `Binding` represents mutable binding for previously bind values
495#[derive(Debug, Clone, PartialEq)]
496#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
497pub struct Binding {
498    /// Binding value name
499    pub name: ValueName,
500    /// Value expression representation
501    pub value: Box<Expression>,
502}
503
504impl Display for Binding {
505    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
506        write!(f, "{}", self.name)
507    }
508}
509
510impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::Binding<'_, I, E>>
511    for Binding
512{
513    fn from(value: ast::Binding<'_, I, E>) -> Self {
514        Self {
515            name: value.name.into(),
516            value: Box::new(value.value.as_ref().clone().into()),
517        }
518    }
519}