core: move gen_slice to object/slice.rs and refactor

This commit is contained in:
lyken 2024-08-25 20:25:04 +08:00
parent b38d9000f8
commit a1410833bc
No known key found for this signature in database
GPG Key ID: 3BD5FC6AC8325DD8
3 changed files with 48 additions and 43 deletions

View File

@ -3111,42 +3111,3 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
_ => unimplemented!(), _ => unimplemented!(),
})) }))
} }
/// Generate LLVM IR for an [`ExprKind::Slice`]
#[allow(clippy::type_complexity)]
pub fn gen_slice<'ctx, G: CodeGenerator>(
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
lower: &Option<Box<Expr<Option<Type>>>>,
upper: &Option<Box<Expr<Option<Type>>>>,
step: &Option<Box<Expr<Option<Type>>>>,
) -> Result<
(
Option<Instance<'ctx, Int<Int32>>>,
Option<Instance<'ctx, Int<Int32>>>,
Option<Instance<'ctx, Int<Int32>>>,
),
String,
> {
let mut help = |value_expr: &Option<Box<Expr<Option<Type>>>>| -> Result<_, String> {
Ok(match value_expr {
None => None,
Some(value_expr) => {
let value_expr = generator
.gen_expr(ctx, value_expr)?
.unwrap()
.to_basic_value_enum(ctx, generator, ctx.primitives.int32)?;
let value_expr = Int(Int32).check_value(generator, ctx.ctx, value_expr).unwrap();
Some(value_expr)
}
})
};
let lower = help(lower)?;
let upper = help(upper)?;
let step = help(step)?;
Ok((lower, upper, step))
}

View File

@ -155,11 +155,11 @@ pub mod util {
use nac3parser::ast::{Expr, ExprKind}; use nac3parser::ast::{Expr, ExprKind};
use crate::{ use crate::{
codegen::{expr::gen_slice, model::*, CodeGenContext, CodeGenerator}, codegen::{model::*, object::slice::util::gen_slice, CodeGenContext, CodeGenerator},
typecheck::typedef::Type, typecheck::typedef::Type,
}; };
use super::{RustNDIndex, RustSlice}; use super::RustNDIndex;
/// Generate LLVM code to transform an ndarray subscript expression to /// Generate LLVM code to transform an ndarray subscript expression to
/// its list of [`RustNDIndex`] /// its list of [`RustNDIndex`]
@ -203,8 +203,8 @@ pub mod util {
// so the code/implementation looks awkward - we have to do pattern matching on the expression // so the code/implementation looks awkward - we have to do pattern matching on the expression
let ndindex = if let ExprKind::Slice { lower, upper, step } = &index_expr.node { let ndindex = if let ExprKind::Slice { lower, upper, step } = &index_expr.node {
// Handle slices // Handle slices
let (lower, upper, step) = gen_slice(generator, ctx, lower, upper, step)?; let slice = gen_slice(generator, ctx, lower, upper, step)?;
RustNDIndex::Slice(RustSlice { start: lower, stop: upper, step }) RustNDIndex::Slice(slice)
} else { } else {
// Treat and handle everything else as a single element index. // Treat and handle everything else as a single element index.
let index = generator.gen_expr(ctx, index_expr)?.unwrap().to_basic_value_enum( let index = generator.gen_expr(ctx, index_expr)?.unwrap().to_basic_value_enum(

View File

@ -80,3 +80,47 @@ impl<'ctx, N: IntKind<'ctx>> RustSlice<'ctx, N> {
} }
} }
} }
pub mod util {
use nac3parser::ast::Expr;
use crate::{
codegen::{model::*, CodeGenContext, CodeGenerator},
typecheck::typedef::Type,
};
use super::RustSlice;
/// Generate LLVM IR for an [`ExprKind::Slice`] and convert it into a [`RustSlice`].
#[allow(clippy::type_complexity)]
pub fn gen_slice<'ctx, G: CodeGenerator>(
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
lower: &Option<Box<Expr<Option<Type>>>>,
upper: &Option<Box<Expr<Option<Type>>>>,
step: &Option<Box<Expr<Option<Type>>>>,
) -> Result<RustSlice<'ctx, Int32>, String> {
let mut help = |value_expr: &Option<Box<Expr<Option<Type>>>>| -> Result<_, String> {
Ok(match value_expr {
None => None,
Some(value_expr) => {
let value_expr = generator
.gen_expr(ctx, value_expr)?
.unwrap()
.to_basic_value_enum(ctx, generator, ctx.primitives.int32)?;
let value_expr =
Int(Int32).check_value(generator, ctx.ctx, value_expr).unwrap();
Some(value_expr)
}
})
};
let start = help(lower)?;
let stop = help(upper)?;
let step = help(step)?;
Ok(RustSlice { start, stop, step })
}
}