semantic_analyzer/
ast.rs

1//! # AST
2//! Abstract Syntax Tree representation contains tree node that
3//! represent full cycle and aspects of the programming language, and
4//! represent `Turing-complete` state machine.
5
6use crate::types::semantic::{ExtendedExpression, SemanticContextInstruction};
7use nom_locate::LocatedSpan;
8#[cfg(feature = "codec")]
9use serde::{
10    de::{self, Deserializer, MapAccess, Visitor},
11    ser::{SerializeStruct, Serializer},
12    Deserialize, Serialize,
13};
14use std::convert::Infallible;
15use std::marker::PhantomData;
16
17/// Max priority level fpr expressions operations
18pub const MAX_PRIORITY_LEVEL_FOR_EXPRESSIONS: u8 = 9;
19
20/// Basic `Ident` entity for elements of AST
21#[derive(Clone, Debug, Copy, PartialEq, Eq)]
22pub struct Ident<'a>(LocatedSpan<&'a str>);
23
24/// Ident methods mirroring `LocatedSpan`
25impl<'a> Ident<'a> {
26    #[must_use]
27    pub fn new(ident: &'a str) -> Self {
28        Self(LocatedSpan::new(ident))
29    }
30
31    #[must_use]
32    pub fn fragment(&self) -> &'a str {
33        self.0.fragment()
34    }
35
36    #[must_use]
37    pub fn location_line(&self) -> u32 {
38        self.0.location_line()
39    }
40
41    #[must_use]
42    pub fn location_offset(&self) -> usize {
43        self.0.location_offset()
44    }
45}
46
47impl std::fmt::Display for Ident<'_> {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        write!(f, "{}", self.fragment())
50    }
51}
52
53impl<'a> From<&'a str> for Ident<'a> {
54    fn from(value: &'a str) -> Self {
55        Ident::new(value)
56    }
57}
58
59/// Ident Serializer
60#[cfg(feature = "codec")]
61impl Serialize for Ident<'_> {
62    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
63    where
64        S: Serializer,
65    {
66        let fragment = self.0.into_fragment_and_extra();
67        let mut state = serializer.serialize_struct("Ident", 4)?;
68        state.serialize_field("offset", &self.0.location_offset())?;
69        state.serialize_field("line", &self.0.location_line())?;
70        state.serialize_field("fragment", &fragment.0)?;
71        state.serialize_field("extra", &fragment.1)?;
72        state.end()
73    }
74}
75
76/// Ident Deserializer
77#[cfg(feature = "codec")]
78impl<'de: 'a, 'a> Deserialize<'de> for Ident<'a> {
79    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
80    where
81        D: Deserializer<'de>,
82    {
83        // grcov-excl-start
84        struct IdentVisitor<'a> {
85            marker: PhantomData<fn() -> Ident<'a>>,
86        }
87
88        impl<'de: 'a, 'a> Visitor<'de> for IdentVisitor<'a> {
89            type Value = Ident<'de>;
90
91            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
92                formatter.write_str("struct Ident")
93            }
94
95            fn visit_map<V>(self, mut map: V) -> Result<Ident<'de>, V::Error>
96            where
97                V: MapAccess<'de>,
98            {
99                let mut offset = None;
100                let mut line = None;
101                let mut fragment = None;
102                let mut extra = None;
103                while let Some(key) = map.next_key::<String>()? {
104                    match key.as_str() {
105                        "offset" => {
106                            if offset.is_some() {
107                                return Err(de::Error::duplicate_field("offset"));
108                            }
109                            offset = Some(map.next_value()?);
110                        }
111                        "line" => {
112                            if line.is_some() {
113                                return Err(de::Error::duplicate_field("line"));
114                            }
115                            line = Some(map.next_value()?);
116                        }
117                        "fragment" => {
118                            if fragment.is_some() {
119                                return Err(de::Error::duplicate_field("fragment"));
120                            }
121                            fragment = Some(map.next_value()?);
122                        }
123                        "extra" => {
124                            if extra.is_some() {
125                                return Err(de::Error::duplicate_field("extra"));
126                            }
127                            extra = Some(map.next_value()?);
128                        }
129                        _ => return Err(de::Error::unknown_field(&key, FIELDS)),
130                    }
131                }
132                let offset = offset.ok_or_else(|| de::Error::missing_field("offset"))?;
133                let line = line.ok_or_else(|| de::Error::missing_field("line"))?;
134                let fragment = fragment.ok_or_else(|| de::Error::missing_field("fragment"))?;
135                #[allow(clippy::let_unit_value)]
136                let extra = extra.ok_or_else(|| de::Error::missing_field("extra"))?;
137                let located =
138                    unsafe { LocatedSpan::new_from_raw_offset(offset, line, fragment, extra) };
139                Ok(Ident(located))
140            }
141            // grcov-excl-end
142        }
143
144        const FIELDS: &[&str] = &["offset", "line", "fragment", "extra"];
145        deserializer.deserialize_struct(
146            "Ident",
147            FIELDS,
148            IdentVisitor {
149                marker: PhantomData,
150            },
151        )
152    }
153}
154
155/// `GetName` trait, represent name of specific entity.
156pub trait GetName {
157    fn name(&self) -> String;
158}
159
160/// `GetLocation` represent location of source data for AST element.
161/// Useful to locate specific source code location, especially for `Ident`.
162pub trait GetLocation {
163    fn location(&self) -> CodeLocation;
164}
165
166/// Import name element of AST
167#[derive(Debug, Clone, PartialEq, Eq)]
168#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
169pub struct ImportName<'a>(#[cfg_attr(feature = "codec", serde(borrow))] Ident<'a>);
170
171impl GetName for ImportName<'_> {
172    fn name(&self) -> String {
173        (*self.0.fragment()).to_string()
174    }
175}
176
177impl<'a> ImportName<'a> {
178    #[must_use]
179    pub const fn new(ident: Ident<'a>) -> Self {
180        Self(ident)
181    }
182}
183
184/// Imports with full path of import
185pub type ImportPath<'a> = Vec<ImportName<'a>>;
186
187/// `ConstantName` constant name for `Constant` elements of AST
188#[derive(Debug, Clone, PartialEq, Eq)]
189#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
190pub struct ConstantName<'a>(#[cfg_attr(feature = "codec", serde(borrow))] Ident<'a>);
191
192impl<'a> ConstantName<'a> {
193    /// Init `ConstantName`, especially useful for testing
194    #[must_use]
195    pub const fn new(name: Ident<'a>) -> Self {
196        Self(name)
197    }
198}
199
200impl GetLocation for ConstantName<'_> {
201    fn location(&self) -> CodeLocation {
202        CodeLocation::new(self.0.location_line(), self.0.location_offset())
203    }
204}
205
206impl GetName for ConstantName<'_> {
207    fn name(&self) -> String {
208        (*self.0.fragment()).to_string()
209    }
210}
211
212/// `FunctionName` function name for `Function` elements of AST.
213#[derive(Debug, Clone, PartialEq, Eq)]
214#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
215pub struct FunctionName<'a>(#[cfg_attr(feature = "codec", serde(borrow))] Ident<'a>);
216
217impl<'a> FunctionName<'a> {
218    #[must_use]
219    pub const fn new(name: Ident<'a>) -> Self {
220        Self(name)
221    }
222}
223
224impl GetLocation for FunctionName<'_> {
225    fn location(&self) -> CodeLocation {
226        CodeLocation::new(self.0.location_line(), self.0.location_offset())
227    }
228}
229
230impl std::fmt::Display for FunctionName<'_> {
231    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
232        write!(f, "{}", self.0.fragment())
233    }
234}
235
236/// `ParameterName` parameter name element of AST, used for `Function`
237/// parameters declaration.
238#[derive(Debug, Clone, PartialEq, Eq)]
239#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
240pub struct ParameterName<'a>(#[cfg_attr(feature = "codec", serde(borrow))] Ident<'a>);
241
242impl<'a> ParameterName<'a> {
243    #[must_use]
244    pub const fn new(name: Ident<'a>) -> Self {
245        Self(name)
246    }
247}
248
249impl std::fmt::Display for ParameterName<'_> {
250    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
251        write!(f, "{}", self.0.fragment())
252    }
253}
254
255/// `ValueName` value name element of AST. It's basic entity for:
256/// - `Struct` type declaration
257/// - `LetBinding` declaration
258/// - `Binding` declaration
259/// - `ExpressionValue` declaration
260#[derive(Debug, Clone, PartialEq, Eq)]
261#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
262pub struct ValueName<'a>(#[cfg_attr(feature = "codec", serde(borrow))] Ident<'a>);
263
264impl<'a> ValueName<'a> {
265    #[must_use]
266    pub const fn new(name: Ident<'a>) -> Self {
267        Self(name)
268    }
269}
270
271impl GetLocation for ValueName<'_> {
272    fn location(&self) -> CodeLocation {
273        CodeLocation::new(self.0.location_line(), self.0.location_offset())
274    }
275}
276
277impl GetName for ValueName<'_> {
278    fn name(&self) -> String {
279        (*self.0.fragment()).to_string()
280    }
281}
282
283/// `CodeLocation` code location of source for AST elements.
284/// Contains: `line` nad `position`.
285#[derive(Debug, Clone, PartialEq, Eq)]
286#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
287pub struct CodeLocation(u32, usize);
288
289impl CodeLocation {
290    /// Initialize code location with:
291    /// - `location` - line of source code
292    /// - `offset` - position on the line of source code
293    #[must_use]
294    pub const fn new(location: u32, offset: usize) -> Self {
295        Self(location, offset)
296    }
297
298    /// Get location line in the source
299    #[must_use]
300    pub const fn line(&self) -> u32 {
301        self.0
302    }
303
304    /// Get location position on the line in the source
305    #[must_use]
306    pub const fn offset(&self) -> usize {
307        self.1
308    }
309}
310
311/// `PrimitiveTypes` primitive types elements of AST.
312/// It's represent basic (primitive) types.
313#[derive(Debug, Clone, PartialEq, Eq)]
314#[cfg_attr(
315    feature = "codec",
316    derive(Serialize, Deserialize),
317    serde(tag = "type", content = "content")
318)]
319pub enum PrimitiveTypes {
320    U8,
321    U16,
322    U32,
323    U64,
324    I8,
325    I16,
326    I32,
327    I64,
328    F32,
329    F64,
330    Bool,
331    Char,
332    Ptr,
333    None,
334}
335
336impl GetName for PrimitiveTypes {
337    fn name(&self) -> String {
338        match self {
339            Self::U8 => "u8".to_string(),
340            Self::U16 => "u16".to_string(),
341            Self::U32 => "u32".to_string(),
342            Self::U64 => "u64".to_string(),
343            Self::I8 => "i8".to_string(),
344            Self::I16 => "i16".to_string(),
345            Self::I32 => "i32".to_string(),
346            Self::I64 => "i64".to_string(),
347            Self::F32 => "f32".to_string(),
348            Self::F64 => "f64".to_string(),
349            Self::Bool => "bool".to_string(),
350            Self::Char => "char".to_string(),
351            Self::Ptr => "ptr".to_string(),
352            Self::None => "()".to_string(),
353        }
354    }
355}
356
357/// `ExpressionStructValue` expression struct value element of AST.
358/// Used for expression value declaration. The basic entity is:
359/// - value name of struct type
360/// - value struct type attribute
361#[derive(Debug, Clone, PartialEq, Eq)]
362#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
363pub struct ExpressionStructValue<'a> {
364    /// Value name of struct typed value
365    #[cfg_attr(feature = "codec", serde(borrow))]
366    pub name: ValueName<'a>,
367    /// Attribute name of struct typed value
368    pub attribute: ValueName<'a>,
369}
370
371/// `StructType` struct type basic element used for `StructTypes`.
372/// It contains basic elements:
373/// - attribute name
374/// - attribute type
375#[derive(Debug, Clone, PartialEq)]
376#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
377pub struct StructType<'a> {
378    /// Attribute name entity of struct type
379    #[cfg_attr(feature = "codec", serde(borrow))]
380    pub attr_name: Ident<'a>,
381    /// Attribute type entity of struct type
382    pub attr_type: Type<'a>,
383}
384
385impl GetName for StructType<'_> {
386    fn name(&self) -> String {
387        (*self.attr_name.fragment()).to_string()
388    }
389}
390
391/// `StructTypes` struct type element of AST.
392/// Basic entity to declare struct complex types and its attributes.
393#[derive(Debug, Clone, PartialEq)]
394#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
395pub struct StructTypes<'a> {
396    /// Struct type name
397    #[cfg_attr(feature = "codec", serde(borrow))]
398    pub name: Ident<'a>,
399    /// Struct type attributes
400    pub attributes: Vec<StructType<'a>>,
401}
402
403impl GetLocation for StructTypes<'_> {
404    fn location(&self) -> CodeLocation {
405        CodeLocation::new(self.name.location_line(), self.name.location_offset())
406    }
407}
408
409impl GetName for StructTypes<'_> {
410    fn name(&self) -> String {
411        (*self.name.fragment()).to_string()
412    }
413}
414
415/// `Type` element of AST.
416/// Basic entity that represents types. Basic type entity is:
417/// - Primitive types
418/// - Struct types
419/// - Arrays
420#[derive(Debug, Clone, PartialEq)]
421#[cfg_attr(
422    feature = "codec",
423    derive(Serialize, Deserialize),
424    serde(tag = "type", content = "content")
425)]
426pub enum Type<'a> {
427    Primitive(PrimitiveTypes),
428    #[cfg_attr(feature = "codec", serde(borrow))]
429    Struct(StructTypes<'a>),
430    Array(Box<Self>, u32),
431}
432
433impl GetName for Type<'_> {
434    fn name(&self) -> String {
435        match self {
436            Self::Primitive(primitive) => primitive.name(),
437            Self::Struct(struct_type) => (*struct_type.name.fragment()).to_string(),
438            Self::Array(array_type, size) => {
439                format!("[{:?};{:?}]", array_type.name(), size)
440            }
441        }
442    }
443}
444
445/// `ConstantValue` constant value element of AST.
446/// Used for `ConstantExpression`. Constant value basic entities:
447/// - `constant` it can contain other constant
448/// - `value` - primitive value (like numbers etc.)
449#[derive(Debug, Clone, PartialEq)]
450#[cfg_attr(
451    feature = "codec",
452    derive(Serialize, Deserialize),
453    serde(tag = "type", content = "content")
454)]
455pub enum ConstantValue<'a> {
456    #[cfg_attr(feature = "codec", serde(borrow))]
457    Constant(ConstantName<'a>),
458    Value(PrimitiveValue),
459}
460
461/// `ConstantExpression` constant expression element of AST.
462/// Used to declare constants.
463/// The constant expression value based on other constant or primitive values.
464/// Constant Expression can contain optional expression operation with other
465/// constant expression. So it can be represented as Constant expression
466/// tree as operations with other constant expressions.
467#[derive(Debug, Clone, PartialEq)]
468#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
469pub struct ConstantExpression<'a> {
470    /// Constant value - can be other constant 0r primitive value
471    #[cfg_attr(feature = "codec", serde(borrow))]
472    pub value: ConstantValue<'a>,
473    /// Constant expression optional expression operation with other constant expression declarations.
474    pub operation: Option<(ExpressionOperations, Box<ConstantExpression<'a>>)>,
475}
476
477/// `Constant` constant declaration element of AST.
478/// Basic constant entity contains:
479/// - constant name
480/// - constant type
481/// - constant value - based on constant expression
482#[derive(Debug, Clone, PartialEq)]
483#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
484pub struct Constant<'a> {
485    /// Constant name
486    #[cfg_attr(feature = "codec", serde(borrow))]
487    pub name: ConstantName<'a>,
488    /// Constant type
489    pub constant_type: Type<'a>,
490    /// Constant value based on constant expression
491    pub constant_value: ConstantExpression<'a>,
492}
493
494impl GetLocation for Constant<'_> {
495    fn location(&self) -> CodeLocation {
496        self.name.location()
497    }
498}
499
500impl GetName for Constant<'_> {
501    fn name(&self) -> String {
502        (*self.name.0.fragment()).to_string()
503    }
504}
505
506/// `FunctionParameter` function parameter element of AST.
507/// Used for `FunctionStatement` declaration.
508#[derive(Debug, Clone, PartialEq)]
509#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
510pub struct FunctionParameter<'a> {
511    /// Function parameter name
512    #[cfg_attr(feature = "codec", serde(borrow))]
513    pub name: ParameterName<'a>,
514    /// Function parameter type
515    pub parameter_type: Type<'a>,
516}
517
518/// `FunctionStatement` it's one of the most basic element of AST.
519/// Basic entity of program logic. It contains function declaration and
520/// function body.
521#[derive(Debug, Clone, PartialEq)]
522#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
523pub struct FunctionStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
524    /// Function name
525    #[cfg_attr(feature = "codec", serde(borrow))]
526    pub name: FunctionName<'a>,
527    /// Function parameters
528    pub parameters: Vec<FunctionParameter<'a>>,
529    /// Function result type
530    pub result_type: Type<'a>,
531    /// Function body
532    pub body: Vec<BodyStatement<'a, I, E>>,
533    _marker: PhantomData<I>,
534}
535
536impl<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> FunctionStatement<'a, I, E> {
537    #[must_use]
538    pub const fn new(
539        name: FunctionName<'a>,
540        parameters: Vec<FunctionParameter<'a>>,
541        result_type: Type<'a>,
542        body: Vec<BodyStatement<'a, I, E>>,
543    ) -> Self {
544        Self {
545            name,
546            parameters,
547            result_type,
548            body,
549            _marker: PhantomData,
550        }
551    }
552}
553
554impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation
555    for FunctionStatement<'_, I, E>
556{
557    fn location(&self) -> CodeLocation {
558        self.name.location()
559    }
560}
561
562impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetName
563    for FunctionStatement<'_, I, E>
564{
565    fn name(&self) -> String {
566        (*self.name.0.fragment()).to_string()
567    }
568}
569
570/// `PrimitiveValue` represents primitive value element of AST.
571/// Values based on primitive types.
572/// Used for `ConstantValue` and `ExpressionValue`.
573#[derive(Debug, Clone, PartialEq)]
574#[cfg_attr(
575    feature = "codec",
576    derive(Serialize, Deserialize),
577    serde(tag = "type", content = "content")
578)]
579pub enum PrimitiveValue {
580    U8(u8),
581    U16(u16),
582    U32(u32),
583    U64(u64),
584    I8(i8),
585    I16(i16),
586    I32(i32),
587    I64(i64),
588    F32(f32),
589    F64(f64),
590    Bool(bool),
591    Char(char),
592    Ptr,
593    None,
594}
595
596impl PrimitiveValue {
597    #[must_use]
598    pub const fn get_type(&self) -> Type<'_> {
599        match self {
600            Self::U8(_) => Type::Primitive(PrimitiveTypes::U8),
601            Self::U16(_) => Type::Primitive(PrimitiveTypes::U16),
602            Self::U32(_) => Type::Primitive(PrimitiveTypes::U32),
603            Self::U64(_) => Type::Primitive(PrimitiveTypes::U64),
604            Self::I8(_) => Type::Primitive(PrimitiveTypes::I8),
605            Self::I16(_) => Type::Primitive(PrimitiveTypes::I16),
606            Self::I32(_) => Type::Primitive(PrimitiveTypes::I32),
607            Self::I64(_) => Type::Primitive(PrimitiveTypes::I64),
608            Self::F32(_) => Type::Primitive(PrimitiveTypes::F32),
609            Self::F64(_) => Type::Primitive(PrimitiveTypes::F64),
610            Self::Char(_) => Type::Primitive(PrimitiveTypes::Char),
611            Self::Bool(_) => Type::Primitive(PrimitiveTypes::Bool),
612            Self::Ptr => Type::Primitive(PrimitiveTypes::Ptr),
613            Self::None => Type::Primitive(PrimitiveTypes::None),
614        }
615    }
616}
617
618/// `ExpressionValue` expression value element of AST.
619/// Basic entity for `Expression` elements of AST.
620/// Expression value contains entities:
621/// - `ValueName` - value name of expression
622/// - `PrimitiveValue` - primitive value name of expression (for
623///   example, it's numbers: 10, 3.2 and other primitive values)
624/// - `FunctionCall` - function call (with parameters) of expression
625/// - `StructValue` - value of expression based on `Struct` types.
626/// - `Expression` - expression representation (sub-branch)
627#[derive(Debug, Clone, PartialEq)]
628#[cfg_attr(
629    feature = "codec",
630    derive(Serialize, Deserialize),
631    serde(tag = "type", content = "content")
632)]
633pub enum ExpressionValue<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
634    /// Value name of expression
635    #[cfg_attr(feature = "codec", serde(borrow))]
636    ValueName(ValueName<'a>),
637    /// Primitive value of expression (like numbers etc.)
638    PrimitiveValue(PrimitiveValue),
639    /// Function call (with parameters) of expression
640    FunctionCall(FunctionCall<'a, I, E>),
641    /// Value of expression based on `Struct` types.
642    StructValue(ExpressionStructValue<'a>),
643    /// Expression representation (sub-branch)
644    Expression(Box<Expression<'a, I, E>>),
645    /// Extended expression
646    ExtendedExpression(Box<E>),
647    #[cfg_attr(feature = "codec", serde(skip))]
648    #[allow(non_camel_case_types)]
649    _marker(Infallible, PhantomData<I>),
650}
651
652/// `ExpressionOperations` expression operation element of AST.
653/// Used for expression operations:
654/// - `ConstantExpression` - expression of constant declaration
655/// - `Expression` - part of operations for expressions
656#[derive(Debug, Clone, PartialEq, Eq)]
657#[cfg_attr(
658    feature = "codec",
659    derive(Serialize, Deserialize),
660    serde(tag = "type", content = "content")
661)]
662pub enum ExpressionOperations {
663    Plus,
664    Minus,
665    Multiply,
666    Divide,
667    ShiftLeft,
668    ShiftRight,
669    And,
670    Or,
671    Xor,
672    Eq,
673    NotEq,
674    Great,
675    Less,
676    GreatEq,
677    LessEq,
678}
679
680impl ExpressionOperations {
681    /// Get expression operation priority level
682    #[must_use]
683    pub const fn priority(&self) -> u8 {
684        match self {
685            Self::Plus => 5,
686            Self::Minus => 4,
687            Self::Divide => 8,
688            Self::Multiply | Self::ShiftLeft | Self::ShiftRight => {
689                MAX_PRIORITY_LEVEL_FOR_EXPRESSIONS
690            }
691            Self::Or | Self::Xor => 6,
692            Self::And
693            | Self::Eq
694            | Self::NotEq
695            | Self::Great
696            | Self::Less
697            | Self::GreatEq
698            | Self::LessEq => 7,
699        }
700    }
701}
702
703/// `Expression` element of AST is basic entity that
704/// represent expression, and optionally expression with optional
705/// operations with other expression. So it can be expression tree
706/// with expression operations.
707#[derive(Debug, Clone, PartialEq)]
708#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
709pub struct Expression<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
710    /// Expression value itself
711    #[cfg_attr(feature = "codec", serde(borrow))]
712    pub expression_value: ExpressionValue<'a, I, E>,
713    /// Optional expression operation with other expression value
714    pub operation: Option<(ExpressionOperations, Box<Expression<'a, I, E>>)>,
715}
716
717impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation for Expression<'_, I, E> {
718    fn location(&self) -> CodeLocation {
719        // TODO: extend it
720        CodeLocation::new(1, 0)
721    }
722}
723
724/// `LetBinding` let binding element of AST. Basic entity
725/// for `values` declarations.
726#[derive(Debug, Clone, PartialEq)]
727#[cfg_attr(feature = "codec", derive(Serialize, Deserialize), serde(tag = "type"))]
728pub struct LetBinding<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
729    /// Value name of let binding
730    #[cfg_attr(feature = "codec", serde(borrow))]
731    pub name: ValueName<'a>,
732    /// Mutability flag of binding
733    pub mutable: bool,
734    /// Optional type of value
735    pub value_type: Option<Type<'a>>,
736    /// Value expression to bind as result of let bending
737    pub value: Box<Expression<'a, I, E>>,
738}
739
740impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation for LetBinding<'_, I, E> {
741    fn location(&self) -> CodeLocation {
742        self.name.location()
743    }
744}
745
746impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetName for LetBinding<'_, I, E> {
747    fn name(&self) -> String {
748        self.name.0.to_string()
749    }
750}
751
752/// `Binding` binding element of AST. Basic entity
753/// for `values` re-declaration, to bind new values for already
754/// declared values.
755#[derive(Debug, Clone, PartialEq)]
756#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
757pub struct Binding<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
758    /// Binding value name
759    #[cfg_attr(feature = "codec", serde(borrow))]
760    pub name: ValueName<'a>,
761    /// Value expression as result of binding
762    pub value: Box<Expression<'a, I, E>>,
763}
764
765impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation for Binding<'_, I, E> {
766    fn location(&self) -> CodeLocation {
767        self.name.location()
768    }
769}
770
771impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetName for Binding<'_, I, E> {
772    fn name(&self) -> String {
773        self.name.0.to_string()
774    }
775}
776
777/// `FunctionCall` function call element of AST.
778/// Basic entity for function call representation.
779#[derive(Debug, Clone, PartialEq)]
780#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
781pub struct FunctionCall<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
782    /// Function name of called function
783    #[cfg_attr(feature = "codec", serde(borrow))]
784    pub name: FunctionName<'a>,
785    /// Function parameters, represented through expression
786    pub parameters: Vec<Expression<'a, I, E>>,
787}
788
789impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation
790    for FunctionCall<'_, I, E>
791{
792    fn location(&self) -> CodeLocation {
793        self.name.location()
794    }
795}
796
797impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetName for FunctionCall<'_, I, E> {
798    fn name(&self) -> String {
799        (*self.name.0.fragment()).to_string()
800    }
801}
802
803/// `Condition` condition declarations.
804/// Used for `ExpressionCondition`. Contains basic condition
805/// entities: `<. >, ==, <=, >=, !=`
806#[derive(Debug, Clone, PartialEq, Eq)]
807#[cfg_attr(
808    feature = "codec",
809    derive(Serialize, Deserialize),
810    serde(tag = "type", content = "content")
811)]
812pub enum Condition {
813    Great,
814    Less,
815    Eq,
816    GreatEq,
817    LessEq,
818    NotEq,
819}
820
821/// `LogicCondition` declaration of logical condition operation.
822/// It can contains only: `and`, `or`. Used for `IfCondition` element of AST.
823#[derive(Debug, Clone, PartialEq, Eq)]
824#[cfg_attr(
825    feature = "codec",
826    derive(Serialize, Deserialize),
827    serde(tag = "type", content = "content")
828)]
829pub enum LogicCondition {
830    And,
831    Or,
832}
833
834/// `ExpressionCondition` expression condition element of AST.
835/// Used in `ExpressionLogicCondition` for `IfCondition` declaration.
836/// It contains condition between twe expressions.
837#[derive(Debug, Clone, PartialEq)]
838#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
839pub struct ExpressionCondition<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
840    /// Left expression
841    #[cfg_attr(feature = "codec", serde(borrow))]
842    pub left: Expression<'a, I, E>,
843    /// Condition between left and right expressions
844    pub condition: Condition,
845    /// Right expression
846    pub right: Expression<'a, I, E>,
847}
848
849/// # Logic expression condition
850/// `ExpressionLogicCondition` expression logic condition used for
851/// `IfCondition` declaration.
852/// Expression logic condition can contains left and optional right
853/// parts. Right part represent logic condition (like `or`, `and`) to
854/// other `ExpressionLogicCondition`. So finally ir can represent tree
855/// expressions logic conditions.
856#[derive(Debug, Clone, PartialEq)]
857#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
858pub struct ExpressionLogicCondition<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
859    /// Left expression condition
860    #[cfg_attr(feature = "codec", serde(borrow))]
861    pub left: ExpressionCondition<'a, I, E>,
862    /// Optional right side contain logic operation to other `ExpressionLogicCondition`
863    pub right: Option<(LogicCondition, Box<ExpressionLogicCondition<'a, I, E>>)>,
864}
865
866/// `IfCondition` if-condition control flow element of AST.
867/// One of the basic control flow. Basic entities:
868/// - single expression condition
869/// - logic expression condition tree
870#[derive(Debug, Clone, PartialEq)]
871#[cfg_attr(
872    feature = "codec",
873    derive(Serialize, Deserialize),
874    serde(tag = "type", content = "content")
875)]
876pub enum IfCondition<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
877    /// Single if condition based on expression
878    #[cfg_attr(feature = "codec", serde(borrow))]
879    Single(Expression<'a, I, E>),
880    /// Logic expression condition tree
881    Logic(ExpressionLogicCondition<'a, I, E>),
882}
883
884/// `IfStatement` if statement AST element.
885/// Contains full representation of if statement with entities:
886/// - if-condition
887/// - If-body statement - body of if-condition success
888/// - Ff-else-body statement - body of else-condition success
889/// - Else-if-body statement - body of else-if-condition success
890#[derive(Debug, Clone, PartialEq)]
891#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
892pub struct IfStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
893    /// If-condition
894    #[cfg_attr(feature = "codec", serde(borrow))]
895    pub condition: IfCondition<'a, I, E>,
896    /// If-body statement - body of if-condition success
897    pub body: IfBodyStatements<'a, I, E>,
898    /// If-else-body statement - body of else-condition success
899    pub else_statement: Option<IfBodyStatements<'a, I, E>>,
900    /// Else-if-body statement - body of else-if-condition success
901    pub else_if_statement: Option<Box<IfStatement<'a, I, E>>>,
902}
903
904impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation
905    for IfStatement<'_, I, E>
906{
907    fn location(&self) -> CodeLocation {
908        // TODO
909        CodeLocation::new(1, 0)
910    }
911}
912
913/// `BodyStatement` one of the basic AST elements.
914/// It's part of Function body.
915#[derive(Debug, Clone, PartialEq)]
916#[cfg_attr(
917    feature = "codec",
918    derive(Serialize, Deserialize),
919    serde(tag = "type", content = "content")
920)]
921pub enum BodyStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
922    /// Let-binding function declaration
923    #[cfg_attr(feature = "codec", serde(borrow))]
924    LetBinding(LetBinding<'a, I, E>),
925    /// Binding function declaration
926    Binding(Binding<'a, I, E>),
927    /// Function call
928    FunctionCall(FunctionCall<'a, I, E>),
929    /// If-condition control flow statement
930    If(IfStatement<'a, I, E>),
931    /// Loop control flow statement
932    Loop(Vec<LoopBodyStatement<'a, I, E>>),
933    /// Expression statement
934    Expression(Expression<'a, I, E>),
935    /// Return statement
936    Return(Expression<'a, I, E>),
937}
938
939/// `IfBodyStatement` statement of if-body elements tree of AST.
940/// Used as body statement of If-control flow.
941#[derive(Debug, Clone, PartialEq)]
942#[cfg_attr(
943    feature = "codec",
944    derive(Serialize, Deserialize),
945    serde(tag = "type", content = "content")
946)]
947pub enum IfBodyStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
948    #[cfg_attr(feature = "codec", serde(borrow))]
949    LetBinding(LetBinding<'a, I, E>),
950    Binding(Binding<'a, I, E>),
951    FunctionCall(FunctionCall<'a, I, E>),
952    If(IfStatement<'a, I, E>),
953    Loop(Vec<LoopBodyStatement<'a, I, E>>),
954    Return(Expression<'a, I, E>),
955}
956
957/// `IfLoopBodyStatement` statement of loop-if-body elements tree of AST.
958/// Used as body statement of If-control flow in the `Loop` AST element.
959#[derive(Debug, Clone, PartialEq)]
960#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
961#[cfg_attr(feature = "codec", serde(tag = "type", content = "content"))]
962pub enum IfLoopBodyStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
963    #[cfg_attr(feature = "codec", serde(borrow))]
964    LetBinding(LetBinding<'a, I, E>),
965    Binding(Binding<'a, I, E>),
966    FunctionCall(FunctionCall<'a, I, E>),
967    If(IfStatement<'a, I, E>),
968    Loop(Vec<LoopBodyStatement<'a, I, E>>),
969    Return(Expression<'a, I, E>),
970    Break,
971    Continue,
972}
973
974/// `IfBodyStatements` set of elements in the AST, that represents
975/// control flow: `if`, `loop`
976#[derive(Debug, Clone, PartialEq)]
977#[cfg_attr(
978    feature = "codec",
979    derive(Serialize, Deserialize),
980    serde(tag = "type", content = "content")
981)]
982pub enum IfBodyStatements<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
983    #[cfg_attr(feature = "codec", serde(borrow))]
984    If(Vec<IfBodyStatement<'a, I, E>>),
985    Loop(Vec<IfLoopBodyStatement<'a, I, E>>),
986}
987
988/// `LoopBodyStatement` statement of loop-body elements tree of AST.
989/// Used as body statement of loop-control flow.
990#[derive(Debug, Clone, PartialEq)]
991#[cfg_attr(
992    feature = "codec",
993    derive(Serialize, Deserialize),
994    serde(tag = "type", content = "content")
995)]
996pub enum LoopBodyStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
997    #[cfg_attr(feature = "codec", serde(borrow))]
998    LetBinding(LetBinding<'a, I, E>),
999    Binding(Binding<'a, I, E>),
1000    FunctionCall(FunctionCall<'a, I, E>),
1001    If(IfStatement<'a, I, E>),
1002    Loop(Vec<LoopBodyStatement<'a, I, E>>),
1003    Return(Expression<'a, I, E>),
1004    Break,
1005    Continue,
1006}
1007
1008/// `MainStatement` main AST statement for all elements.
1009#[derive(Debug, Clone, PartialEq)]
1010#[cfg_attr(
1011    feature = "codec",
1012    derive(Serialize, Deserialize),
1013    serde(tag = "type", content = "content")
1014)]
1015pub enum MainStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
1016    /// Import declarations
1017    #[cfg_attr(feature = "codec", serde(borrow))]
1018    Import(ImportPath<'a>),
1019    /// Constant declarations
1020    Constant(Constant<'a>),
1021    /// Type declaration
1022    Types(StructTypes<'a>),
1023    /// Function declaration and function body-statement
1024    Function(FunctionStatement<'a, I, E>),
1025}
1026
1027/// # Main
1028/// Stack of `MainStatement` main AST elements. That gather
1029/// tries of AST, to represent full sort of source code.
1030pub type Main<'a, I, E> = Vec<MainStatement<'a, I, E>>;