#![allow(clippy::module_inception)]
pub mod block_state;
pub mod condition;
pub mod error;
pub mod expression;
pub mod semantic;
pub mod types;
use crate::ast;
use crate::ast::GetName;
use crate::types::condition::{IfStatement, LoopBodyStatement};
use crate::types::expression::{Expression, ExpressionOperations};
use crate::types::types::Type;
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
pub struct ValueName(String);
impl From<ast::ValueName<'_>> for ValueName {
fn from(value: ast::ValueName<'_>) -> Self {
Self(value.name())
}
}
impl From<String> for ValueName {
fn from(value: String) -> Self {
Self(value)
}
}
impl ToString for ValueName {
fn to_string(&self) -> String {
self.0.clone()
}
}
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
pub struct InnerValueName(String);
impl From<ValueName> for InnerValueName {
fn from(value: ValueName) -> Self {
Self(value.0)
}
}
impl From<String> for InnerValueName {
fn from(value: String) -> Self {
Self(value)
}
}
impl From<&str> for InnerValueName {
fn from(value: &str) -> Self {
Self(value.to_string())
}
}
impl ToString for InnerValueName {
fn to_string(&self) -> String {
self.0.clone()
}
}
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
pub struct LabelName(String);
impl From<String> for LabelName {
fn from(value: String) -> Self {
Self(value)
}
}
impl ToString for LabelName {
fn to_string(&self) -> String {
self.0.clone()
}
}
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
pub struct FunctionName(String);
impl From<String> for FunctionName {
fn from(value: String) -> Self {
Self(value)
}
}
impl From<ast::FunctionName<'_>> for FunctionName {
fn from(value: ast::FunctionName<'_>) -> Self {
Self(value.to_string())
}
}
impl ToString for FunctionName {
fn to_string(&self) -> String {
self.0.clone()
}
}
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
pub struct ConstantName(String);
impl From<ast::ConstantName<'_>> for ConstantName {
fn from(value: ast::ConstantName<'_>) -> Self {
Self(value.name())
}
}
impl From<String> for ConstantName {
fn from(value: String) -> Self {
Self(value)
}
}
impl ToString for ConstantName {
fn to_string(&self) -> String {
self.0.clone()
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ConstantValue {
Constant(ConstantName),
Value(PrimitiveValue),
}
impl From<ast::ConstantValue<'_>> for ConstantValue {
fn from(value: ast::ConstantValue<'_>) -> Self {
match value {
ast::ConstantValue::Constant(v) => Self::Constant(v.into()),
ast::ConstantValue::Value(v) => Self::Value(v.into()),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ConstantExpression {
pub value: ConstantValue,
pub operation: Option<(ExpressionOperations, Box<ConstantExpression>)>,
}
impl From<ast::ConstantExpression<'_>> for ConstantExpression {
fn from(value: ast::ConstantExpression<'_>) -> Self {
Self {
value: value.value.into(),
operation: value
.operation
.map(|(op, expr)| (op.into(), Box::new(expr.as_ref().clone().into()))),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Constant {
pub name: ConstantName,
pub constant_type: Type,
pub constant_value: ConstantExpression,
}
impl From<ast::Constant<'_>> for Constant {
fn from(value: ast::Constant<'_>) -> Self {
Self {
name: value.name.into(),
constant_type: value.constant_type.into(),
constant_value: value.constant_value.into(),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Value {
pub inner_name: InnerValueName,
pub inner_type: Type,
pub mutable: bool,
pub alloca: bool,
pub malloc: bool,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Function {
pub inner_name: FunctionName,
pub inner_type: Type,
pub parameters: Vec<Type>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParameterName(String);
impl From<ast::ParameterName<'_>> for ParameterName {
fn from(value: ast::ParameterName<'_>) -> Self {
Self(value.to_string())
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct FunctionParameter {
pub name: ParameterName,
pub parameter_type: Type,
}
impl From<ast::FunctionParameter<'_>> for FunctionParameter {
fn from(value: ast::FunctionParameter<'_>) -> Self {
Self {
name: value.name.into(),
parameter_type: value.parameter_type.into(),
}
}
}
impl ToString for FunctionParameter {
fn to_string(&self) -> String {
self.name.0.clone()
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct FunctionStatement {
pub name: FunctionName,
pub parameters: Vec<FunctionParameter>,
pub result_type: Type,
pub body: Vec<BodyStatement>,
}
impl From<ast::FunctionStatement<'_>> for FunctionStatement {
fn from(value: ast::FunctionStatement<'_>) -> Self {
Self {
name: value.name.into(),
parameters: value.parameters.iter().map(|v| v.clone().into()).collect(),
result_type: value.result_type.into(),
body: value.body.iter().map(|v| v.clone().into()).collect(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum BodyStatement {
LetBinding(LetBinding),
Binding(Binding),
FunctionCall(FunctionCall),
If(IfStatement),
Loop(Vec<LoopBodyStatement>),
Expression(Expression),
Return(Expression),
}
impl From<ast::BodyStatement<'_>> for BodyStatement {
fn from(value: ast::BodyStatement<'_>) -> Self {
match value {
ast::BodyStatement::LetBinding(v) => Self::LetBinding(v.into()),
ast::BodyStatement::Binding(v) => Self::Binding(v.into()),
ast::BodyStatement::FunctionCall(v) => Self::FunctionCall(v.into()),
ast::BodyStatement::If(v) => Self::If(v.into()),
ast::BodyStatement::Loop(v) => Self::Loop(v.iter().map(|v| v.clone().into()).collect()),
ast::BodyStatement::Expression(v) => Self::Expression(v.into()),
ast::BodyStatement::Return(v) => Self::Return(v.into()),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct LetBinding {
pub name: ValueName,
pub mutable: bool,
pub value_type: Option<Type>,
pub value: Box<Expression>,
}
impl ToString for LetBinding {
fn to_string(&self) -> String {
self.name.to_string()
}
}
impl From<ast::LetBinding<'_>> for LetBinding {
fn from(value: ast::LetBinding<'_>) -> Self {
Self {
name: value.name.into(),
mutable: value.mutable,
value_type: value.value_type.map(Into::into),
value: Box::new(value.value.as_ref().clone().into()),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum PrimitiveValue {
U8(u8),
U16(u16),
U32(u32),
U64(u64),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
F32(f32),
F64(f64),
Bool(bool),
String(String),
Char(char),
Ptr,
None,
}
impl From<ast::PrimitiveValue> for PrimitiveValue {
fn from(value: ast::PrimitiveValue) -> Self {
match value {
ast::PrimitiveValue::U8(v) => Self::U8(v),
ast::PrimitiveValue::U16(v) => Self::U16(v),
ast::PrimitiveValue::U32(v) => Self::U32(v),
ast::PrimitiveValue::U64(v) => Self::U64(v),
ast::PrimitiveValue::I8(v) => Self::I8(v),
ast::PrimitiveValue::I16(v) => Self::I16(v),
ast::PrimitiveValue::I32(v) => Self::I32(v),
ast::PrimitiveValue::I64(v) => Self::I64(v),
ast::PrimitiveValue::F32(v) => Self::F32(v),
ast::PrimitiveValue::F64(v) => Self::F64(v),
ast::PrimitiveValue::Bool(v) => Self::Bool(v),
ast::PrimitiveValue::String(v) => Self::String(v),
ast::PrimitiveValue::Char(v) => Self::Char(v),
ast::PrimitiveValue::Ptr => Self::Ptr,
ast::PrimitiveValue::None => Self::None,
}
}
}
impl ToString for PrimitiveValue {
fn to_string(&self) -> String {
match self {
Self::U8(val) => val.clone().to_string(),
Self::U16(val) => val.clone().to_string(),
Self::U32(val) => val.clone().to_string(),
Self::U64(val) => val.clone().to_string(),
Self::I8(val) => val.clone().to_string(),
Self::I16(val) => val.clone().to_string(),
Self::I32(val) => val.clone().to_string(),
Self::I64(val) => val.clone().to_string(),
Self::F32(val) => val.clone().to_string(),
Self::F64(val) => val.clone().to_string(),
Self::Bool(val) => val.to_string(),
Self::String(s) => s.clone(),
Self::Char(c) => format!("{}", c),
Self::Ptr => "ptr".to_string(),
Self::None => "None".to_string(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructValue {
pub name: ValueName,
pub attribute: ValueName,
}
impl ToString for StructValue {
fn to_string(&self) -> String {
self.name.to_string()
}
}
impl From<ast::StructValue<'_>> for StructValue {
fn from(value: ast::StructValue<'_>) -> Self {
Self {
name: value.name.into(),
attribute: value.attribute.into(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct FunctionCall {
pub name: FunctionName,
pub parameters: Vec<Expression>,
}
impl ToString for FunctionCall {
fn to_string(&self) -> String {
self.name.to_string()
}
}
impl From<ast::FunctionCall<'_>> for FunctionCall {
fn from(value: ast::FunctionCall<'_>) -> Self {
Self {
name: value.name.into(),
parameters: value.parameters.iter().map(|v| v.clone().into()).collect(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Binding {
pub name: ValueName,
pub value: Box<Expression>,
}
impl ToString for Binding {
fn to_string(&self) -> String {
self.name.to_string()
}
}
impl From<ast::Binding<'_>> for Binding {
fn from(value: ast::Binding<'_>) -> Self {
Self {
name: value.name.into(),
value: Box::new(value.value.as_ref().clone().into()),
}
}
}