use super::types::Type;
use super::{FunctionCall, PrimitiveValue, ValueName};
use crate::ast;
use crate::types::semantic::ExtendedExpression;
#[cfg(feature = "codec")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
pub struct ExpressionResult {
pub expr_type: Type,
pub expr_value: ExpressionResultValue,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(
feature = "codec",
derive(Serialize, Deserialize),
serde(tag = "type", content = "content")
)]
pub enum ExpressionResultValue {
PrimitiveValue(PrimitiveValue),
Register(u64),
}
#[derive(Debug, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
pub struct ExtendedExpressionValue(String);
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(
feature = "codec",
derive(Serialize, Deserialize),
serde(tag = "type", content = "content")
)]
pub enum ExpressionValue {
ValueName(ValueName),
PrimitiveValue(PrimitiveValue),
StructValue(ExpressionStructValue),
FunctionCall(FunctionCall),
Expression(Box<Expression>),
ExtendedExpression(ExtendedExpressionValue),
}
impl ToString for ExpressionValue {
fn to_string(&self) -> String {
match self {
Self::ValueName(val) => val.clone().to_string(),
Self::PrimitiveValue(val) => val.clone().to_string(),
Self::StructValue(st_val) => st_val.clone().to_string(),
Self::FunctionCall(fn_call) => fn_call.clone().to_string(),
Self::Expression(val) => val.to_string(),
Self::ExtendedExpression(val) => val.clone().0,
}
}
}
impl<E: ExtendedExpression> From<ast::ExpressionValue<'_, E>> for ExpressionValue {
fn from(value: ast::ExpressionValue<'_, E>) -> Self {
match value {
ast::ExpressionValue::ValueName(v) => Self::ValueName(v.into()),
ast::ExpressionValue::PrimitiveValue(v) => Self::PrimitiveValue(v.into()),
ast::ExpressionValue::StructValue(v) => Self::StructValue(v.into()),
ast::ExpressionValue::FunctionCall(v) => Self::FunctionCall(v.into()),
ast::ExpressionValue::Expression(v) => {
Self::Expression(Box::new(v.as_ref().clone().into()))
}
ast::ExpressionValue::ExtendedExpression(expr) => {
Self::ExtendedExpression(ExtendedExpressionValue(format!("{expr:?}")))
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
pub struct ExpressionStructValue {
pub name: ValueName,
pub attribute: ValueName,
}
impl ToString for ExpressionStructValue {
fn to_string(&self) -> String {
self.name.to_string()
}
}
impl From<ast::ExpressionStructValue<'_>> for ExpressionStructValue {
fn from(value: ast::ExpressionStructValue<'_>) -> Self {
Self {
name: value.name.into(),
attribute: value.attribute.into(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "codec",
derive(Serialize, Deserialize),
serde(tag = "type", content = "content")
)]
pub enum ExpressionOperations {
Plus,
Minus,
Multiply,
Divide,
ShiftLeft,
ShiftRight,
And,
Or,
Xor,
Eq,
NotEq,
Great,
Less,
GreatEq,
LessEq,
}
impl From<ast::ExpressionOperations> for ExpressionOperations {
fn from(value: ast::ExpressionOperations) -> Self {
match value {
ast::ExpressionOperations::Plus => Self::Plus,
ast::ExpressionOperations::Minus => Self::Minus,
ast::ExpressionOperations::Multiply => Self::Multiply,
ast::ExpressionOperations::Divide => Self::Divide,
ast::ExpressionOperations::ShiftLeft => Self::ShiftLeft,
ast::ExpressionOperations::ShiftRight => Self::ShiftRight,
ast::ExpressionOperations::And => Self::And,
ast::ExpressionOperations::Or => Self::Or,
ast::ExpressionOperations::Xor => Self::Xor,
ast::ExpressionOperations::Eq => Self::Eq,
ast::ExpressionOperations::NotEq => Self::NotEq,
ast::ExpressionOperations::Great => Self::Great,
ast::ExpressionOperations::Less => Self::Less,
ast::ExpressionOperations::GreatEq => Self::GreatEq,
ast::ExpressionOperations::LessEq => Self::LessEq,
}
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
pub struct Expression {
pub expression_value: ExpressionValue,
pub operation: Option<(ExpressionOperations, Box<Expression>)>,
}
impl ToString for Expression {
fn to_string(&self) -> String {
self.expression_value.to_string()
}
}
impl<E: ExtendedExpression> From<ast::Expression<'_, E>> for Expression {
fn from(value: ast::Expression<'_, E>) -> Self {
Self {
expression_value: value.expression_value.into(),
operation: value
.operation
.map(|(op, expr)| (op.into(), Box::new(expr.as_ref().clone().into()))),
}
}
}