mirror of
https://github.com/edg-l/edlang.git
synced 2024-09-07 19:35:16 +00:00
array indexing
This commit is contained in:
parent
a6d4bee05a
commit
3e885063df
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -507,7 +507,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "inkwell"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/TheDan64/inkwell?rev=5d5a531c765a6ad37aa6591c0287d0f9109fff62#5d5a531c765a6ad37aa6591c0287d0f9109fff62"
|
||||
source = "git+https://github.com/TheDan64/inkwell?rev=6c0fb56b3554e939f9ca61b465043d6a84fb7b95#6c0fb56b3554e939f9ca61b465043d6a84fb7b95"
|
||||
dependencies = [
|
||||
"either",
|
||||
"inkwell_internals",
|
||||
|
@ -520,7 +520,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "inkwell_internals"
|
||||
version = "0.9.0"
|
||||
source = "git+https://github.com/TheDan64/inkwell?rev=5d5a531c765a6ad37aa6591c0287d0f9109fff62#5d5a531c765a6ad37aa6591c0287d0f9109fff62"
|
||||
source = "git+https://github.com/TheDan64/inkwell?rev=6c0fb56b3554e939f9ca61b465043d6a84fb7b95#6c0fb56b3554e939f9ca61b465043d6a84fb7b95"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -17,6 +17,6 @@ edlang_ir = { version = "0.0.1-alpha.18", path = "../edlang_ir" }
|
|||
edlang_parser = { version = "0.0.1-alpha.18", path = "../edlang_parser" }
|
||||
edlang_session = { version = "0.0.1-alpha.18", path = "../edlang_session" }
|
||||
llvm-sys = "180.0"
|
||||
inkwell = { git = "https://github.com/TheDan64/inkwell", rev = "5d5a531c765a6ad37aa6591c0287d0f9109fff62", features = ["llvm18-0"] }
|
||||
inkwell = { git = "https://github.com/TheDan64/inkwell", rev = "6c0fb56b3554e939f9ca61b465043d6a84fb7b95", features = ["llvm18-0"] }
|
||||
tracing = { workspace = true }
|
||||
edlang_span = { version = "0.0.1-alpha.18", path = "../edlang_span" }
|
||||
|
|
|
@ -21,7 +21,7 @@ use inkwell::{
|
|||
values::{BasicValue, BasicValueEnum, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use ir::{LocalKind, ModuleBody, Place, ProgramBody, TypeInfo, ValueTree};
|
||||
use ir::{LocalKind, ModuleBody, ProgramBody, TypeInfo, TypeKind, ValueTree};
|
||||
use llvm_sys::debuginfo::LLVMDIFlagPublic;
|
||||
use tracing::{info, trace};
|
||||
|
||||
|
@ -462,43 +462,46 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError>
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
ir::PlaceElem::Index { local } => {
|
||||
let value = compile_load_place(
|
||||
ctx,
|
||||
fn_id,
|
||||
&locals,
|
||||
&Place {
|
||||
local: *local,
|
||||
projection: Default::default(),
|
||||
},
|
||||
false,
|
||||
)?;
|
||||
ir::PlaceElem::Index { value } => {
|
||||
let (value, _ty) = compile_rvalue(ctx, fn_id, &locals, value)?;
|
||||
|
||||
ptr = unsafe {
|
||||
ctx.builder.build_in_bounds_gep(
|
||||
ptr.get_type(),
|
||||
compile_basic_type(ctx, &local_ty),
|
||||
ptr,
|
||||
&[
|
||||
ctx.ctx.context.i32_type().const_int(0, false),
|
||||
value.0.into_int_value(),
|
||||
value.into_int_value(),
|
||||
],
|
||||
"constindex",
|
||||
)?
|
||||
};
|
||||
|
||||
local_ty = match local_ty.kind {
|
||||
ir::TypeKind::Slice(inner, _) => (*inner).clone(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
ir::PlaceElem::ConstIndex { index } => {
|
||||
ptr = unsafe {
|
||||
ctx.builder.build_in_bounds_gep(
|
||||
ptr.get_type(),
|
||||
compile_basic_type(ctx, &local_ty),
|
||||
ptr,
|
||||
&[ctx
|
||||
.ctx
|
||||
.context
|
||||
.i32_type()
|
||||
.const_int((*index) as u64, false)],
|
||||
&[
|
||||
ctx.ctx.context.i32_type().const_int(0, false),
|
||||
ctx.ctx
|
||||
.context
|
||||
.i32_type()
|
||||
.const_int((*index) as u64, false),
|
||||
],
|
||||
"constindex",
|
||||
)?
|
||||
};
|
||||
|
||||
local_ty = match local_ty.kind {
|
||||
ir::TypeKind::Slice(inner, _) => (*inner).clone(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1073,9 +1076,65 @@ fn compile_rvalue<'ctx>(
|
|||
.build_load(compile_basic_type(ctx, &local_ty), ptr, "deref")?
|
||||
.into_pointer_value();
|
||||
}
|
||||
ir::PlaceElem::Field { .. } => todo!(),
|
||||
ir::PlaceElem::Index { .. } => todo!(),
|
||||
ir::PlaceElem::ConstIndex { .. } => todo!(),
|
||||
ir::PlaceElem::Field { field_idx } => {
|
||||
local_ty = match local_ty.kind {
|
||||
ir::TypeKind::Struct(id, _) => {
|
||||
let struct_body = ctx.ctx.program.structs.get(&id).unwrap();
|
||||
let ty = struct_body.variants[*field_idx].ty.clone();
|
||||
let field_name =
|
||||
struct_body.variants[*field_idx].name.clone();
|
||||
ptr = ctx.builder.build_struct_gep(
|
||||
compile_basic_type(ctx, &local_ty),
|
||||
ptr,
|
||||
(*field_idx).try_into().unwrap(),
|
||||
&format!("ptr_field_{field_name}"),
|
||||
)?;
|
||||
ty
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
ir::PlaceElem::Index { value } => {
|
||||
let (value, _ty) = compile_rvalue(ctx, fn_id, &locals, value)?;
|
||||
|
||||
ptr = unsafe {
|
||||
ctx.builder.build_in_bounds_gep(
|
||||
compile_basic_type(ctx, &local_ty),
|
||||
ptr,
|
||||
&[
|
||||
ctx.ctx.context.i32_type().const_int(0, false),
|
||||
value.into_int_value(),
|
||||
],
|
||||
"constindex",
|
||||
)?
|
||||
};
|
||||
|
||||
local_ty = match local_ty.kind {
|
||||
ir::TypeKind::Slice(inner, _) => (*inner).clone(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
ir::PlaceElem::ConstIndex { index } => {
|
||||
ptr = unsafe {
|
||||
ctx.builder.build_in_bounds_gep(
|
||||
compile_basic_type(ctx, &local_ty),
|
||||
ptr,
|
||||
&[
|
||||
ctx.ctx.context.i32_type().const_int(0, false),
|
||||
ctx.ctx
|
||||
.context
|
||||
.i32_type()
|
||||
.const_int((*index) as u64, false),
|
||||
],
|
||||
"constindex",
|
||||
)?
|
||||
};
|
||||
|
||||
local_ty = match local_ty.kind {
|
||||
ir::TypeKind::Slice(inner, _) => (*inner).clone(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1118,8 +1177,9 @@ fn compile_rvalue<'ctx>(
|
|||
let target_llvm_ty = compile_basic_type(ctx, &target_ty);
|
||||
let (value, ty) = compile_load_operand(ctx, fn_id, locals, op)?;
|
||||
let current_ty = compile_basic_type(ctx, &ty);
|
||||
let is_ptr = matches!(ty.kind, TypeKind::Ptr(_, _) | TypeKind::Ref(_, _));
|
||||
|
||||
if target_llvm_ty.is_pointer_type() {
|
||||
if is_ptr {
|
||||
// int to ptr
|
||||
let target_llvm_ty = target_llvm_ty.into_pointer_type();
|
||||
if current_ty.is_int_type() {
|
||||
|
@ -1265,8 +1325,44 @@ fn compile_load_place<'ctx>(
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
ir::PlaceElem::Index { .. } => todo!(),
|
||||
ir::PlaceElem::ConstIndex { .. } => todo!(),
|
||||
ir::PlaceElem::Index { value } => {
|
||||
let (value, _ty) = compile_rvalue(ctx, fn_id, locals, value)?;
|
||||
|
||||
ptr = unsafe {
|
||||
ctx.builder.build_in_bounds_gep(
|
||||
compile_basic_type(ctx, &local_ty),
|
||||
ptr,
|
||||
&[
|
||||
ctx.ctx.context.i32_type().const_int(0, false),
|
||||
value.into_int_value(),
|
||||
],
|
||||
"constindex",
|
||||
)?
|
||||
};
|
||||
|
||||
local_ty = match local_ty.kind {
|
||||
ir::TypeKind::Slice(inner, _) => (*inner).clone(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
ir::PlaceElem::ConstIndex { index } => {
|
||||
ptr = unsafe {
|
||||
ctx.builder.build_in_bounds_gep(
|
||||
compile_basic_type(ctx, &local_ty),
|
||||
ptr,
|
||||
&[
|
||||
ctx.ctx.context.i32_type().const_int(0, false),
|
||||
ctx.ctx.context.i32_type().const_int((*index) as u64, false),
|
||||
],
|
||||
"constindex",
|
||||
)?
|
||||
};
|
||||
|
||||
local_ty = match local_ty.kind {
|
||||
ir::TypeKind::Slice(inner, _) => (*inner).clone(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -348,9 +348,9 @@ impl fmt::Display for TypeKind {
|
|||
write!(f, "*{word} {}", inner.kind)
|
||||
}
|
||||
TypeKind::Ref(is_mut, inner) => {
|
||||
let word = if *is_mut { "mut" } else { "const" };
|
||||
let word = if *is_mut { "mut " } else { "" };
|
||||
|
||||
write!(f, "&{word} {}", inner.kind)
|
||||
write!(f, "&{word}{}", inner.kind)
|
||||
}
|
||||
TypeKind::Struct(_, name) => write!(f, "{}", name),
|
||||
TypeKind::Slice(inner, size) => {
|
||||
|
@ -483,11 +483,11 @@ pub struct Place {
|
|||
pub projection: SmallVec<[PlaceElem; 1]>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PlaceElem {
|
||||
Deref,
|
||||
Field { field_idx: usize },
|
||||
Index { local: usize },
|
||||
Index { value: Box<RValue> },
|
||||
ConstIndex { index: usize },
|
||||
}
|
||||
|
||||
|
|
|
@ -1357,7 +1357,30 @@ fn lower_path(
|
|||
unimplemented!()
|
||||
}
|
||||
}
|
||||
ast::PathSegment::Index { .. } => todo!(),
|
||||
ast::PathSegment::Index { value, span: _ } => {
|
||||
// auto deref
|
||||
while let TypeKind::Ref(_, inner) = ty {
|
||||
place.projection.push(PlaceElem::Deref);
|
||||
ty = inner.kind;
|
||||
}
|
||||
|
||||
if let ast::Expression::Value(ast::ValueExpr::Int { value, span: _ }) = value {
|
||||
place.projection.push(PlaceElem::ConstIndex {
|
||||
index: (*value).try_into().unwrap(),
|
||||
});
|
||||
} else {
|
||||
let (rvalue, _ty, _span) = lower_expr(builder, value, None)?;
|
||||
place.projection.push(PlaceElem::Index {
|
||||
value: Box::new(rvalue),
|
||||
});
|
||||
}
|
||||
|
||||
ty = if let TypeKind::Slice(inner, _) = ty {
|
||||
inner.kind.clone()
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
ast::PathSegment::Method { value, span } => {
|
||||
// is while fine? auto deref
|
||||
while let TypeKind::Ref(_, inner) = ty {
|
||||
|
|
Loading…
Reference in a new issue