forked from M-Labs/nac3
WIP 6
This commit is contained in:
parent
7742fbf9e0
commit
059b130aff
|
@ -2,7 +2,7 @@ use std::marker::PhantomData;
|
|||
|
||||
use inkwell::{
|
||||
types::{BasicType, BasicTypeEnum, IntType},
|
||||
values::{BasicValueEnum, IntValue},
|
||||
values::{BasicValueEnum, IntValue, PointerValue},
|
||||
};
|
||||
|
||||
use crate::codegen::optics::*;
|
||||
|
@ -95,7 +95,7 @@ struct Producer<'ctx, G: CodeGenerator + ?Sized, ElementOptic> {
|
|||
///
|
||||
/// See also [`typecheck::type_inferencer::fold_numpy_function_call_shape_argument`] to
|
||||
/// learn how `shape` gets from being a Python user expression to here.
|
||||
fn parse_input_shape_arg<'ctx, G>(
|
||||
pub fn parse_input_shape_arg<'ctx, G>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
shape: BasicValueEnum<'ctx>,
|
||||
|
@ -258,14 +258,14 @@ where
|
|||
Ok(ndarray_ptr)
|
||||
}
|
||||
|
||||
enum NDArrayInitMode<'ctx, G: CodeGenerator + ?Sized> {
|
||||
NDim { ndim: IntValue<'ctx>, _phantom: PhantomData<&'ctx G> },
|
||||
pub enum NDArrayInitMode<'ctx, G: CodeGenerator + ?Sized> {
|
||||
NDim { ndim: IntValue<'ctx> },
|
||||
Shape { shape: Producer<'ctx, G, IntLens<'ctx>> },
|
||||
ShapeAndAllocaData { shape: Producer<'ctx, G, IntLens<'ctx>> },
|
||||
}
|
||||
|
||||
/// TODO: DOCUMENT ME
|
||||
fn alloca_ndarray_and_init<'ctx, G>(
|
||||
pub fn alloca_ndarray_and_init<'ctx, G>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
elem_type: BasicTypeEnum<'ctx>,
|
||||
|
@ -277,7 +277,7 @@ where
|
|||
{
|
||||
// It is implemented verbosely in order to make the initialization modes super clear in their intent.
|
||||
match init_mode {
|
||||
NDArrayInitMode::NDim { ndim: ndims, _phantom } => {
|
||||
NDArrayInitMode::NDim { ndim } => {
|
||||
let ndarray = alloca_ndarray(generator, ctx, elem_type, ndims, name)?;
|
||||
Ok(ndarray)
|
||||
}
|
||||
|
@ -397,11 +397,11 @@ fn call_nac3_ndarray_nbytes<'ctx, G: CodeGenerator + ?Sized>(
|
|||
.returning("nbytes", &IntLens(size_type))
|
||||
}
|
||||
|
||||
fn call_nac3_ndarray_fill_generic<'ctx, G: CodeGenerator + ?Sized>(
|
||||
pub fn call_nac3_ndarray_fill_generic<'ctx, G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
ndarray_ptr: &Address<'ctx, NpArrayLens<'ctx>>,
|
||||
fill_value_ptr: &Address<'ctx, IntLens<'ctx>>,
|
||||
fill_value_ptr: PointerValue<'ctx>,
|
||||
) {
|
||||
let size_type = generator.get_size_type(ctx.ctx);
|
||||
|
||||
|
@ -410,6 +410,6 @@ fn call_nac3_ndarray_fill_generic<'ctx, G: CodeGenerator + ?Sized>(
|
|||
&get_sized_dependent_function_name(size_type, "__nac3_ndarray_fill_generic"),
|
||||
)
|
||||
.arg("ndarray", &AddressLens(NpArrayLens { size_type }), ndarray_ptr)
|
||||
.arg("pvalue", &opaque_address_lens(ctx.ctx), fill_value_ptr)
|
||||
.arg("pvalue", &OpaqueAddressLens, fill_value_ptr)
|
||||
.returning_void();
|
||||
}
|
||||
|
|
|
@ -43,13 +43,13 @@ impl<'ctx, 'a> FunctionBuilder<'ctx, 'a> {
|
|||
|
||||
// The name is for self-documentation
|
||||
#[must_use]
|
||||
pub fn arg<S: Optic<'ctx>>(mut self, _name: &'static str, optic: &S, arg: &S::Value) -> Self {
|
||||
pub fn arg<S: MemoryOptic<'ctx>>(mut self, _name: &'static str, optic: &S, arg: &S::MemoryValue) -> Self {
|
||||
self.arguments
|
||||
.push((optic.get_llvm_type(self.ctx.ctx).into(), arg.get_llvm_value().into()));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn returning<S: Prism<'ctx>>(self, name: &'static str, return_prism: &S) -> S::Value {
|
||||
pub fn returning<S: Prism<'ctx>>(self, name: &'static str, return_prism: &S) -> S::MemoryValue {
|
||||
let (param_tys, param_vals): (Vec<_>, Vec<_>) = self.arguments.into_iter().unzip();
|
||||
|
||||
let function = self.ctx.module.get_function(self.fn_name).unwrap_or_else(|| {
|
||||
|
|
|
@ -26,7 +26,7 @@ use inkwell::{
|
|||
use irrt::error_context::StrLens;
|
||||
use itertools::Itertools;
|
||||
use nac3parser::ast::{Location, Stmt, StrRef};
|
||||
use optics::Optic as _;
|
||||
use optics::MemoryOptic as _;
|
||||
use parking_lot::{Condvar, Mutex};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::{
|
||||
|
@ -44,6 +44,7 @@ mod generator;
|
|||
pub mod irrt;
|
||||
pub mod llvm_intrinsics;
|
||||
pub mod numpy;
|
||||
pub mod numpy_new;
|
||||
pub mod optics;
|
||||
pub mod stmt;
|
||||
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
use inkwell::values::{BasicValueEnum, PointerValue};
|
||||
use nac3parser::ast::StrRef;
|
||||
|
||||
use crate::{
|
||||
codegen::optics::build_opaque_alloca, symbol_resolver::ValueEnum, toplevel::DefinitionId, typecheck::typedef::{FunSignature, Type}
|
||||
};
|
||||
|
||||
use super::{
|
||||
irrt::{
|
||||
self,
|
||||
numpy::{alloca_ndarray_and_init, parse_input_shape_arg, NDArrayInitMode, NpArrayLens},
|
||||
},
|
||||
optics::Address,
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
|
||||
/// LLVM-typed implementation for generating the implementation for constructing an empty `NDArray`.
|
||||
fn call_ndarray_empty_impl<'ctx, G>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
elem_ty: Type,
|
||||
shape: BasicValueEnum<'ctx>,
|
||||
shape_ty: Type,
|
||||
name: &str,
|
||||
) -> Result<Address<'ctx, NpArrayLens<'ctx>>, String>
|
||||
where
|
||||
G: CodeGenerator + ?Sized,
|
||||
{
|
||||
let elem_type = ctx.get_llvm_type(generator, elem_ty);
|
||||
let shape = parse_input_shape_arg(generator, ctx, shape, shape_ty);
|
||||
let ndarray_ptr = alloca_ndarray_and_init(
|
||||
generator,
|
||||
ctx,
|
||||
elem_type,
|
||||
NDArrayInitMode::ShapeAndAllocaData { shape },
|
||||
name,
|
||||
)?;
|
||||
Ok(ndarray_ptr)
|
||||
}
|
||||
|
||||
fn call_ndarray_fill_impl<'ctx, G>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
elem_ty: Type,
|
||||
shape: BasicValueEnum<'ctx>,
|
||||
shape_ty: Type,
|
||||
fill_value: BasicValueEnum<'ctx>,
|
||||
name: &str,
|
||||
) -> Result<Address<'ctx, NpArrayLens<'ctx>>, String>
|
||||
where
|
||||
G: CodeGenerator + ?Sized,
|
||||
{
|
||||
let ndarray_ptr = call_ndarray_empty_impl(generator, ctx, elem_ty, shape, shape_ty, name)?;
|
||||
|
||||
// NOTE: fill_value's type is not checked!!
|
||||
let fill_value_ptr = build_opaque_alloca(ctx, fill_value.get_type(), name);
|
||||
fill_value_ptr.store(ctx, );
|
||||
// let fill_value_ptr = ctx.builder.build_alloca(, "fill_value_ptr").unwrap();
|
||||
// ctx.builder.build_store(fill_value_ptr, fill_value);
|
||||
|
||||
// let ok = irrt::numpy::call_nac3_ndarray_fill_generic(generator, ctx, ndarray_ptr, Address { fill_value_ptr } );
|
||||
todo!()
|
||||
Ok(ndarray_ptr)
|
||||
}
|
||||
|
||||
/// Generates LLVM IR for `np.empty`.
|
||||
pub fn gen_ndarray_empty<'ctx, G>(
|
||||
context: &mut CodeGenContext<'ctx, '_>,
|
||||
obj: &Option<(Type, ValueEnum<'ctx>)>,
|
||||
fun: (&FunSignature, DefinitionId),
|
||||
args: &[(Option<StrRef>, ValueEnum<'ctx>)],
|
||||
generator: &mut dyn CodeGenerator,
|
||||
) -> Result<PointerValue<'ctx>, String> {
|
||||
assert!(obj.is_none());
|
||||
assert_eq!(args.len(), 1);
|
||||
|
||||
// Parse arguments
|
||||
let shape_ty = fun.0.args[0].ty;
|
||||
let shape = args[0].1.clone().to_basic_value_enum(context, generator, shape_ty)?;
|
||||
|
||||
// Implementation
|
||||
let ndarray_ptr = call_ndarray_empty_impl(
|
||||
generator,
|
||||
context,
|
||||
context.primitives.float,
|
||||
shape,
|
||||
shape_ty,
|
||||
"empty_ndarray",
|
||||
)?;
|
||||
Ok(ndarray_ptr.address)
|
||||
}
|
|
@ -7,10 +7,7 @@ use inkwell::{
|
|||
|
||||
use crate::codegen::CodeGenContext;
|
||||
|
||||
use super::{
|
||||
core::{MemoryGetter, MemorySetter, Optic, OpticValue, Prism},
|
||||
int::IntLens,
|
||||
};
|
||||
use super::core::{MemoryGetter, MemoryOptic, MemorySetter, OpticValue, Prism};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Address<'ctx, AddresseeOptic> {
|
||||
|
@ -19,7 +16,7 @@ pub struct Address<'ctx, AddresseeOptic> {
|
|||
}
|
||||
|
||||
impl<'ctx, AddresseeOptic> Address<'ctx, AddresseeOptic> {
|
||||
pub fn cast_to<S: Optic<'ctx>>(
|
||||
pub fn cast_to<S: MemoryOptic<'ctx>>(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
new_optic: S,
|
||||
|
@ -30,8 +27,8 @@ impl<'ctx, AddresseeOptic> Address<'ctx, AddresseeOptic> {
|
|||
Address { addressee_optic: new_optic, address: casted_address }
|
||||
}
|
||||
|
||||
pub fn cast_to_opaque(&self, ctx: &CodeGenContext<'ctx, '_>) -> Address<'ctx, IntLens<'ctx>> {
|
||||
self.cast_to(ctx, IntLens::int8(ctx.ctx))
|
||||
pub fn cast_to_opaque(&self) -> OpaqueAddress<'ctx> {
|
||||
OpaqueAddress(self.address)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,21 +41,16 @@ impl<'ctx, AddresseeOptic> OpticValue<'ctx> for Address<'ctx, AddresseeOptic> {
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct AddressLens<AddresseeOptic>(pub AddresseeOptic);
|
||||
|
||||
#[must_use]
|
||||
pub fn opaque_address_lens(ctx: &Context) -> AddressLens<IntLens<'_>> {
|
||||
AddressLens(IntLens::int8(ctx))
|
||||
}
|
||||
|
||||
impl<'ctx, AddresseeOptic: Optic<'ctx>> Optic<'ctx> for AddressLens<AddresseeOptic> {
|
||||
type Value = Address<'ctx, AddresseeOptic>;
|
||||
impl<'ctx, AddresseeOptic: MemoryOptic<'ctx>> MemoryOptic<'ctx> for AddressLens<AddresseeOptic> {
|
||||
type MemoryValue = Address<'ctx, AddresseeOptic>;
|
||||
|
||||
fn get_llvm_type(&self, ctx: &'ctx Context) -> BasicTypeEnum<'ctx> {
|
||||
self.0.get_llvm_type(ctx).ptr_type(AddressSpace::default()).as_basic_type_enum()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx, AddresseeOptic: Optic<'ctx>> Prism<'ctx> for AddressLens<AddresseeOptic> {
|
||||
fn review<V: AnyValue<'ctx>>(&self, value: V) -> Self::Value {
|
||||
impl<'ctx, AddresseeOptic: MemoryOptic<'ctx>> Prism<'ctx> for AddressLens<AddresseeOptic> {
|
||||
fn review<V: AnyValue<'ctx>>(&self, value: V) -> Self::MemoryValue {
|
||||
Address {
|
||||
addressee_optic: self.0.clone(),
|
||||
address: value.as_any_value_enum().into_pointer_value(),
|
||||
|
@ -66,23 +58,23 @@ impl<'ctx, AddresseeOptic: Optic<'ctx>> Prism<'ctx> for AddressLens<AddresseeOpt
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ctx, AddressesOptic: Optic<'ctx>> MemoryGetter<'ctx> for AddressLens<AddressesOptic> {
|
||||
impl<'ctx, AddressesOptic: MemoryOptic<'ctx>> MemoryGetter<'ctx> for AddressLens<AddressesOptic> {
|
||||
fn get(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
pointer: PointerValue<'ctx>,
|
||||
name: &str,
|
||||
) -> Self::Value {
|
||||
) -> Self::MemoryValue {
|
||||
self.review(ctx.builder.build_load(pointer, name).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx, AddressesOptic: Optic<'ctx>> MemorySetter<'ctx> for AddressLens<AddressesOptic> {
|
||||
impl<'ctx, AddressesOptic: MemoryOptic<'ctx>> MemorySetter<'ctx> for AddressLens<AddressesOptic> {
|
||||
fn set(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
pointer: PointerValue<'ctx>,
|
||||
value: &Self::Value,
|
||||
value: &Self::MemoryValue,
|
||||
) {
|
||||
ctx.builder.build_store(pointer, value.address).unwrap();
|
||||
}
|
||||
|
@ -90,14 +82,49 @@ impl<'ctx, AddressesOptic: Optic<'ctx>> MemorySetter<'ctx> for AddressLens<Addre
|
|||
|
||||
// To make [`Address`] convenient to use
|
||||
impl<'ctx, AddresseeOptic: MemoryGetter<'ctx>> Address<'ctx, AddresseeOptic> {
|
||||
pub fn load(&self, ctx: &CodeGenContext<'ctx, '_>, name: &str) -> AddresseeOptic::Value {
|
||||
pub fn load(&self, ctx: &CodeGenContext<'ctx, '_>, name: &str) -> AddresseeOptic::MemoryValue {
|
||||
self.addressee_optic.get(ctx, self.address, name)
|
||||
}
|
||||
}
|
||||
|
||||
// To make [`Address`] convenient to use
|
||||
impl<'ctx, AddresseeOptic: MemorySetter<'ctx>> Address<'ctx, AddresseeOptic> {
|
||||
pub fn store(&self, ctx: &CodeGenContext<'ctx, '_>, value: &AddresseeOptic::Value) {
|
||||
pub fn store(&self, ctx: &CodeGenContext<'ctx, '_>, value: &AddresseeOptic::MemoryValue) {
|
||||
self.addressee_optic.set(ctx, self.address, value);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct OpaqueAddress<'ctx>(pub PointerValue<'ctx>);
|
||||
|
||||
impl<'ctx> OpaqueAddress<'ctx> {
|
||||
pub fn cast_to<AddresseeOptic: MemoryOptic<'ctx>>(
|
||||
&self,
|
||||
ctx: &'ctx CodeGenContext,
|
||||
addressee_optic: AddresseeOptic,
|
||||
name: &str,
|
||||
) -> Address<'ctx, AddresseeOptic> {
|
||||
let ptr = ctx.builder.build_pointer_cast(
|
||||
self.0,
|
||||
addressee_optic.get_llvm_type(ctx.ctx).ptr_type(AddressSpace::default()),
|
||||
name,
|
||||
);
|
||||
Address { addressee_optic, address: ptr }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct OpaqueAddressLens;
|
||||
|
||||
impl<'ctx> MemoryOptic<'ctx> for OpaqueAddressLens {
|
||||
type MemoryValue = BasicValueEnum<'ctx>;
|
||||
|
||||
fn get_llvm_type(&self, ctx: &'ctx Context) -> BasicTypeEnum<'ctx> {
|
||||
ctx.i8_type().ptr_type(AddressSpace::default()).as_basic_type_enum()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> OpaqueAddress<'ctx> {
|
||||
pub fn store(&self, ctx: &CodeGenContext<'ctx, '_>, value: BasicValueEnum<'ctx>) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ impl<'ctx, T: BasicValue<'ctx>> OpticValue<'ctx> for T {
|
|||
}
|
||||
|
||||
// TODO: The interface is unintuitive
|
||||
pub trait Optic<'ctx>: Clone {
|
||||
type Value: OpticValue<'ctx>;
|
||||
pub trait MemoryOptic<'ctx>: Clone {
|
||||
type MemoryValue: OpticValue<'ctx>;
|
||||
|
||||
fn get_llvm_type(&self, ctx: &'ctx Context) -> BasicTypeEnum<'ctx>;
|
||||
|
||||
|
@ -32,20 +32,20 @@ pub trait Optic<'ctx>: Clone {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Prism<'ctx>: Optic<'ctx> {
|
||||
pub trait Prism<'ctx>: MemoryOptic<'ctx> {
|
||||
// TODO: Return error if `review` fails
|
||||
fn review<V: AnyValue<'ctx>>(&self, value: V) -> Self::Value;
|
||||
fn review<V: AnyValue<'ctx>>(&self, value: V) -> Self::MemoryValue;
|
||||
}
|
||||
|
||||
pub trait MemoryGetter<'ctx>: Optic<'ctx> {
|
||||
pub trait MemoryGetter<'ctx>: MemoryOptic<'ctx> {
|
||||
fn get(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
pointer: PointerValue<'ctx>,
|
||||
name: &str,
|
||||
) -> Self::Value;
|
||||
) -> Self::MemoryValue;
|
||||
}
|
||||
|
||||
pub trait MemorySetter<'ctx>: Optic<'ctx> {
|
||||
fn set(&self, ctx: &CodeGenContext<'ctx, '_>, pointer: PointerValue<'ctx>, value: &Self::Value);
|
||||
pub trait MemorySetter<'ctx>: MemoryOptic<'ctx> {
|
||||
fn set(&self, ctx: &CodeGenContext<'ctx, '_>, pointer: PointerValue<'ctx>, value: &Self::MemoryValue);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::codegen::CodeGenContext;
|
|||
|
||||
use super::{
|
||||
address::Address,
|
||||
core::{MemoryGetter, Optic},
|
||||
core::{MemoryGetter, MemoryOptic},
|
||||
};
|
||||
|
||||
// ((Memory, Pointer) -> ElementOptic::Value*)
|
||||
|
@ -23,21 +23,21 @@ pub struct GepGetter<ElementOptic> {
|
|||
pub element_optic: ElementOptic,
|
||||
}
|
||||
|
||||
impl<'ctx, ElementOptic: Optic<'ctx>> Optic<'ctx> for GepGetter<ElementOptic> {
|
||||
type Value = Address<'ctx, ElementOptic>;
|
||||
impl<'ctx, ElementOptic: MemoryOptic<'ctx>> MemoryOptic<'ctx> for GepGetter<ElementOptic> {
|
||||
type MemoryValue = Address<'ctx, ElementOptic>;
|
||||
|
||||
fn get_llvm_type(&self, ctx: &'ctx Context) -> BasicTypeEnum<'ctx> {
|
||||
self.element_optic.get_llvm_type(ctx).ptr_type(AddressSpace::default()).as_basic_type_enum()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx, ElementOptic: Optic<'ctx>> MemoryGetter<'ctx> for GepGetter<ElementOptic> {
|
||||
impl<'ctx, ElementOptic: MemoryOptic<'ctx>> MemoryGetter<'ctx> for GepGetter<ElementOptic> {
|
||||
fn get(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
pointer: PointerValue<'ctx>,
|
||||
name: &str,
|
||||
) -> Self::Value {
|
||||
) -> Self::MemoryValue {
|
||||
let llvm_i32 = ctx.ctx.i32_type(); // TODO: I think I'm not supposed to *just* use i32 for GEP like that
|
||||
let element_ptr = unsafe {
|
||||
ctx.builder
|
||||
|
|
|
@ -6,7 +6,7 @@ use inkwell::{
|
|||
|
||||
use crate::codegen::CodeGenContext;
|
||||
|
||||
use super::core::{MemoryGetter, MemorySetter, Optic, Prism};
|
||||
use super::core::{MemoryGetter, MemorySetter, MemoryOptic, Prism};
|
||||
|
||||
// NOTE: I wanted to make Int8Lens, Int16Lens, Int32Lens, with all
|
||||
// having the trait IsIntLens, and implement `impl <S: IsIntLens> Optic<S> for T`,
|
||||
|
@ -31,8 +31,8 @@ impl<'ctx> IntLens<'ctx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ctx> Optic<'ctx> for IntLens<'ctx> {
|
||||
type Value = IntValue<'ctx>;
|
||||
impl<'ctx> MemoryOptic<'ctx> for IntLens<'ctx> {
|
||||
type MemoryValue = IntValue<'ctx>;
|
||||
|
||||
fn get_llvm_type(&self, _ctx: &'ctx Context) -> BasicTypeEnum<'ctx> {
|
||||
self.0.as_basic_type_enum()
|
||||
|
@ -40,7 +40,7 @@ impl<'ctx> Optic<'ctx> for IntLens<'ctx> {
|
|||
}
|
||||
|
||||
impl<'ctx> Prism<'ctx> for IntLens<'ctx> {
|
||||
fn review<V: AnyValue<'ctx>>(&self, value: V) -> Self::Value {
|
||||
fn review<V: AnyValue<'ctx>>(&self, value: V) -> Self::MemoryValue {
|
||||
let int = value.as_any_value_enum().into_int_value();
|
||||
debug_assert_eq!(int.get_type().get_bit_width(), self.0.get_bit_width());
|
||||
int
|
||||
|
@ -53,13 +53,13 @@ impl<'ctx> MemoryGetter<'ctx> for IntLens<'ctx> {
|
|||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
pointer: PointerValue<'ctx>,
|
||||
name: &str,
|
||||
) -> Self::Value {
|
||||
) -> Self::MemoryValue {
|
||||
self.review(ctx.builder.build_load(pointer, name).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> MemorySetter<'ctx> for IntLens<'ctx> {
|
||||
fn set(&self, ctx: &CodeGenContext<'ctx, '_>, pointer: PointerValue<'ctx>, int: &Self::Value) {
|
||||
fn set(&self, ctx: &CodeGenContext<'ctx, '_>, pointer: PointerValue<'ctx>, int: &Self::MemoryValue) {
|
||||
debug_assert_eq!(int.get_type().get_bit_width(), self.0.get_bit_width());
|
||||
ctx.builder.build_store(pointer, int.as_basic_value_enum()).unwrap();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{
|
||||
core::Optic,
|
||||
core::MemoryOptic,
|
||||
ixed::{BoundedIxed, Ixed},
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,7 @@ pub struct ArraySlice<'ctx, ElementOptic> {
|
|||
pub base: Address<'ctx, ElementOptic>,
|
||||
}
|
||||
|
||||
impl<'ctx, ElementOptic: Optic<'ctx>> Ixed<'ctx, ElementOptic> for ArraySlice<'ctx, ElementOptic> {
|
||||
impl<'ctx, ElementOptic: MemoryOptic<'ctx>> Ixed<'ctx, ElementOptic> for ArraySlice<'ctx, ElementOptic> {
|
||||
fn ix(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
|
@ -27,7 +27,7 @@ impl<'ctx, ElementOptic: Optic<'ctx>> Ixed<'ctx, ElementOptic> for ArraySlice<'c
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ctx, ElementOptic: Optic<'ctx>> BoundedIxed<'ctx, ElementOptic>
|
||||
impl<'ctx, ElementOptic: MemoryOptic<'ctx>> BoundedIxed<'ctx, ElementOptic>
|
||||
for ArraySlice<'ctx, ElementOptic>
|
||||
{
|
||||
fn num_elements(&self, _ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::codegen::CodeGenContext;
|
|||
|
||||
use super::{
|
||||
address::Address,
|
||||
core::{MemoryGetter, MemorySetter, Optic, OpticValue},
|
||||
core::{MemoryGetter, MemorySetter, MemoryOptic, OpticValue},
|
||||
gep::GepGetter,
|
||||
};
|
||||
|
||||
|
@ -40,8 +40,8 @@ impl<'ctx, StructOptic> OpticValue<'ctx> for OpticalStructValue<'ctx, StructOpti
|
|||
}
|
||||
|
||||
// TODO: check StructType
|
||||
impl<'ctx, T: StructureOptic<'ctx>> Optic<'ctx> for T {
|
||||
type Value = OpticalStructValue<'ctx, Self>;
|
||||
impl<'ctx, T: StructureOptic<'ctx>> MemoryOptic<'ctx> for T {
|
||||
type MemoryValue = OpticalStructValue<'ctx, Self>;
|
||||
|
||||
fn get_llvm_type(&self, ctx: &'ctx Context) -> BasicTypeEnum<'ctx> {
|
||||
let mut builder = FieldBuilder::new(ctx, self.struct_name());
|
||||
|
@ -59,7 +59,7 @@ impl<'ctx, T: StructureOptic<'ctx>> MemoryGetter<'ctx> for T {
|
|||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
pointer: PointerValue<'ctx>,
|
||||
name: &str,
|
||||
) -> Self::Value {
|
||||
) -> Self::MemoryValue {
|
||||
OpticalStructValue {
|
||||
optic: self.clone(),
|
||||
llvm: ctx.builder.build_load(pointer, name).unwrap().into_struct_value(),
|
||||
|
@ -72,14 +72,14 @@ impl<'ctx, T: StructureOptic<'ctx>> MemorySetter<'ctx> for T {
|
|||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
pointer: PointerValue<'ctx>,
|
||||
value: &Self::Value,
|
||||
value: &Self::MemoryValue,
|
||||
) {
|
||||
ctx.builder.build_store(pointer, value.llvm).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx, AddresseeOptic: StructureOptic<'ctx>> Address<'ctx, AddresseeOptic> {
|
||||
pub fn focus<GetFieldGepFn, FieldElementOptic: Optic<'ctx>>(
|
||||
pub fn focus<GetFieldGepFn, FieldElementOptic: MemoryOptic<'ctx>>(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
get_field_gep_fn: GetFieldGepFn,
|
||||
|
@ -121,7 +121,7 @@ impl<'ctx> FieldBuilder<'ctx> {
|
|||
index
|
||||
}
|
||||
|
||||
pub fn add_field<ElementOptic: Optic<'ctx>>(
|
||||
pub fn add_field<ElementOptic: MemoryOptic<'ctx>>(
|
||||
&mut self,
|
||||
name: &'static str,
|
||||
element_optic: ElementOptic,
|
||||
|
|
Loading…
Reference in New Issue