pipeline_script/llvm/value/
mod.rs1pub 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 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::LLVMDoubleTypeKind => LLVMValue::Double(DoubleValue::new(value)),
86 LLVMTypeKind::LLVMVoidTypeKind => LLVMValue::Unit,
87 LLVMTypeKind::LLVMFloatTypeKind => LLVMValue::Float(FloatValue::new(value)),
89 LLVMTypeKind::LLVMPointerTypeKind => {
90 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_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}