[core] codegen: Implement StructProxy on existing proxies
This commit is contained in:
parent
0ff99f4677
commit
acd5e382c0
@ -1431,7 +1431,7 @@ fn polymorphic_print<'ctx>(
|
||||
fmt.push_str("range(");
|
||||
flush(ctx, generator, &mut fmt, &mut args);
|
||||
|
||||
let val = RangeType::new(ctx).map_value(value.into_pointer_value(), None);
|
||||
let val = RangeType::new(ctx).map_pointer_value(value.into_pointer_value(), None);
|
||||
|
||||
let (start, stop, step) = destructure_range(ctx, val);
|
||||
|
||||
|
@ -47,14 +47,14 @@ pub fn call_len<'ctx, G: CodeGenerator + ?Sized>(
|
||||
let range_ty = ctx.primitives.range;
|
||||
|
||||
Ok(if ctx.unifier.unioned(arg_ty, range_ty) {
|
||||
let arg = RangeType::new(ctx).map_value(arg.into_pointer_value(), Some("range"));
|
||||
let arg = RangeType::new(ctx).map_pointer_value(arg.into_pointer_value(), Some("range"));
|
||||
let (start, end, step) = destructure_range(ctx, arg);
|
||||
calculate_len_for_slice_range(generator, ctx, start, end, step)
|
||||
} else {
|
||||
match &*ctx.unifier.get_ty_immutable(arg_ty) {
|
||||
TypeEnum::TTuple { .. } => {
|
||||
let tuple = TupleType::from_unifier_type(generator, ctx, arg_ty)
|
||||
.map_value(arg.into_struct_value(), None);
|
||||
.map_struct_value(arg.into_struct_value(), None);
|
||||
llvm_i32.const_int(tuple.get_type().num_elements().into(), false)
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ pub fn call_len<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if *obj_id == ctx.primitives.list.obj_id(&ctx.unifier).unwrap() =>
|
||||
{
|
||||
let list = ListType::from_unifier_type(generator, ctx, arg_ty)
|
||||
.map_value(arg.into_pointer_value(), None);
|
||||
.map_pointer_value(arg.into_pointer_value(), None);
|
||||
ctx.builder
|
||||
.build_int_truncate_or_bit_cast(list.load_size(ctx, None), llvm_i32, "len")
|
||||
.unwrap()
|
||||
|
@ -1151,7 +1151,7 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
|
||||
if *obj_id == ctx.primitives.range.obj_id(&ctx.unifier).unwrap() =>
|
||||
{
|
||||
let iter_val =
|
||||
RangeType::new(ctx).map_value(iter_val.into_pointer_value(), Some("range"));
|
||||
RangeType::new(ctx).map_pointer_value(iter_val.into_pointer_value(), Some("range"));
|
||||
let (start, stop, step) = destructure_range(ctx, iter_val);
|
||||
let diff = ctx.builder.build_int_sub(stop, start, "diff").unwrap();
|
||||
// add 1 to the length as the value is rounded to zero
|
||||
|
@ -511,7 +511,7 @@ pub fn gen_for<G: CodeGenerator>(
|
||||
if *obj_id == ctx.primitives.range.obj_id(&ctx.unifier).unwrap() =>
|
||||
{
|
||||
let iter_val =
|
||||
RangeType::new(ctx).map_value(iter_val.into_pointer_value(), Some("range"));
|
||||
RangeType::new(ctx).map_pointer_value(iter_val.into_pointer_value(), Some("range"));
|
||||
// Internal variable for loop; Cannot be assigned
|
||||
let i = generator.gen_var_alloc(ctx, int32.into(), Some("for.i.addr"))?;
|
||||
// Variable declared in "target" expression of the loop; Can be reassigned *or* shadowed
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::{AsContextRef, Context},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{IntValue, PointerValue},
|
||||
context::Context,
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
AddressSpace, IntPredicate, OptimizationLevel,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -13,8 +13,9 @@ use crate::{
|
||||
codegen::{
|
||||
types::structure::{
|
||||
check_struct_type_matches_fields, FieldIndexCounter, StructField, StructFields,
|
||||
StructProxyType,
|
||||
},
|
||||
values::{ListValue, ProxyValue},
|
||||
values::ListValue,
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
typecheck::typedef::{iter_type_vars, Type, TypeEnum},
|
||||
@ -62,13 +63,6 @@ impl<'ctx> ListType<'ctx> {
|
||||
ListStructFields::new_typed(item, llvm_usize)
|
||||
}
|
||||
|
||||
/// See [`ListType::fields`].
|
||||
// TODO: Move this into e.g. StructProxyType
|
||||
#[must_use]
|
||||
pub fn get_fields(&self, _ctx: &impl AsContextRef<'ctx>) -> ListStructFields<'ctx> {
|
||||
Self::fields(self.item.unwrap_or(self.llvm_usize.into()), self.llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of a `List`.
|
||||
#[must_use]
|
||||
fn llvm_type(
|
||||
@ -153,9 +147,15 @@ impl<'ctx> ListType<'ctx> {
|
||||
Self::new_impl(ctx.ctx, llvm_elem_type, llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`ListType`] from a [`StructType`].
|
||||
#[must_use]
|
||||
pub fn from_struct_type(ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`ListType`] from a [`PointerType`].
|
||||
#[must_use]
|
||||
pub fn from_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
let ctx = ptr_ty.get_context();
|
||||
@ -295,9 +295,27 @@ impl<'ctx> ListType<'ctx> {
|
||||
|
||||
/// Converts an existing value into a [`ListValue`].
|
||||
#[must_use]
|
||||
pub fn map_value(
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`ListValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(value, self.llvm_usize, name)
|
||||
@ -357,6 +375,14 @@ impl<'ctx> ProxyType<'ctx> for ListType<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for ListType<'ctx> {
|
||||
type StructFields = ListStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
Self::fields(self.item.unwrap_or(self.llvm_usize.into()), self.llvm_usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<ListType<'ctx>> for PointerType<'ctx> {
|
||||
fn from(value: ListType<'ctx>) -> Self {
|
||||
value.as_base_type()
|
||||
|
@ -222,7 +222,7 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||
if *obj_id == ctx.primitives.list.obj_id(&ctx.unifier).unwrap() =>
|
||||
{
|
||||
let list = ListType::from_unifier_type(generator, ctx, object_ty)
|
||||
.map_value(object.into_pointer_value(), None);
|
||||
.map_pointer_value(object.into_pointer_value(), None);
|
||||
self.construct_numpy_array_list_impl(generator, ctx, (object_ty, list), copy, name)
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::{AsContextRef, Context},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{IntValue, PointerValue},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -10,10 +10,10 @@ use nac3core_derive::StructFields;
|
||||
|
||||
use crate::codegen::{
|
||||
types::{
|
||||
structure::{check_struct_type_matches_fields, StructField, StructFields},
|
||||
structure::{check_struct_type_matches_fields, StructField, StructFields, StructProxyType},
|
||||
ProxyType,
|
||||
},
|
||||
values::{ndarray::ShapeEntryValue, ProxyValue},
|
||||
values::ndarray::ShapeEntryValue,
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
|
||||
@ -41,13 +41,6 @@ impl<'ctx> ShapeEntryType<'ctx> {
|
||||
ShapeEntryStructFields::new(ctx, llvm_usize)
|
||||
}
|
||||
|
||||
/// See [`ShapeEntryStructFields::fields`].
|
||||
// TODO: Move this into e.g. StructProxyType
|
||||
#[must_use]
|
||||
pub fn get_fields(&self, ctx: impl AsContextRef<'ctx>) -> ShapeEntryStructFields<'ctx> {
|
||||
Self::fields(ctx, self.llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of a `ShapeEntry`.
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context, llvm_usize: IntType<'ctx>) -> PointerType<'ctx> {
|
||||
@ -78,9 +71,15 @@ impl<'ctx> ShapeEntryType<'ctx> {
|
||||
Self::new_impl(ctx, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
/// Creates a [`ShapeEntryType`] from a [`StructType`] representing an `ShapeEntry`.
|
||||
#[must_use]
|
||||
pub fn from_struct_type(ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates a [`ShapeEntryType`] from a [`PointerType`] representing an `ShapeEntry`.
|
||||
#[must_use]
|
||||
pub fn from_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
Self { ty: ptr_ty, llvm_usize }
|
||||
@ -117,9 +116,27 @@ impl<'ctx> ShapeEntryType<'ctx> {
|
||||
|
||||
/// Converts an existing value into a [`ShapeEntryValue`].
|
||||
#[must_use]
|
||||
pub fn map_value(
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`ShapeEntryValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(value, self.llvm_usize, name)
|
||||
@ -173,6 +190,14 @@ impl<'ctx> ProxyType<'ctx> for ShapeEntryType<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for ShapeEntryType<'ctx> {
|
||||
type StructFields = ShapeEntryStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
Self::fields(self.ty.get_context(), self.llvm_usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<ShapeEntryType<'ctx>> for PointerType<'ctx> {
|
||||
fn from(value: ShapeEntryType<'ctx>) -> Self {
|
||||
value.as_base_type()
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::Context,
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{IntValue, PointerValue},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -13,10 +13,11 @@ use crate::{
|
||||
types::{
|
||||
structure::{
|
||||
check_struct_type_matches_fields, FieldIndexCounter, StructField, StructFields,
|
||||
StructProxyType,
|
||||
},
|
||||
ProxyType,
|
||||
},
|
||||
values::{ndarray::ContiguousNDArrayValue, ProxyValue},
|
||||
values::ndarray::ContiguousNDArrayValue,
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
toplevel::numpy::unpack_ndarray_var_tys,
|
||||
@ -67,13 +68,6 @@ impl<'ctx> ContiguousNDArrayType<'ctx> {
|
||||
ContiguousNDArrayStructFields::new_typed(item, llvm_usize)
|
||||
}
|
||||
|
||||
/// See [`NDArrayType::fields`].
|
||||
// TODO: Move this into e.g. StructProxyType
|
||||
#[must_use]
|
||||
pub fn get_fields(&self) -> ContiguousNDArrayStructFields<'ctx> {
|
||||
Self::fields(self.item, self.llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of an `NDArray`.
|
||||
#[must_use]
|
||||
fn llvm_type(
|
||||
@ -123,9 +117,19 @@ impl<'ctx> ContiguousNDArrayType<'ctx> {
|
||||
Self::new_impl(ctx.ctx, llvm_dtype, ctx.get_size_type())
|
||||
}
|
||||
|
||||
/// Creates an [`ContiguousNDArrayType`] from a [`StructType`] representing an `NDArray`.
|
||||
#[must_use]
|
||||
pub fn from_struct_type(
|
||||
ty: StructType<'ctx>,
|
||||
item: BasicTypeEnum<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), item, llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`ContiguousNDArrayType`] from a [`PointerType`] representing an `NDArray`.
|
||||
#[must_use]
|
||||
pub fn from_type(
|
||||
pub fn from_pointer_type(
|
||||
ptr_ty: PointerType<'ctx>,
|
||||
item: BasicTypeEnum<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
@ -174,9 +178,28 @@ impl<'ctx> ContiguousNDArrayType<'ctx> {
|
||||
|
||||
/// Converts an existing value into a [`ContiguousNDArrayValue`].
|
||||
#[must_use]
|
||||
pub fn map_value(
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.item,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`ContiguousNDArrayValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||
@ -243,6 +266,14 @@ impl<'ctx> ProxyType<'ctx> for ContiguousNDArrayType<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for ContiguousNDArrayType<'ctx> {
|
||||
type StructFields = ContiguousNDArrayStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
Self::fields(self.item, self.llvm_usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<ContiguousNDArrayType<'ctx>> for PointerType<'ctx> {
|
||||
fn from(value: ContiguousNDArrayType<'ctx>) -> Self {
|
||||
value.as_base_type()
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::{AsContextRef, Context},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{IntValue, PointerValue},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -10,12 +10,12 @@ use nac3core_derive::StructFields;
|
||||
|
||||
use crate::codegen::{
|
||||
types::{
|
||||
structure::{check_struct_type_matches_fields, StructField, StructFields},
|
||||
structure::{check_struct_type_matches_fields, StructField, StructFields, StructProxyType},
|
||||
ProxyType,
|
||||
},
|
||||
values::{
|
||||
ndarray::{NDIndexValue, RustNDIndex},
|
||||
ArrayLikeIndexer, ArraySliceValue, ProxyValue,
|
||||
ArrayLikeIndexer, ArraySliceValue,
|
||||
},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
@ -43,11 +43,6 @@ impl<'ctx> NDIndexType<'ctx> {
|
||||
NDIndexStructFields::new(ctx, llvm_usize)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_fields(&self) -> NDIndexStructFields<'ctx> {
|
||||
Self::fields(self.ty.get_context(), self.llvm_usize)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context, llvm_usize: IntType<'ctx>) -> PointerType<'ctx> {
|
||||
let field_tys =
|
||||
@ -76,7 +71,12 @@ impl<'ctx> NDIndexType<'ctx> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn from_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
pub fn from_struct_type(ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), llvm_usize)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
Self { ty: ptr_ty, llvm_usize }
|
||||
@ -148,9 +148,26 @@ impl<'ctx> NDIndexType<'ctx> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn map_value(
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(value, self.llvm_usize, name)
|
||||
@ -201,6 +218,14 @@ impl<'ctx> ProxyType<'ctx> for NDIndexType<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for NDIndexType<'ctx> {
|
||||
type StructFields = NDIndexStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
Self::fields(self.ty.get_context(), self.llvm_usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<NDIndexType<'ctx>> for PointerType<'ctx> {
|
||||
fn from(value: NDIndexType<'ctx>) -> Self {
|
||||
value.as_base_type()
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::{AsContextRef, Context},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{IntValue, PointerValue},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -11,7 +11,9 @@ use nac3core_derive::StructFields;
|
||||
use super::ProxyType;
|
||||
use crate::codegen::{
|
||||
irrt,
|
||||
types::structure::{check_struct_type_matches_fields, StructField, StructFields},
|
||||
types::structure::{
|
||||
check_struct_type_matches_fields, StructField, StructFields, StructProxyType,
|
||||
},
|
||||
values::{
|
||||
ndarray::{NDArrayValue, NDIterValue},
|
||||
ArrayLikeValue, ArraySliceValue, ProxyValue, TypedArrayLikeAdapter,
|
||||
@ -50,13 +52,6 @@ impl<'ctx> NDIterType<'ctx> {
|
||||
NDIterStructFields::new(ctx, llvm_usize)
|
||||
}
|
||||
|
||||
/// See [`NDIterType::fields`].
|
||||
// TODO: Move this into e.g. StructProxyType
|
||||
#[must_use]
|
||||
pub fn get_fields(&self, ctx: impl AsContextRef<'ctx>) -> NDIterStructFields<'ctx> {
|
||||
Self::fields(ctx, self.llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of an `NDIter`.
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context, llvm_usize: IntType<'ctx>) -> PointerType<'ctx> {
|
||||
@ -87,9 +82,15 @@ impl<'ctx> NDIterType<'ctx> {
|
||||
Self::new_impl(ctx, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
/// Creates an [`NDIterType`] from a [`StructType`] representing an `NDIter`.
|
||||
#[must_use]
|
||||
pub fn from_struct_type(ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`NDIterType`] from a [`PointerType`] representing an `NDIter`.
|
||||
#[must_use]
|
||||
pub fn from_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
Self { ty: ptr_ty, llvm_usize }
|
||||
@ -159,7 +160,8 @@ impl<'ctx> NDIterType<'ctx> {
|
||||
let indices =
|
||||
TypedArrayLikeAdapter::from(indices, |_, _, v| v.into_int_value(), |_, _, v| v.into());
|
||||
|
||||
let nditer = self.map_value(nditer, ndarray, indices.as_slice_value(ctx, generator), None);
|
||||
let nditer =
|
||||
self.map_pointer_value(nditer, ndarray, indices.as_slice_value(ctx, generator), None);
|
||||
|
||||
irrt::ndarray::call_nac3_nditer_initialize(generator, ctx, nditer, ndarray, &indices);
|
||||
|
||||
@ -167,9 +169,30 @@ impl<'ctx> NDIterType<'ctx> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn map_value(
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
parent: NDArrayValue<'ctx>,
|
||||
indices: ArraySliceValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
parent,
|
||||
indices,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
parent: NDArrayValue<'ctx>,
|
||||
indices: ArraySliceValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
@ -229,6 +252,14 @@ impl<'ctx> ProxyType<'ctx> for NDIterType<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for NDIterType<'ctx> {
|
||||
type StructFields = NDIterStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
Self::fields(self.ty.get_context(), self.llvm_usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<NDIterType<'ctx>> for PointerType<'ctx> {
|
||||
fn from(value: NDIterType<'ctx>) -> Self {
|
||||
value.as_base_type()
|
||||
|
@ -1,13 +1,14 @@
|
||||
use inkwell::{
|
||||
context::Context,
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
types::{AnyTypeEnum, ArrayType, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{ArrayValue, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
|
||||
use super::ProxyType;
|
||||
use crate::{
|
||||
codegen::{
|
||||
values::{ProxyValue, RangeValue},
|
||||
values::RangeValue,
|
||||
{CodeGenContext, CodeGenerator},
|
||||
},
|
||||
typecheck::typedef::{Type, TypeEnum},
|
||||
@ -61,9 +62,15 @@ impl<'ctx> RangeType<'ctx> {
|
||||
Self::new(ctx)
|
||||
}
|
||||
|
||||
/// Creates an [`RangeType`] from a [`ArrayType`].
|
||||
#[must_use]
|
||||
pub fn from_array_type(arr_ty: ArrayType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_pointer_type(arr_ty.ptr_type(AddressSpace::default()), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`RangeType`] from a [`PointerType`].
|
||||
#[must_use]
|
||||
pub fn from_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
RangeType { ty: ptr_ty, llvm_usize }
|
||||
@ -110,9 +117,27 @@ impl<'ctx> RangeType<'ctx> {
|
||||
|
||||
/// Converts an existing value into a [`RangeValue`].
|
||||
#[must_use]
|
||||
pub fn map_value(
|
||||
pub fn map_array_value<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: ArrayValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_array_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`RangeValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(value, self.llvm_usize, name)
|
||||
|
@ -1,14 +1,14 @@
|
||||
use inkwell::{
|
||||
context::Context,
|
||||
types::{BasicType, BasicTypeEnum, IntType, StructType},
|
||||
values::BasicValueEnum,
|
||||
types::{BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{BasicValueEnum, PointerValue, StructValue},
|
||||
};
|
||||
use itertools::Itertools;
|
||||
|
||||
use super::ProxyType;
|
||||
use crate::{
|
||||
codegen::{
|
||||
values::{ProxyValue, TupleValue},
|
||||
values::TupleValue,
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
typecheck::typedef::{Type, TypeEnum},
|
||||
@ -77,12 +77,18 @@ impl<'ctx> TupleType<'ctx> {
|
||||
|
||||
/// Creates an [`TupleType`] from a [`StructType`].
|
||||
#[must_use]
|
||||
pub fn from_type(struct_ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
pub fn from_struct_type(struct_ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(struct_ty, llvm_usize).is_ok());
|
||||
|
||||
TupleType { ty: struct_ty, llvm_usize }
|
||||
}
|
||||
|
||||
/// Creates an [`TupleType`] from a [`PointerType`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_struct_type(ptr_ty.get_element_type().into_struct_type(), llvm_usize)
|
||||
}
|
||||
|
||||
/// Returns the number of elements present in this [`TupleType`].
|
||||
#[must_use]
|
||||
pub fn num_elements(&self) -> u32 {
|
||||
@ -117,7 +123,10 @@ impl<'ctx> TupleType<'ctx> {
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
self.map_value(Self::llvm_type(ctx.ctx, &self.ty.get_field_types()).const_zero(), name)
|
||||
self.map_struct_value(
|
||||
Self::llvm_type(ctx.ctx, &self.ty.get_field_types()).const_zero(),
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Constructs a [`TupleValue`] from `objects`. The resulting tuple preserves the order of
|
||||
@ -147,13 +156,24 @@ impl<'ctx> TupleType<'ctx> {
|
||||
|
||||
/// Converts an existing value into a [`ListValue`].
|
||||
#[must_use]
|
||||
pub fn map_value(
|
||||
pub fn map_struct_value(
|
||||
&self,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(value, self.llvm_usize, name)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`TupleValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
value: PointerValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(ctx, value, self.llvm_usize, name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyType<'ctx> for TupleType<'ctx> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::{AsContextRef, Context, ContextRef},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::IntValue,
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -12,10 +12,11 @@ use crate::codegen::{
|
||||
types::{
|
||||
structure::{
|
||||
check_struct_type_matches_fields, FieldIndexCounter, StructField, StructFields,
|
||||
StructProxyType,
|
||||
},
|
||||
ProxyType,
|
||||
},
|
||||
values::{utils::SliceValue, ProxyValue},
|
||||
values::utils::SliceValue,
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
|
||||
@ -27,7 +28,7 @@ pub struct SliceType<'ctx> {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy, StructFields)]
|
||||
pub struct SliceFields<'ctx> {
|
||||
pub struct SliceStructFields<'ctx> {
|
||||
#[value_type(bool_type())]
|
||||
pub start_defined: StructField<'ctx, IntValue<'ctx>>,
|
||||
#[value_type(usize)]
|
||||
@ -42,14 +43,14 @@ pub struct SliceFields<'ctx> {
|
||||
pub step: StructField<'ctx, IntValue<'ctx>>,
|
||||
}
|
||||
|
||||
impl<'ctx> SliceFields<'ctx> {
|
||||
/// Creates a new instance of [`SliceFields`] with a custom integer type for its range values.
|
||||
impl<'ctx> SliceStructFields<'ctx> {
|
||||
/// Creates a new instance of [`SliceStructFields`] with a custom integer type for its range values.
|
||||
#[must_use]
|
||||
pub fn new_sized(ctx: &impl AsContextRef<'ctx>, int_ty: IntType<'ctx>) -> Self {
|
||||
let ctx = unsafe { ContextRef::new(ctx.as_ctx_ref()) };
|
||||
let mut counter = FieldIndexCounter::default();
|
||||
|
||||
SliceFields {
|
||||
SliceStructFields {
|
||||
start_defined: StructField::create(&mut counter, "start_defined", ctx.bool_type()),
|
||||
start: StructField::create(&mut counter, "start", int_ty),
|
||||
stop_defined: StructField::create(&mut counter, "stop_defined", ctx.bool_type()),
|
||||
@ -61,16 +62,10 @@ impl<'ctx> SliceFields<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> SliceType<'ctx> {
|
||||
// TODO: Move this into e.g. StructProxyType
|
||||
#[must_use]
|
||||
pub fn get_fields(&self) -> SliceFields<'ctx> {
|
||||
SliceFields::new_sized(&self.int_ty.get_context(), self.int_ty)
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of a `Slice`.
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context, int_ty: IntType<'ctx>) -> PointerType<'ctx> {
|
||||
let field_tys = SliceFields::new_sized(&int_ty.get_context(), int_ty)
|
||||
let field_tys = SliceStructFields::new_sized(&int_ty.get_context(), int_ty)
|
||||
.into_iter()
|
||||
.map(|field| field.1)
|
||||
.collect_vec();
|
||||
@ -90,6 +85,16 @@ impl<'ctx> SliceType<'ctx> {
|
||||
Self::new_impl(ctx.ctx, int_ty, ctx.get_size_type())
|
||||
}
|
||||
|
||||
/// Creates an instance of [`SliceType`] with `int_ty` as its backing integer type.
|
||||
#[must_use]
|
||||
pub fn new_with_generator<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
int_ty: IntType<'ctx>,
|
||||
) -> Self {
|
||||
Self::new_impl(ctx, int_ty, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
/// Creates an instance of [`SliceType`] with `usize` as its backing integer type.
|
||||
#[must_use]
|
||||
pub fn new_usize(ctx: &CodeGenContext<'ctx, '_>) -> Self {
|
||||
@ -105,9 +110,19 @@ impl<'ctx> SliceType<'ctx> {
|
||||
Self::new_impl(ctx, generator.get_size_type(ctx), generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
/// Creates an [`SliceType`] from a [`StructType`] representing a `slice`.
|
||||
#[must_use]
|
||||
pub fn from_struct_type(
|
||||
ty: StructType<'ctx>,
|
||||
int_ty: IntType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), int_ty, llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`SliceType`] from a [`PointerType`] representing a `slice`.
|
||||
#[must_use]
|
||||
pub fn from_type(
|
||||
pub fn from_pointer_type(
|
||||
ptr_ty: PointerType<'ctx>,
|
||||
int_ty: IntType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
@ -157,11 +172,30 @@ impl<'ctx> SliceType<'ctx> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`SliceValue`].
|
||||
#[must_use]
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.int_ty,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`ContiguousNDArrayValue`].
|
||||
#[must_use]
|
||||
pub fn map_value(
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
value: PointerValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||
@ -192,7 +226,7 @@ impl<'ctx> ProxyType<'ctx> for SliceType<'ctx> {
|
||||
fn has_same_repr(ty: Self::Base, llvm_usize: IntType<'ctx>) -> Result<(), String> {
|
||||
let ctx = ty.get_context();
|
||||
|
||||
let fields = SliceFields::new(ctx, llvm_usize);
|
||||
let fields = SliceStructFields::new(ctx, llvm_usize);
|
||||
|
||||
let llvm_ty = ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ty) = llvm_ty else {
|
||||
@ -242,6 +276,14 @@ impl<'ctx> ProxyType<'ctx> for SliceType<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for SliceType<'ctx> {
|
||||
type StructFields = SliceStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
SliceStructFields::new_sized(&self.ty.get_context(), self.int_ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<SliceType<'ctx>> for PointerType<'ctx> {
|
||||
fn from(value: SliceType<'ctx>) -> Self {
|
||||
value.as_base_type()
|
||||
|
@ -1,14 +1,18 @@
|
||||
use inkwell::{
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType},
|
||||
values::{BasicValueEnum, IntValue, PointerValue},
|
||||
values::{BasicValueEnum, IntValue, PointerValue, StructValue},
|
||||
AddressSpace, IntPredicate,
|
||||
};
|
||||
|
||||
use super::{
|
||||
ArrayLikeIndexer, ArrayLikeValue, ProxyValue, UntypedArrayLikeAccessor, UntypedArrayLikeMutator,
|
||||
structure::StructProxyValue, ArrayLikeIndexer, ArrayLikeValue, ProxyValue,
|
||||
UntypedArrayLikeAccessor, UntypedArrayLikeMutator,
|
||||
};
|
||||
use crate::codegen::{
|
||||
types::{structure::StructField, ListType, ProxyType},
|
||||
types::{
|
||||
structure::{StructField, StructProxyType},
|
||||
ListType, ProxyType,
|
||||
},
|
||||
{CodeGenContext, CodeGenerator},
|
||||
};
|
||||
|
||||
@ -21,6 +25,26 @@ pub struct ListValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ListValue<'ctx> {
|
||||
/// Creates an [`ListValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, llvm_usize, name)
|
||||
}
|
||||
|
||||
/// Creates an [`ListValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_value(
|
||||
@ -33,19 +57,13 @@ impl<'ctx> ListValue<'ctx> {
|
||||
ListValue { value: ptr, llvm_usize, name }
|
||||
}
|
||||
|
||||
fn items_field(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields(&ctx.ctx).items
|
||||
}
|
||||
|
||||
/// Returns the double-indirection pointer to the `data` array, as if by calling `getelementptr`
|
||||
/// on the field.
|
||||
fn pptr_to_data(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
|
||||
self.items_field(ctx).ptr_by_gep(ctx, self.value, self.name)
|
||||
fn items_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields().items
|
||||
}
|
||||
|
||||
/// Stores the array of data elements `data` into this instance.
|
||||
fn store_data(&self, ctx: &CodeGenContext<'ctx, '_>, data: PointerValue<'ctx>) {
|
||||
self.items_field(ctx).store(ctx, self.value, data, self.name);
|
||||
self.items_field().store(ctx, self.value, data, self.name);
|
||||
}
|
||||
|
||||
/// Convenience method for creating a new array storing data elements with the given element
|
||||
@ -83,15 +101,15 @@ impl<'ctx> ListValue<'ctx> {
|
||||
ListDataProxy(self)
|
||||
}
|
||||
|
||||
fn len_field(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields(&ctx.ctx).len
|
||||
fn len_field(&self) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields().len
|
||||
}
|
||||
|
||||
/// Stores the `size` of this `list` into this instance.
|
||||
pub fn store_size(&self, ctx: &CodeGenContext<'ctx, '_>, size: IntValue<'ctx>) {
|
||||
debug_assert_eq!(size.get_type(), ctx.get_size_type());
|
||||
|
||||
self.len_field(ctx).store(ctx, self.value, size, self.name);
|
||||
self.len_field().store(ctx, self.value, size, self.name);
|
||||
}
|
||||
|
||||
/// Returns the size of this `list` as a value.
|
||||
@ -100,7 +118,7 @@ impl<'ctx> ListValue<'ctx> {
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> IntValue<'ctx> {
|
||||
self.len_field(ctx).load(ctx, self.value, name)
|
||||
self.len_field().load(ctx, self.value, name)
|
||||
}
|
||||
|
||||
/// Returns an instance of [`ListValue`] with the `items` pointer cast to `i8*`.
|
||||
@ -123,7 +141,7 @@ impl<'ctx> ProxyValue<'ctx> for ListValue<'ctx> {
|
||||
type Type = ListType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
ListType::from_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
ListType::from_pointer_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
@ -135,6 +153,8 @@ impl<'ctx> ProxyValue<'ctx> for ListValue<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for ListValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<ListValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: ListValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
@ -159,12 +179,7 @@ impl<'ctx> ArrayLikeValue<'ctx> for ListDataProxy<'ctx, '_> {
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
_: &G,
|
||||
) -> PointerValue<'ctx> {
|
||||
let var_name = self.0.name.map(|v| format!("{v}.data")).unwrap_or_default();
|
||||
|
||||
ctx.builder
|
||||
.build_load(self.0.pptr_to_data(ctx), var_name.as_str())
|
||||
.map(BasicValueEnum::into_pointer_value)
|
||||
.unwrap()
|
||||
self.0.items_field().load(ctx, self.0.value, self.0.name)
|
||||
}
|
||||
|
||||
fn size<G: CodeGenerator + ?Sized>(
|
||||
|
@ -1,6 +1,6 @@
|
||||
use inkwell::{
|
||||
types::IntType,
|
||||
values::{IntValue, PointerValue},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
};
|
||||
use itertools::Itertools;
|
||||
|
||||
@ -8,12 +8,13 @@ use crate::codegen::{
|
||||
irrt,
|
||||
types::{
|
||||
ndarray::{NDArrayType, ShapeEntryType},
|
||||
structure::StructField,
|
||||
structure::{StructField, StructProxyType},
|
||||
ProxyType,
|
||||
},
|
||||
values::{
|
||||
ndarray::NDArrayValue, ArrayLikeIndexer, ArrayLikeValue, ArraySliceValue, ProxyValue,
|
||||
TypedArrayLikeAccessor, TypedArrayLikeAdapter, TypedArrayLikeMutator,
|
||||
ndarray::NDArrayValue, structure::StructProxyValue, ArrayLikeIndexer, ArrayLikeValue,
|
||||
ArraySliceValue, ProxyValue, TypedArrayLikeAccessor, TypedArrayLikeAdapter,
|
||||
TypedArrayLikeMutator,
|
||||
},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
@ -26,6 +27,26 @@ pub struct ShapeEntryValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ShapeEntryValue<'ctx> {
|
||||
/// Creates an [`ShapeEntryValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, llvm_usize, name)
|
||||
}
|
||||
|
||||
/// Creates an [`ShapeEntryValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_value(
|
||||
@ -39,7 +60,7 @@ impl<'ctx> ShapeEntryValue<'ctx> {
|
||||
}
|
||||
|
||||
fn ndims_field(&self) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields(self.value.get_type().get_context()).ndims
|
||||
self.get_type().get_fields().ndims
|
||||
}
|
||||
|
||||
/// Stores the number of dimensions into this value.
|
||||
@ -48,7 +69,7 @@ impl<'ctx> ShapeEntryValue<'ctx> {
|
||||
}
|
||||
|
||||
fn shape_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields(self.value.get_type().get_context()).shape
|
||||
self.get_type().get_fields().shape
|
||||
}
|
||||
|
||||
/// Stores the shape into this value.
|
||||
@ -63,7 +84,7 @@ impl<'ctx> ProxyValue<'ctx> for ShapeEntryValue<'ctx> {
|
||||
type Type = ShapeEntryType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
Self::Type::from_type(self.value.get_type(), self.llvm_usize)
|
||||
Self::Type::from_pointer_type(self.value.get_type(), self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
@ -75,6 +96,8 @@ impl<'ctx> ProxyValue<'ctx> for ShapeEntryValue<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for ShapeEntryValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<ShapeEntryValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: ShapeEntryValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
@ -163,7 +186,7 @@ fn broadcast_shapes<'ctx, G, Shape>(
|
||||
None,
|
||||
)
|
||||
};
|
||||
let shape_entry = llvm_shape_ty.map_value(pshape_entry, None);
|
||||
let shape_entry = llvm_shape_ty.map_pointer_value(pshape_entry, None);
|
||||
|
||||
let in_ndims = llvm_usize.const_int(*in_ndims, false);
|
||||
shape_entry.store_ndims(ctx, in_ndims);
|
||||
|
@ -1,16 +1,17 @@
|
||||
use inkwell::{
|
||||
types::{BasicType, BasicTypeEnum, IntType},
|
||||
values::{IntValue, PointerValue},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
AddressSpace,
|
||||
};
|
||||
|
||||
use super::{ArrayLikeValue, NDArrayValue, ProxyValue};
|
||||
use super::NDArrayValue;
|
||||
use crate::codegen::{
|
||||
stmt::gen_if_callback,
|
||||
types::{
|
||||
ndarray::{ContiguousNDArrayType, NDArrayType},
|
||||
structure::StructField,
|
||||
structure::{StructField, StructProxyType},
|
||||
},
|
||||
values::{structure::StructProxyValue, ArrayLikeValue, ProxyValue},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
|
||||
@ -23,6 +24,27 @@ pub struct ContiguousNDArrayValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ContiguousNDArrayValue<'ctx> {
|
||||
/// Creates an [`ContiguousNDArrayValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
dtype: BasicTypeEnum<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, dtype, llvm_usize, name)
|
||||
}
|
||||
|
||||
/// Creates an [`ContiguousNDArrayValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_value(
|
||||
@ -75,7 +97,7 @@ impl<'ctx> ProxyValue<'ctx> for ContiguousNDArrayValue<'ctx> {
|
||||
type Type = ContiguousNDArrayType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
<Self as ProxyValue<'ctx>>::Type::from_type(
|
||||
<Self as ProxyValue<'ctx>>::Type::from_pointer_type(
|
||||
self.as_base_value().get_type(),
|
||||
self.item,
|
||||
self.llvm_usize,
|
||||
@ -91,6 +113,8 @@ impl<'ctx> ProxyValue<'ctx> for ContiguousNDArrayValue<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for ContiguousNDArrayValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<ContiguousNDArrayValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: ContiguousNDArrayValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
|
@ -1,6 +1,6 @@
|
||||
use inkwell::{
|
||||
types::IntType,
|
||||
values::{IntValue, PointerValue},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -12,10 +12,12 @@ use crate::{
|
||||
irrt,
|
||||
types::{
|
||||
ndarray::{NDArrayType, NDIndexType},
|
||||
structure::StructField,
|
||||
structure::{StructField, StructProxyType},
|
||||
utils::SliceType,
|
||||
},
|
||||
values::{ndarray::NDArrayValue, utils::RustSlice, ProxyValue},
|
||||
values::{
|
||||
ndarray::NDArrayValue, structure::StructProxyValue, utils::RustSlice, ProxyValue,
|
||||
},
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
typecheck::typedef::Type,
|
||||
@ -30,6 +32,26 @@ pub struct NDIndexValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> NDIndexValue<'ctx> {
|
||||
/// Creates an [`NDIndexValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, llvm_usize, name)
|
||||
}
|
||||
|
||||
/// Creates an [`NDIndexValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_value(
|
||||
@ -73,7 +95,7 @@ impl<'ctx> ProxyValue<'ctx> for NDIndexValue<'ctx> {
|
||||
type Type = NDIndexType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
Self::Type::from_type(self.value.get_type(), self.llvm_usize)
|
||||
Self::Type::from_pointer_type(self.value.get_type(), self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
@ -85,6 +107,8 @@ impl<'ctx> ProxyValue<'ctx> for NDIndexValue<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for NDIndexValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<NDIndexValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: NDIndexValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
|
@ -1,15 +1,18 @@
|
||||
use inkwell::{
|
||||
types::{BasicType, IntType},
|
||||
values::{BasicValueEnum, IntValue, PointerValue},
|
||||
values::{BasicValueEnum, IntValue, PointerValue, StructValue},
|
||||
AddressSpace,
|
||||
};
|
||||
|
||||
use super::{NDArrayValue, ProxyValue};
|
||||
use super::NDArrayValue;
|
||||
use crate::codegen::{
|
||||
irrt,
|
||||
stmt::{gen_for_callback, BreakContinueHooks},
|
||||
types::{ndarray::NDIterType, structure::StructField},
|
||||
values::{ArraySliceValue, TypedArrayLikeAdapter},
|
||||
types::{
|
||||
ndarray::NDIterType,
|
||||
structure::{StructField, StructProxyType},
|
||||
},
|
||||
values::{structure::StructProxyValue, ArraySliceValue, ProxyValue, TypedArrayLikeAdapter},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
|
||||
@ -23,6 +26,28 @@ pub struct NDIterValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> NDIterValue<'ctx> {
|
||||
/// Creates an [`NDArrayValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
parent: NDArrayValue<'ctx>,
|
||||
indices: ArraySliceValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, parent, indices, llvm_usize, name)
|
||||
}
|
||||
|
||||
/// Creates an [`NDArrayValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_value(
|
||||
@ -56,11 +81,8 @@ impl<'ctx> NDIterValue<'ctx> {
|
||||
irrt::ndarray::call_nac3_nditer_next(ctx, *self);
|
||||
}
|
||||
|
||||
fn element_field(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields(ctx.ctx).element
|
||||
fn element_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields().element
|
||||
}
|
||||
|
||||
/// Get pointer to the current element.
|
||||
@ -68,7 +90,7 @@ impl<'ctx> NDIterValue<'ctx> {
|
||||
pub fn get_pointer(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
|
||||
let elem_ty = self.parent.dtype;
|
||||
|
||||
let p = self.element_field(ctx).load(ctx, self.as_abi_value(ctx), self.name);
|
||||
let p = self.element_field().load(ctx, self.as_abi_value(ctx), self.name);
|
||||
ctx.builder
|
||||
.build_pointer_cast(p, elem_ty.ptr_type(AddressSpace::default()), "element")
|
||||
.unwrap()
|
||||
@ -81,14 +103,14 @@ impl<'ctx> NDIterValue<'ctx> {
|
||||
ctx.builder.build_load(p, "value").unwrap()
|
||||
}
|
||||
|
||||
fn nth_field(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields(ctx.ctx).nth
|
||||
fn nth_field(&self) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields().nth
|
||||
}
|
||||
|
||||
/// Get the index of the current element if this ndarray were a flat ndarray.
|
||||
#[must_use]
|
||||
pub fn get_index(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
self.nth_field(ctx).load(ctx, self.as_abi_value(ctx), self.name)
|
||||
self.nth_field().load(ctx, self.as_abi_value(ctx), self.name)
|
||||
}
|
||||
|
||||
/// Get the indices of the current element.
|
||||
@ -110,7 +132,7 @@ impl<'ctx> ProxyValue<'ctx> for NDIterValue<'ctx> {
|
||||
type Type = NDIterType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
NDIterType::from_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
NDIterType::from_pointer_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
@ -122,6 +144,8 @@ impl<'ctx> ProxyValue<'ctx> for NDIterValue<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for NDIterValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<NDIterValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: NDIterValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
|
@ -42,7 +42,7 @@ pub fn parse_numpy_int_sequence<'ctx, G: CodeGenerator + ?Sized>(
|
||||
// 1. A list of `int32`; e.g., `np.empty([600, 800, 3])`
|
||||
|
||||
let input_seq = ListType::from_unifier_type(generator, ctx, input_seq_ty)
|
||||
.map_value(input_seq.into_pointer_value(), None);
|
||||
.map_pointer_value(input_seq.into_pointer_value(), None);
|
||||
|
||||
let len = input_seq.load_size(ctx, None);
|
||||
// TODO: Find a way to remove this mid-BB allocation
|
||||
@ -86,7 +86,7 @@ pub fn parse_numpy_int_sequence<'ctx, G: CodeGenerator + ?Sized>(
|
||||
// 2. A tuple of ints; e.g., `np.empty((600, 800, 3))`
|
||||
|
||||
let input_seq = TupleType::from_unifier_type(generator, ctx, input_seq_ty)
|
||||
.map_value(input_seq.into_struct_value(), None);
|
||||
.map_struct_value(input_seq.into_struct_value(), None);
|
||||
|
||||
let len = input_seq.get_type().num_elements();
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
use inkwell::{
|
||||
types::IntType,
|
||||
values::{BasicValueEnum, IntValue, PointerValue},
|
||||
values::{ArrayValue, BasicValueEnum, IntValue, PointerValue},
|
||||
};
|
||||
|
||||
use super::ProxyValue;
|
||||
use crate::codegen::{types::RangeType, CodeGenContext};
|
||||
use crate::codegen::{types::RangeType, CodeGenContext, CodeGenerator};
|
||||
|
||||
/// Proxy type for accessing a `range` value in LLVM.
|
||||
#[derive(Copy, Clone)]
|
||||
@ -15,6 +15,26 @@ pub struct RangeValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> RangeValue<'ctx> {
|
||||
/// Creates an [`RangeValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_array_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: ArrayValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, llvm_usize, name)
|
||||
}
|
||||
|
||||
/// Creates an [`RangeValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_value(
|
||||
@ -142,7 +162,7 @@ impl<'ctx> ProxyValue<'ctx> for RangeValue<'ctx> {
|
||||
type Type = RangeType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
RangeType::from_type(self.value.get_type(), self.llvm_usize)
|
||||
RangeType::from_pointer_type(self.value.get_type(), self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use inkwell::{
|
||||
types::IntType,
|
||||
values::{BasicValue, BasicValueEnum, StructValue},
|
||||
values::{BasicValue, BasicValueEnum, PointerValue, StructValue},
|
||||
};
|
||||
|
||||
use super::ProxyValue;
|
||||
@ -26,6 +26,24 @@ impl<'ctx> TupleValue<'ctx> {
|
||||
Self { value, llvm_usize, name }
|
||||
}
|
||||
|
||||
/// Creates an [`TupleValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_value(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
ptr: PointerValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
Self::from_struct_value(
|
||||
ctx.builder
|
||||
.build_load(ptr, name.unwrap_or_default())
|
||||
.map(BasicValueEnum::into_struct_value)
|
||||
.unwrap(),
|
||||
llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Stores a value into the tuple element at the given `index`.
|
||||
pub fn store_element(
|
||||
&mut self,
|
||||
@ -62,7 +80,7 @@ impl<'ctx> ProxyValue<'ctx> for TupleValue<'ctx> {
|
||||
type Type = TupleType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
TupleType::from_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
TupleType::from_struct_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
|
@ -1,14 +1,17 @@
|
||||
use inkwell::{
|
||||
types::IntType,
|
||||
values::{IntValue, PointerValue},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
};
|
||||
|
||||
use nac3parser::ast::Expr;
|
||||
|
||||
use crate::{
|
||||
codegen::{
|
||||
types::{structure::StructField, utils::SliceType},
|
||||
values::ProxyValue,
|
||||
types::{
|
||||
structure::{StructField, StructProxyType},
|
||||
utils::SliceType,
|
||||
},
|
||||
values::{structure::StructProxyValue, ProxyValue},
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
typecheck::typedef::Type,
|
||||
@ -24,6 +27,27 @@ pub struct SliceValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> SliceValue<'ctx> {
|
||||
/// Creates an [`SliceValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
int_ty: IntType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, int_ty, llvm_usize, name)
|
||||
}
|
||||
|
||||
/// Creates an [`SliceValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_value(
|
||||
@ -155,7 +179,7 @@ impl<'ctx> ProxyValue<'ctx> for SliceValue<'ctx> {
|
||||
type Type = SliceType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
Self::Type::from_type(self.value.get_type(), self.int_ty, self.llvm_usize)
|
||||
Self::Type::from_pointer_type(self.value.get_type(), self.int_ty, self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
@ -167,6 +191,8 @@ impl<'ctx> ProxyValue<'ctx> for SliceValue<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for SliceValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<SliceValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: SliceValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
|
@ -577,7 +577,7 @@ impl<'a> BuiltinBuilder<'a> {
|
||||
let (zelf_ty, zelf) = obj.unwrap();
|
||||
let zelf =
|
||||
zelf.to_basic_value_enum(ctx, generator, zelf_ty)?.into_pointer_value();
|
||||
let zelf = RangeType::new(ctx).map_value(zelf, Some("range"));
|
||||
let zelf = RangeType::new(ctx).map_pointer_value(zelf, Some("range"));
|
||||
|
||||
let mut start = None;
|
||||
let mut stop = None;
|
||||
|
Loading…
Reference in New Issue
Block a user