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 Pointer(PointerValue),
42 Array(ArrayValue),
43 Struct(StructValue),
44 Function(FunctionValue),
46 Reference(ReferenceValue),
47 EnumVariant(EnumVariantValue),
48 Unit,
49}
50
51impl From<&str> for LLVMValue {
52 fn from(value: &str) -> Self {
53 let str = CString::new(value).unwrap();
54 let c = unsafe { LLVMConstString(str.as_ptr(), value.len() as c_uint, 0) };
55 LLVMValue::String(c)
56 }
57}
58
59impl From<LLVMValueRef> for LLVMValue {
60 fn from(value: LLVMValueRef) -> Self {
61 let ty = unsafe { LLVMTypeOf(value) };
62 let type_kind = unsafe { LLVMGetTypeKind(ty) };
63 match type_kind {
64 LLVMTypeKind::LLVMIntegerTypeKind => {
65 let width = unsafe { LLVMGetIntTypeWidth(ty) };
66 let width = width as i8;
67
68 match width {
69 1 => LLVMValue::Bool(BoolValue::new(value)),
70 8 => LLVMValue::Int8(Int8Value::new(value)),
71 16 => LLVMValue::Int16(Int16Value::new(value)),
72 32 => LLVMValue::Int32(Int32Value::new(value)),
73 64 => LLVMValue::Int64(Int64Value::new(value)),
74 _ => {
75 todo!()
76 }
77 }
78 }
79 LLVMTypeKind::LLVMDoubleTypeKind => LLVMValue::Double(DoubleValue::new(value)),
84 LLVMTypeKind::LLVMVoidTypeKind => LLVMValue::Unit,
85 LLVMTypeKind::LLVMFloatTypeKind => LLVMValue::Float(FloatValue::new(value)),
87 t => {
88 println!("{t:?}");
89 todo!()
90 }
91 }
92 }
93}
94
95impl From<ReferenceValue> for LLVMValue {
96 fn from(value: ReferenceValue) -> Self {
97 LLVMValue::Reference(value)
98 }
99}
100
101impl LLVMValue {
102 pub fn id(&self) -> i32 {
103 match self {
104 LLVMValue::Unit => 0,
105 LLVMValue::Bool(_) => 1,
106 LLVMValue::Int8(_) => 3,
107 LLVMValue::Int16(_) => 5,
108 LLVMValue::Int32(_) => 7,
109 LLVMValue::Int64(_) => 9,
110 LLVMValue::Float(_) => 11,
111 LLVMValue::Double(_) => 13,
112 LLVMValue::String(_) => 15,
113 t => {
114 panic!("Unknown type: {:?}", t)
115 }
116 }
117 }
118 pub fn as_llvm_value_ref(&self) -> LLVMValueRef {
119 unsafe {
120 match self {
121 LLVMValue::String(i) => *i,
122 LLVMValue::Float(i) => i.get_reference(),
123 LLVMValue::Double(i) => i.get_reference(),
124 LLVMValue::Int64(i) => i.get_reference(),
125 LLVMValue::Int32(i) => i.get_reference(),
126 LLVMValue::Int16(i) => i.get_reference(),
127 LLVMValue::Int8(i) => i.get_reference(),
128 LLVMValue::Bool(i) => i.get_reference(),
129 LLVMValue::Pointer(i) => i.get_reference(),
130 LLVMValue::Array(i) => i.get_reference(),
131 LLVMValue::Struct(i) => i.get_reference(),
132 LLVMValue::Reference(i) => i.get_reference(),
133 LLVMValue::Unit => LLVMGetUndef(LLVMVoidType()),
134 LLVMValue::Function(i) => i.get_reference(),
135 LLVMValue::EnumVariant(i) => i.get_reference(),
136 }
137 }
138 }
139 pub fn as_int32(&self) -> Option<&Int32Value> {
146 match self {
147 LLVMValue::Int32(v) => Some(v),
148 _ => None,
149 }
150 }
151 pub fn as_bool(&self) -> Option<&BoolValue> {
152 match self {
153 LLVMValue::Bool(v) => Some(v),
154 _ => None,
155 }
156 }
157 pub fn is_float(&self) -> bool {
158 matches!(self, LLVMValue::Float(_))
159 }
160 pub fn is_bool(&self) -> bool {
161 matches!(self, LLVMValue::Bool(_))
162 }
163 pub fn is_double(&self) -> bool {
164 matches!(self, LLVMValue::Double(_))
165 }
166 pub fn as_float(&self) -> Option<&FloatValue> {
167 match self {
168 LLVMValue::Float(v) => Some(v),
169 _ => None,
170 }
171 }
172 pub fn as_double(&self) -> Option<&DoubleValue> {
173 match self {
174 LLVMValue::Double(v) => Some(v),
175 _ => None,
176 }
177 }
178 pub fn as_reference(&self) -> Option<&ReferenceValue> {
179 match self {
180 LLVMValue::Reference(v) => Some(v),
181 _ => None,
182 }
183 }
184 pub fn as_array(&self) -> Option<&ArrayValue> {
185 match self {
186 LLVMValue::Array(v) => Some(v),
187 _ => None,
188 }
189 }
190 pub fn as_pointer(&self) -> Option<&PointerValue> {
191 match self {
192 LLVMValue::Pointer(v) => Some(v),
193 _ => None,
194 }
195 }
196 pub fn as_struct(&self) -> Option<&StructValue> {
197 match self {
198 LLVMValue::Struct(v) => Some(v),
199 _ => None,
200 }
201 }
202 pub fn into_struct(self) -> Option<StructValue> {
203 match self {
204 LLVMValue::Struct(v) => Some(v),
205 _ => None,
206 }
207 }
208 pub fn as_function(&self) -> Option<FunctionValue> {
209 match self {
210 LLVMValue::Function(v) => Some(v.clone()),
211 _ => None,
212 }
213 }
214 pub fn is_reference(&self) -> bool {
215 matches!(self, LLVMValue::Reference(_))
216 }
217 pub fn is_struct(&self) -> bool {
218 matches!(self, LLVMValue::Struct(_))
219 }
220 pub fn is_pointer(&self) -> bool {
221 matches!(self, LLVMValue::Pointer(_))
222 }
223 pub fn is_function(&self) -> bool {
224 matches!(self, LLVMValue::Function(_))
225 }
226 pub fn is_array(&self) -> bool {
227 matches!(self, LLVMValue::Array(_))
228 }
229 pub fn is_string(&self) -> bool {
230 matches!(self, LLVMValue::String(_))
231 }
232 pub fn get_llvm_type(&self, ctx: &Context) -> LLVMType {
233 let ty = unsafe { LLVMTypeOf(self.as_llvm_value_ref()) };
234 match self {
235 LLVMValue::Bool(_) => LLVMType::Int1(ty),
236 LLVMValue::Int8(_) => LLVMType::Int8(ty),
237 LLVMValue::Int16(_) => LLVMType::Int16(ty),
238 LLVMValue::Int32(_) => LLVMType::Int32(ty),
239 LLVMValue::Int64(_) => LLVMType::Int64(ty),
240 LLVMValue::Float(_) => LLVMType::Float(ty),
241 LLVMValue::Double(_) => LLVMType::Double(ty),
242 LLVMValue::Pointer(pointer_value) => pointer_value.get_llvm_type(ctx),
243 LLVMValue::Array(array) => LLVMType::Array(Box::new(array.get_element_type()), ty),
244 LLVMValue::Struct(struct_value) => struct_value.get_llvm_type(ctx),
245 LLVMValue::Unit => LLVMType::Unit(ty),
246 LLVMValue::String(_) => LLVMType::String(ty),
247 LLVMValue::Function(function_value) => function_value.get_llvm_type(ctx),
248 LLVMValue::Reference(reference_value) => reference_value.get_llvm_type(ctx),
249 LLVMValue::EnumVariant(enum_variant_value) => enum_variant_value.get_llvm_type(ctx),
250 }
251 }
252 pub fn is_unit(&self) -> bool {
253 matches!(self, LLVMValue::Unit)
254 }
255 pub fn is_undef(&self) -> bool {
256 match self {
257 LLVMValue::Bool(v) => v.is_undef(),
258 LLVMValue::Int8(v) => v.is_undef(),
259 LLVMValue::Int16(v) => v.is_undef(),
260 LLVMValue::Int32(v) => v.is_undef(),
261 LLVMValue::Int64(v) => v.is_undef(),
262 LLVMValue::Float(v) => v.is_undef(),
263 LLVMValue::Double(v) => v.is_undef(),
264 LLVMValue::Pointer(v) => v.is_undef(),
265 LLVMValue::Reference(v) => v.is_undef(),
266 LLVMValue::Struct(v) => v.is_undef(),
267 LLVMValue::Array(v) => v.is_undef(),
268 LLVMValue::EnumVariant(v) => v.is_undef(),
269 LLVMValue::Function(v) => v.is_undef(),
270 LLVMValue::Unit => false,
271 LLVMValue::String(_) => false,
272 }
273 }
274}