wafel_api/
data_type.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std::fmt;

use wafel_data_access::MemoryLayout;
use wafel_data_type::{DataTypeRef, FloatType, IntType};

use crate::Error;

/// A simplified description of a variable's data type.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DataType {
    /// Void, typically used as a pointer target or function return type.
    Void,
    /// An integer type.
    Int(IntType),
    /// A float type.
    Float(FloatType),
    /// A pointer type.
    Pointer,
    /// An array type.
    Array,
    /// A struct type.
    Struct,
    /// A union type.
    Union,
}

impl DataType {
    /// Return true if the data type is void.
    pub fn is_void(&self) -> bool {
        matches!(self, Self::Void)
    }

    /// Return true if the data type is an integer type.
    pub fn is_int(&self) -> bool {
        matches!(self, Self::Int(_))
    }

    /// Return true if the data type is a float type.
    pub fn is_float(&self) -> bool {
        matches!(self, Self::Float(_))
    }

    /// Return true if the data type is a pointer type.
    pub fn is_pointer(&self) -> bool {
        matches!(self, Self::Pointer)
    }

    /// Return true if the data type is an array type.
    pub fn is_array(&self) -> bool {
        matches!(self, Self::Array)
    }

    /// Return true if the data type is a struct type.
    pub fn is_struct(&self) -> bool {
        matches!(self, Self::Struct)
    }

    /// Return true if the data type is a union type.
    pub fn is_union(&self) -> bool {
        matches!(self, Self::Union)
    }
}

impl fmt::Display for DataType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            DataType::Void => write!(f, "void"),
            DataType::Int(int_type) => write!(f, "{}", int_type),
            DataType::Float(float_type) => write!(f, "{}", float_type),
            DataType::Pointer => write!(f, "pointer"),
            DataType::Array => write!(f, "array"),
            DataType::Struct => write!(f, "struct"),
            DataType::Union => write!(f, "union"),
        }
    }
}

pub(crate) fn simplified_data_type(
    layout: &impl MemoryLayout,
    data_type: &DataTypeRef,
) -> Result<DataType, Error> {
    use wafel_data_type::DataType::*;
    Ok(match data_type.as_ref() {
        Void => DataType::Void,
        Int(int_type) => DataType::Int(*int_type),
        Float(float_type) => DataType::Float(*float_type),
        Pointer { .. } => DataType::Pointer,
        Array { .. } => DataType::Array,
        Struct { .. } => DataType::Struct,
        Union { .. } => DataType::Union,
        Name(type_name) => {
            simplified_data_type(layout, layout.data_layout().data_type(type_name)?)?
        }
    })
}