pipeline_script/llvm/value/
mod.rs

1pub mod array;
2pub mod bool;
3pub mod double;
4pub mod float;
5pub mod fucntion;
6pub mod int;
7pub mod penum;
8pub mod pointer;
9pub mod pstruct;
10pub mod reference;
11
12use crate::context::Context;
13use crate::llvm::types::LLVMType;
14use crate::llvm::value::array::ArrayValue;
15use crate::llvm::value::bool::BoolValue;
16use crate::llvm::value::double::DoubleValue;
17use crate::llvm::value::float::FloatValue;
18use crate::llvm::value::fucntion::FunctionValue;
19use crate::llvm::value::int::{Int16Value, Int32Value, Int64Value, Int8Value};
20use crate::llvm::value::penum::EnumVariantValue;
21use crate::llvm::value::pointer::PointerValue;
22use crate::llvm::value::pstruct::StructValue;
23use crate::llvm::value::reference::ReferenceValue;
24use llvm_sys::core::{
25    LLVMConstString, LLVMGetIntTypeWidth, LLVMGetTypeKind, LLVMGetUndef, LLVMTypeOf, LLVMVoidType,
26};
27use llvm_sys::prelude::LLVMValueRef;
28use llvm_sys::LLVMTypeKind;
29use std::ffi::{c_uint, CString};
30
31#[derive(Clone, Debug)]
32pub enum LLVMValue {
33    String(LLVMValueRef),
34    Bool(BoolValue),
35    Int8(Int8Value),
36    Int16(Int16Value),
37    Int32(Int32Value),
38    Int64(Int64Value),
39    Float(FloatValue),
40    Double(DoubleValue),
41    Inject(Box<LLVMValue>),
42    Pointer(PointerValue),
43    Array(ArrayValue),
44    Struct(StructValue),
45    // Undef(LLVMValueRef),
46    Function(FunctionValue),
47    Reference(ReferenceValue),
48    EnumVariant(EnumVariantValue),
49    Unit,
50}
51
52impl From<&str> for LLVMValue {
53    fn from(value: &str) -> Self {
54        let str = CString::new(value).unwrap();
55        let c = unsafe { LLVMConstString(str.as_ptr(), value.len() as c_uint, 0) };
56        LLVMValue::String(c)
57    }
58}
59
60impl From<LLVMValueRef> for LLVMValue {
61    #[allow(clippy::not_unsafe_ptr_arg_deref)]
62    fn from(value: LLVMValueRef) -> Self {
63        let ty = unsafe { LLVMTypeOf(value) };
64        let type_kind = unsafe { LLVMGetTypeKind(ty) };
65        match type_kind {
66            LLVMTypeKind::LLVMIntegerTypeKind => {
67                let width = unsafe { LLVMGetIntTypeWidth(ty) };
68                let width = width as i8;
69
70                match width {
71                    1 => LLVMValue::Bool(BoolValue::new(value)),
72                    8 => LLVMValue::Int8(Int8Value::new(value)),
73                    16 => LLVMValue::Int16(Int16Value::new(value)),
74                    32 => LLVMValue::Int32(Int32Value::new(value)),
75                    64 => LLVMValue::Int64(Int64Value::new(value)),
76                    _ => {
77                        todo!()
78                    }
79                }
80            }
81            // LLVMTypeKind::LLVMPointerTypeKind => {
82            //     LLVMValue::Pointer(PointerValue::new(value, LLVMGetUndef(ty)))
83            // }
84            // LLVMTypeKind::LLVMArrayTypeKind => LLVMValue::Array(value),
85            LLVMTypeKind::LLVMDoubleTypeKind => LLVMValue::Double(DoubleValue::new(value)),
86            LLVMTypeKind::LLVMVoidTypeKind => LLVMValue::Unit,
87            // LLVMTypeKind::LLVMStructTypeKind => LLVMValue::Struct(StructValue::new(value, UNNAMED.into(), HashMap::new(), ty)),
88            LLVMTypeKind::LLVMFloatTypeKind => LLVMValue::Float(FloatValue::new(value)),
89            LLVMTypeKind::LLVMPointerTypeKind => {
90                // 指针类型,通常用于字符串
91                LLVMValue::String(value)
92            },
93            t => {
94                println!("{t:?}");
95                todo!()
96            }
97        }
98    }
99}
100
101impl From<ReferenceValue> for LLVMValue {
102    fn from(value: ReferenceValue) -> Self {
103        LLVMValue::Reference(value)
104    }
105}
106
107impl LLVMValue {
108    pub fn id(&self) -> i32 {
109        match self {
110            LLVMValue::Unit => 0,
111            LLVMValue::Bool(_) => 1,
112            LLVMValue::Int8(_) => 3,
113            LLVMValue::Int16(_) => 5,
114            LLVMValue::Int32(_) => 7,
115            LLVMValue::Int64(_) => 9,
116            LLVMValue::Float(_) => 11,
117            LLVMValue::Double(_) => 13,
118            LLVMValue::String(_) => 15,
119            LLVMValue::Pointer(_) => 18,
120            LLVMValue::Array(_) => 20,
121            LLVMValue::Struct(_) => 19,
122            LLVMValue::Function(_) => 21,
123            LLVMValue::Reference(_) => 18,
124            LLVMValue::EnumVariant(_) => 23,
125            LLVMValue::Inject(inner) => inner.id(),
126        }
127    }
128    pub fn is_inject(&self)->bool{
129        matches!(self,LLVMValue::Inject(_))
130    }
131    pub fn as_llvm_value_ref(&self) -> LLVMValueRef {
132        unsafe {
133            match self {
134                LLVMValue::String(i) => *i,
135                LLVMValue::Float(i) => i.get_reference(),
136                LLVMValue::Double(i) => i.get_reference(),
137                LLVMValue::Int64(i) => i.get_reference(),
138                LLVMValue::Int32(i) => i.get_reference(),
139                LLVMValue::Int16(i) => i.get_reference(),
140                LLVMValue::Int8(i) => i.get_reference(),
141                LLVMValue::Bool(i) => i.get_reference(),
142                LLVMValue::Pointer(i) => i.get_reference(),
143                LLVMValue::Array(i) => i.get_reference(),
144                LLVMValue::Struct(i) => i.get_reference(),
145                LLVMValue::Reference(i) => i.get_reference(),
146                LLVMValue::Unit => LLVMGetUndef(LLVMVoidType()),
147                LLVMValue::Function(i) => i.get_reference(),
148                LLVMValue::EnumVariant(i) => i.get_reference(),
149                LLVMValue::Inject(i) => i.as_llvm_value_ref(),
150            }
151        }
152    }
153    // pub fn as_enum_variant(&self) -> Option<&EnumVariantValue> {
154    //     match self {
155    //         LLVMValue::EnumVariant(v) => Some(v),
156    //         _ => None,
157    //     }
158    // }
159    pub fn as_int32(&self) -> Option<&Int32Value> {
160        match self {
161            LLVMValue::Int32(v) => Some(v),
162            _ => None,
163        }
164    }
165    pub fn as_bool(&self) -> Option<&BoolValue> {
166        match self {
167            LLVMValue::Bool(v) => Some(v),
168            _ => None,
169        }
170    }
171    pub fn is_float(&self) -> bool {
172        matches!(self, LLVMValue::Float(_))
173    }
174    pub fn is_bool(&self) -> bool {
175        matches!(self, LLVMValue::Bool(_))
176    }
177    pub fn is_double(&self) -> bool {
178        matches!(self, LLVMValue::Double(_))
179    }
180    pub fn as_float(&self) -> Option<&FloatValue> {
181        match self {
182            LLVMValue::Float(v) => Some(v),
183            _ => None,
184        }
185    }
186    pub fn as_double(&self) -> Option<&DoubleValue> {
187        match self {
188            LLVMValue::Double(v) => Some(v),
189            _ => None,
190        }
191    }
192    pub fn as_reference(&self) -> Option<&ReferenceValue> {
193        match self {
194            LLVMValue::Reference(v) => Some(v),
195            _ => None,
196        }
197    }
198    pub fn as_array(&self) -> Option<&ArrayValue> {
199        match self {
200            LLVMValue::Array(v) => Some(v),
201            _ => None,
202        }
203    }
204    pub fn as_pointer(&self) -> Option<&PointerValue> {
205        match self {
206            LLVMValue::Pointer(v) => Some(v),
207            _ => None,
208        }
209    }
210    pub fn as_struct(&self) -> Option<&StructValue> {
211        match self {
212            LLVMValue::Struct(v) => Some(v),
213            _ => None,
214        }
215    }
216    pub fn into_struct(self) -> Option<StructValue> {
217        match self {
218            LLVMValue::Struct(v) => Some(v),
219            _ => None,
220        }
221    }
222    pub fn as_function(&self) -> Option<FunctionValue> {
223        match self {
224            LLVMValue::Function(v) => Some(v.clone()),
225            _ => None,
226        }
227    }
228    pub fn is_reference(&self) -> bool {
229        matches!(self, LLVMValue::Reference(_))
230    }
231    pub fn is_struct(&self) -> bool {
232        matches!(self, LLVMValue::Struct(_))
233    }
234    pub fn is_pointer(&self) -> bool {
235        matches!(self, LLVMValue::Pointer(_))
236    }
237    pub fn is_function(&self) -> bool {
238        matches!(self, LLVMValue::Function(_))
239    }
240    pub fn is_array(&self) -> bool {
241        matches!(self, LLVMValue::Array(_))
242    }
243    pub fn is_string(&self) -> bool {
244        matches!(self, LLVMValue::String(_))
245    }
246    pub fn get_llvm_type(&self, ctx: &Context) -> LLVMType {
247        let ty = unsafe { LLVMTypeOf(self.as_llvm_value_ref()) };
248        match self {
249            LLVMValue::Bool(_) => LLVMType::Int1(ty),
250            LLVMValue::Int8(_) => LLVMType::Int8(ty),
251            LLVMValue::Int16(_) => LLVMType::Int16(ty),
252            LLVMValue::Int32(_) => LLVMType::Int32(ty),
253            LLVMValue::Int64(_) => LLVMType::Int64(ty),
254            LLVMValue::Float(_) => LLVMType::Float(ty),
255            LLVMValue::Double(_) => LLVMType::Double(ty),
256            LLVMValue::Pointer(pointer_value) => pointer_value.get_llvm_type(ctx),
257            LLVMValue::Array(array) => LLVMType::Array(Box::new(array.get_element_type()), ty),
258            LLVMValue::Struct(struct_value) => struct_value.get_llvm_type(ctx),
259            LLVMValue::Unit => LLVMType::Unit(ty),
260            LLVMValue::String(_) => LLVMType::String(ty),
261            LLVMValue::Function(function_value) => function_value.get_llvm_type(ctx),
262            LLVMValue::Reference(reference_value) => reference_value.get_llvm_type(ctx),
263            LLVMValue::EnumVariant(enum_variant_value) => enum_variant_value.get_llvm_type(ctx),
264            LLVMValue::Inject(i) => i.get_llvm_type(ctx),
265        }
266    }
267    pub fn is_unit(&self) -> bool {
268        matches!(self, LLVMValue::Unit)
269    }
270    pub fn is_undef(&self) -> bool {
271        match self {
272            LLVMValue::Bool(v) => v.is_undef(),
273            LLVMValue::Int8(v) => v.is_undef(),
274            LLVMValue::Int16(v) => v.is_undef(),
275            LLVMValue::Int32(v) => v.is_undef(),
276            LLVMValue::Int64(v) => v.is_undef(),
277            LLVMValue::Float(v) => v.is_undef(),
278            LLVMValue::Double(v) => v.is_undef(),
279            LLVMValue::Pointer(v) => v.is_undef(),
280            LLVMValue::Reference(v) => v.is_undef(),
281            LLVMValue::Struct(v) => v.is_undef(),
282            LLVMValue::Array(v) => v.is_undef(),
283            LLVMValue::EnumVariant(v) => v.is_undef(),
284            LLVMValue::Function(v) => v.is_undef(),
285            LLVMValue::Unit => false,
286            LLVMValue::String(_) => false,
287            LLVMValue::Inject(i) => i.is_undef(),
288        }
289    }
290}