forked from M-Labs/nac3
core: move Slice and RustSlice to its own file & genericize their IntKind
This commit is contained in:
parent
f698b0c1fa
commit
a6e1d354b6
@ -4,5 +4,6 @@ pub mod exception;
|
||||
pub mod list;
|
||||
pub mod ndarray;
|
||||
pub mod range;
|
||||
pub mod slice;
|
||||
pub mod str;
|
||||
pub mod tuple;
|
||||
|
@ -1,4 +1,9 @@
|
||||
use crate::codegen::{irrt::call_nac3_ndarray_index, model::*, CodeGenContext, CodeGenerator};
|
||||
use crate::codegen::{
|
||||
irrt::call_nac3_ndarray_index,
|
||||
model::*,
|
||||
object::slice::{RustSlice, Slice},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
|
||||
use super::NDArrayObject;
|
||||
|
||||
@ -23,86 +28,11 @@ impl<'ctx> StructKind<'ctx> for NDIndex {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fields of [`Slice`]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SliceFields<'ctx, F: FieldTraversal<'ctx>> {
|
||||
pub start_defined: F::Out<Int<Bool>>,
|
||||
pub start: F::Out<Int<Int32>>,
|
||||
pub stop_defined: F::Out<Int<Bool>>,
|
||||
pub stop: F::Out<Int<Int32>>,
|
||||
pub step_defined: F::Out<Int<Bool>>,
|
||||
pub step: F::Out<Int<Int32>>,
|
||||
}
|
||||
|
||||
/// An IRRT representation of an (unresolved) slice.
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
pub struct Slice;
|
||||
|
||||
impl<'ctx> StructKind<'ctx> for Slice {
|
||||
type Fields<F: FieldTraversal<'ctx>> = SliceFields<'ctx, F>;
|
||||
|
||||
fn traverse_fields<F: FieldTraversal<'ctx>>(&self, traversal: &mut F) -> Self::Fields<F> {
|
||||
Self::Fields {
|
||||
start_defined: traversal.add_auto("start_defined"),
|
||||
start: traversal.add_auto("start"),
|
||||
stop_defined: traversal.add_auto("stop_defined"),
|
||||
stop: traversal.add_auto("stop"),
|
||||
step_defined: traversal.add_auto("step_defined"),
|
||||
step: traversal.add_auto("step"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A convenience structure to prepare a [`Slice`].
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RustSlice<'ctx> {
|
||||
pub start: Option<Instance<'ctx, Int<Int32>>>,
|
||||
pub stop: Option<Instance<'ctx, Int<Int32>>>,
|
||||
pub step: Option<Instance<'ctx, Int<Int32>>>,
|
||||
}
|
||||
|
||||
impl<'ctx> RustSlice<'ctx> {
|
||||
/// Write the contents to an LLVM [`Slice`].
|
||||
pub fn write_to_slice<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
dst_slice_ptr: Instance<'ctx, Ptr<Struct<Slice>>>,
|
||||
) {
|
||||
let false_ = Int(Bool).const_false(generator, ctx.ctx);
|
||||
let true_ = Int(Bool).const_true(generator, ctx.ctx);
|
||||
|
||||
match self.start {
|
||||
Some(start) => {
|
||||
dst_slice_ptr.gep(ctx, |f| f.start_defined).store(ctx, true_);
|
||||
dst_slice_ptr.gep(ctx, |f| f.start).store(ctx, start);
|
||||
}
|
||||
None => dst_slice_ptr.gep(ctx, |f| f.start_defined).store(ctx, false_),
|
||||
}
|
||||
|
||||
match self.stop {
|
||||
Some(stop) => {
|
||||
dst_slice_ptr.gep(ctx, |f| f.stop_defined).store(ctx, true_);
|
||||
dst_slice_ptr.gep(ctx, |f| f.stop).store(ctx, stop);
|
||||
}
|
||||
None => dst_slice_ptr.gep(ctx, |f| f.stop_defined).store(ctx, false_),
|
||||
}
|
||||
|
||||
match self.step {
|
||||
Some(step) => {
|
||||
dst_slice_ptr.gep(ctx, |f| f.step_defined).store(ctx, true_);
|
||||
dst_slice_ptr.gep(ctx, |f| f.step).store(ctx, step);
|
||||
}
|
||||
None => dst_slice_ptr.gep(ctx, |f| f.step_defined).store(ctx, false_),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A convenience enum to prepare an [`NDIndex`].
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum RustNDIndex<'ctx> {
|
||||
SingleElement(Instance<'ctx, Int<Int32>>), // TODO: To be SizeT
|
||||
Slice(RustSlice<'ctx>),
|
||||
Slice(RustSlice<'ctx, Int32>), // TODO: To be SizeT
|
||||
NewAxis,
|
||||
Ellipsis,
|
||||
}
|
||||
@ -143,7 +73,7 @@ impl<'ctx> RustNDIndex<'ctx> {
|
||||
.store(ctx, index_ptr.pointer_cast(generator, ctx, Int(Byte)));
|
||||
}
|
||||
RustNDIndex::Slice(in_rust_slice) => {
|
||||
let user_slice_ptr = Struct(Slice).alloca(generator, ctx);
|
||||
let user_slice_ptr = Struct(Slice(Int32)).alloca(generator, ctx);
|
||||
in_rust_slice.write_to_slice(generator, ctx, user_slice_ptr);
|
||||
|
||||
dst_ndindex_ptr
|
||||
|
82
nac3core/src/codegen/object/slice.rs
Normal file
82
nac3core/src/codegen/object/slice.rs
Normal file
@ -0,0 +1,82 @@
|
||||
use crate::codegen::{model::*, CodeGenContext, CodeGenerator};
|
||||
|
||||
/// Fields of [`Slice`]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SliceFields<'ctx, F: FieldTraversal<'ctx>, N: IntKind<'ctx>> {
|
||||
pub start_defined: F::Out<Int<Bool>>,
|
||||
pub start: F::Out<Int<N>>,
|
||||
pub stop_defined: F::Out<Int<Bool>>,
|
||||
pub stop: F::Out<Int<N>>,
|
||||
pub step_defined: F::Out<Int<Bool>>,
|
||||
pub step: F::Out<Int<N>>,
|
||||
}
|
||||
|
||||
/// An IRRT representation of an (unresolved) slice.
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
pub struct Slice<N>(pub N);
|
||||
|
||||
impl<'ctx, N: IntKind<'ctx>> StructKind<'ctx> for Slice<N> {
|
||||
type Fields<F: FieldTraversal<'ctx>> = SliceFields<'ctx, F, N>;
|
||||
|
||||
fn traverse_fields<F: FieldTraversal<'ctx>>(&self, traversal: &mut F) -> Self::Fields<F> {
|
||||
Self::Fields {
|
||||
start_defined: traversal.add_auto("start_defined"),
|
||||
start: traversal.add("start", Int(self.0)),
|
||||
stop_defined: traversal.add_auto("stop_defined"),
|
||||
stop: traversal.add("stop", Int(self.0)),
|
||||
step_defined: traversal.add_auto("step_defined"),
|
||||
step: traversal.add("step", Int(self.0)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A Rust structure that has [`Slice`] utilities and looks like a [`Slice`] but
|
||||
/// `start`, `stop` and `step` are held by LLVM registers only and possibly
|
||||
/// [`Option::None`] if unspecified.
|
||||
///
|
||||
/// This structure exists because many implementations use [`Slice`] utilities but
|
||||
/// it might not be good to alloca an actual [`Slice`] value on the stack in order
|
||||
/// to perform calculations.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RustSlice<'ctx, N: IntKind<'ctx>> {
|
||||
pub start: Option<Instance<'ctx, Int<N>>>,
|
||||
pub stop: Option<Instance<'ctx, Int<N>>>,
|
||||
pub step: Option<Instance<'ctx, Int<N>>>,
|
||||
}
|
||||
|
||||
impl<'ctx, N: IntKind<'ctx>> RustSlice<'ctx, N> {
|
||||
/// Write the contents to an LLVM [`Slice`].
|
||||
pub fn write_to_slice<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
dst_slice_ptr: Instance<'ctx, Ptr<Struct<Slice<N>>>>,
|
||||
) {
|
||||
let false_ = Int(Bool).const_false(generator, ctx.ctx);
|
||||
let true_ = Int(Bool).const_true(generator, ctx.ctx);
|
||||
|
||||
match self.start {
|
||||
Some(start) => {
|
||||
dst_slice_ptr.gep(ctx, |f| f.start_defined).store(ctx, true_);
|
||||
dst_slice_ptr.gep(ctx, |f| f.start).store(ctx, start);
|
||||
}
|
||||
None => dst_slice_ptr.gep(ctx, |f| f.start_defined).store(ctx, false_),
|
||||
}
|
||||
|
||||
match self.stop {
|
||||
Some(stop) => {
|
||||
dst_slice_ptr.gep(ctx, |f| f.stop_defined).store(ctx, true_);
|
||||
dst_slice_ptr.gep(ctx, |f| f.stop).store(ctx, stop);
|
||||
}
|
||||
None => dst_slice_ptr.gep(ctx, |f| f.stop_defined).store(ctx, false_),
|
||||
}
|
||||
|
||||
match self.step {
|
||||
Some(step) => {
|
||||
dst_slice_ptr.gep(ctx, |f| f.step_defined).store(ctx, true_);
|
||||
dst_slice_ptr.gep(ctx, |f| f.step).store(ctx, step);
|
||||
}
|
||||
None => dst_slice_ptr.gep(ctx, |f| f.step_defined).store(ctx, false_),
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user