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_double(&self) -> bool {
161 matches!(self, LLVMValue::Double(_))
162 }
163 pub fn as_float(&self) -> Option<&FloatValue> {
164 match self {
165 LLVMValue::Float(v) => Some(v),
166 _ => None,
167 }
168 }
169 pub fn as_double(&self) -> Option<&DoubleValue> {
170 match self {
171 LLVMValue::Double(v) => Some(v),
172 _ => None,
173 }
174 }
175 pub fn as_reference(&self) -> Option<&ReferenceValue> {
176 match self {
177 LLVMValue::Reference(v) => Some(v),
178 _ => None,
179 }
180 }
181 pub fn as_array(&self) -> Option<&ArrayValue> {
182 match self {
183 LLVMValue::Array(v) => Some(v),
184 _ => None,
185 }
186 }
187 pub fn as_pointer(&self) -> Option<&PointerValue> {
188 match self {
189 LLVMValue::Pointer(v) => Some(v),
190 _ => None,
191 }
192 }
193 pub fn as_struct(&self) -> Option<&StructValue> {
194 match self {
195 LLVMValue::Struct(v) => Some(v),
196 _ => None,
197 }
198 }
199 pub fn as_function(&self) -> Option<FunctionValue> {
200 match self {
201 LLVMValue::Function(v) => Some(v.clone()),
202 _ => None,
203 }
204 }
205 pub fn is_reference(&self) -> bool {
206 matches!(self, LLVMValue::Reference(_))
207 }
208 pub fn is_struct(&self) -> bool {
209 matches!(self, LLVMValue::Struct(_))
210 }
211 pub fn is_pointer(&self) -> bool {
212 matches!(self, LLVMValue::Pointer(_))
213 }
214 pub fn is_function(&self) -> bool {
215 matches!(self, LLVMValue::Function(_))
216 }
217 pub fn is_array(&self) -> bool {
218 matches!(self, LLVMValue::Array(_))
219 }
220 pub fn get_llvm_type(&self, ctx: &Context) -> LLVMType {
221 let ty = unsafe { LLVMTypeOf(self.as_llvm_value_ref()) };
222 match self {
223 LLVMValue::Bool(_) => LLVMType::Int1(ty),
224 LLVMValue::Int8(_) => LLVMType::Int8(ty),
225 LLVMValue::Int16(_) => LLVMType::Int16(ty),
226 LLVMValue::Int32(_) => LLVMType::Int32(ty),
227 LLVMValue::Int64(_) => LLVMType::Int64(ty),
228 LLVMValue::Float(_) => LLVMType::Float(ty),
229 LLVMValue::Double(_) => LLVMType::Double(ty),
230 LLVMValue::Pointer(pointer_value) => pointer_value.get_llvm_type(ctx),
231 LLVMValue::Array(array) => LLVMType::Array(Box::new(array.get_element_type()), ty),
232 LLVMValue::Struct(struct_value) => struct_value.get_llvm_type(ctx),
233 LLVMValue::Unit => LLVMType::Unit(ty),
234 LLVMValue::String(_) => LLVMType::String(ty),
235 LLVMValue::Function(function_value) => function_value.get_llvm_type(ctx),
236 LLVMValue::Reference(reference_value) => reference_value.get_llvm_type(ctx),
237 LLVMValue::EnumVariant(enum_variant_value) => enum_variant_value.get_llvm_type(ctx),
238 }
239 }
240 pub fn is_unit(&self) -> bool {
241 matches!(self, LLVMValue::Unit)
242 }
243 pub fn is_undef(&self) -> bool {
244 match self {
245 LLVMValue::Bool(v) => v.is_undef(),
246 LLVMValue::Int8(v) => v.is_undef(),
247 LLVMValue::Int16(v) => v.is_undef(),
248 LLVMValue::Int32(v) => v.is_undef(),
249 LLVMValue::Int64(v) => v.is_undef(),
250 LLVMValue::Float(v) => v.is_undef(),
251 LLVMValue::Double(v) => v.is_undef(),
252 LLVMValue::Pointer(v) => v.is_undef(),
253 LLVMValue::Reference(v) => v.is_undef(),
254 LLVMValue::Struct(v) => v.is_undef(),
255 LLVMValue::Array(v) => v.is_undef(),
256 LLVMValue::EnumVariant(v) => v.is_undef(),
257 LLVMValue::Function(v) => v.is_undef(),
258 LLVMValue::Unit => false,
259 LLVMValue::String(_) => false,
260 }
261 }
262}