semantic_analyzer/types/
expression.rs

1//! # Expression types
2//! Expression types for Semantic analyzer result state.
3
4use super::types::Type;
5use super::{FunctionCall, PrimitiveValue, ValueName};
6use crate::ast;
7use crate::types::semantic::{ExtendedExpression, SemanticContextInstruction};
8#[cfg(feature = "codec")]
9use serde::{Deserialize, Serialize};
10use std::fmt::Display;
11
12/// # Expression result
13/// Contains analyzing results of expression:
14/// - `expr_type` - result type of expression
15/// - `expr_value` - result value of expression
16#[derive(Debug, Clone, PartialEq)]
17#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
18pub struct ExpressionResult {
19    /// Result type of expression
20    pub expr_type: Type,
21    /// Result value of expression
22    pub expr_value: ExpressionResultValue,
23}
24
25/// # Expression Result Value
26/// Result value of expression analyze has to kind:
27/// - Primitive value
28/// - Register that contain result of expression
29///   evaluation or call.
30#[derive(Debug, Clone, PartialEq)]
31#[cfg_attr(
32    feature = "codec",
33    derive(Serialize, Deserialize),
34    serde(tag = "type", content = "content")
35)]
36pub enum ExpressionResultValue {
37    PrimitiveValue(PrimitiveValue),
38    Register(u64),
39}
40
41/// `ExtendedExpressionValue` represent simplified string
42/// data of custom extended `ExpressionValue`. For now
43/// used only for display errors.
44#[derive(Debug, Clone, Eq, PartialEq)]
45#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
46pub struct ExtendedExpressionValue(String);
47
48/// Expression value kinds:
49/// - value name - initialized through let-binding
50/// - primitive value - most primitive value, like integers etc.
51/// - struct value - value of struct type
52/// - function call - call of function with params
53/// - expression - contains other expression
54#[derive(Debug, Clone, PartialEq)]
55#[cfg_attr(
56    feature = "codec",
57    derive(Serialize, Deserialize),
58    serde(tag = "type", content = "content")
59)]
60pub enum ExpressionValue {
61    ValueName(ValueName),
62    PrimitiveValue(PrimitiveValue),
63    StructValue(ExpressionStructValue),
64    FunctionCall(FunctionCall),
65    Expression(Box<Expression>),
66    ExtendedExpression(ExtendedExpressionValue),
67}
68
69impl Display for ExpressionValue {
70    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71        let str = match self {
72            Self::ValueName(val) => val.clone().to_string(),
73            Self::PrimitiveValue(val) => val.clone().to_string(),
74            Self::StructValue(st_val) => st_val.clone().to_string(),
75            Self::FunctionCall(fn_call) => fn_call.clone().to_string(),
76            Self::Expression(val) => val.to_string(),
77            Self::ExtendedExpression(val) => val.clone().0,
78        };
79        write!(f, "{str}")
80    }
81}
82
83impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::ExpressionValue<'_, I, E>>
84    for ExpressionValue
85{
86    fn from(value: ast::ExpressionValue<'_, I, E>) -> Self {
87        match value {
88            #[allow(unreachable_patterns)]
89            ast::ExpressionValue::_marker(..) => unreachable!(),
90            ast::ExpressionValue::ValueName(v) => Self::ValueName(v.into()),
91            ast::ExpressionValue::PrimitiveValue(v) => Self::PrimitiveValue(v.into()),
92            ast::ExpressionValue::StructValue(v) => Self::StructValue(v.into()),
93            ast::ExpressionValue::FunctionCall(v) => Self::FunctionCall(v.into()),
94            ast::ExpressionValue::Expression(v) => {
95                Self::Expression(Box::new(v.as_ref().clone().into()))
96            }
97            ast::ExpressionValue::ExtendedExpression(expr) => {
98                Self::ExtendedExpression(ExtendedExpressionValue(format!("{expr:?}")))
99            }
100        }
101    }
102}
103
104/// Expression value of struct type. It's represent access to
105/// struct attributes of values with struct type
106#[derive(Debug, Clone, PartialEq, Eq)]
107#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
108pub struct ExpressionStructValue {
109    /// Value name for structure value
110    pub name: ValueName,
111    /// Value attribute for structure value
112    pub attribute: ValueName,
113}
114
115impl Display for ExpressionStructValue {
116    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117        write!(f, "{}", self.name)
118    }
119}
120
121impl From<ast::ExpressionStructValue<'_>> for ExpressionStructValue {
122    fn from(value: ast::ExpressionStructValue<'_>) -> Self {
123        Self {
124            name: value.name.into(),
125            attribute: value.attribute.into(),
126        }
127    }
128}
129
130/// Basic  expression operations - calculations and
131/// logic operations
132#[derive(Debug, Clone, PartialEq, Eq)]
133#[cfg_attr(
134    feature = "codec",
135    derive(Serialize, Deserialize),
136    serde(tag = "type", content = "content")
137)]
138pub enum ExpressionOperations {
139    Plus,
140    Minus,
141    Multiply,
142    Divide,
143    ShiftLeft,
144    ShiftRight,
145    And,
146    Or,
147    Xor,
148    Eq,
149    NotEq,
150    Great,
151    Less,
152    GreatEq,
153    LessEq,
154}
155
156impl From<ast::ExpressionOperations> for ExpressionOperations {
157    fn from(value: ast::ExpressionOperations) -> Self {
158        match value {
159            ast::ExpressionOperations::Plus => Self::Plus,
160            ast::ExpressionOperations::Minus => Self::Minus,
161            ast::ExpressionOperations::Multiply => Self::Multiply,
162            ast::ExpressionOperations::Divide => Self::Divide,
163            ast::ExpressionOperations::ShiftLeft => Self::ShiftLeft,
164            ast::ExpressionOperations::ShiftRight => Self::ShiftRight,
165            ast::ExpressionOperations::And => Self::And,
166            ast::ExpressionOperations::Or => Self::Or,
167            ast::ExpressionOperations::Xor => Self::Xor,
168            ast::ExpressionOperations::Eq => Self::Eq,
169            ast::ExpressionOperations::NotEq => Self::NotEq,
170            ast::ExpressionOperations::Great => Self::Great,
171            ast::ExpressionOperations::Less => Self::Less,
172            ast::ExpressionOperations::GreatEq => Self::GreatEq,
173            ast::ExpressionOperations::LessEq => Self::LessEq,
174        }
175    }
176}
177
178/// # Expression
179/// Basic expression entity representation. It contains
180/// `ExpressionValue` and optional operations with other
181/// expressions. So it's represent flat tree.
182#[derive(Debug, Clone, PartialEq)]
183#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
184pub struct Expression {
185    /// Expression value
186    pub expression_value: ExpressionValue,
187    /// Optional expression operation under other `Expression`
188    pub operation: Option<(ExpressionOperations, Box<Expression>)>,
189}
190
191impl Display for Expression {
192    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
193        write!(f, "{}", self.expression_value)
194    }
195}
196
197impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> From<ast::Expression<'_, I, E>>
198    for Expression
199{
200    fn from(value: ast::Expression<'_, I, E>) -> Self {
201        Self {
202            expression_value: value.expression_value.into(),
203            operation: value
204                .operation
205                .map(|(op, expr)| (op.into(), Box::new(expr.as_ref().clone().into()))),
206        }
207    }
208}