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]]
|
[[package]]
|
||||||
name = "inkwell"
|
name = "inkwell"
|
||||||
version = "0.4.0"
|
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 = [
|
dependencies = [
|
||||||
"either",
|
"either",
|
||||||
"inkwell_internals",
|
"inkwell_internals",
|
||||||
|
@ -520,7 +520,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inkwell_internals"
|
name = "inkwell_internals"
|
||||||
version = "0.9.0"
|
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 = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"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_parser = { version = "0.0.1-alpha.18", path = "../edlang_parser" }
|
||||||
edlang_session = { version = "0.0.1-alpha.18", path = "../edlang_session" }
|
edlang_session = { version = "0.0.1-alpha.18", path = "../edlang_session" }
|
||||||
llvm-sys = "180.0"
|
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 }
|
tracing = { workspace = true }
|
||||||
edlang_span = { version = "0.0.1-alpha.18", path = "../edlang_span" }
|
edlang_span = { version = "0.0.1-alpha.18", path = "../edlang_span" }
|
||||||
|
|
|
@ -21,7 +21,7 @@ use inkwell::{
|
||||||
values::{BasicValue, BasicValueEnum, PointerValue},
|
values::{BasicValue, BasicValueEnum, PointerValue},
|
||||||
AddressSpace,
|
AddressSpace,
|
||||||
};
|
};
|
||||||
use ir::{LocalKind, ModuleBody, Place, ProgramBody, TypeInfo, ValueTree};
|
use ir::{LocalKind, ModuleBody, ProgramBody, TypeInfo, TypeKind, ValueTree};
|
||||||
use llvm_sys::debuginfo::LLVMDIFlagPublic;
|
use llvm_sys::debuginfo::LLVMDIFlagPublic;
|
||||||
use tracing::{info, trace};
|
use tracing::{info, trace};
|
||||||
|
|
||||||
|
@ -462,43 +462,46 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError>
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ir::PlaceElem::Index { local } => {
|
ir::PlaceElem::Index { value } => {
|
||||||
let value = compile_load_place(
|
let (value, _ty) = compile_rvalue(ctx, fn_id, &locals, value)?;
|
||||||
ctx,
|
|
||||||
fn_id,
|
|
||||||
&locals,
|
|
||||||
&Place {
|
|
||||||
local: *local,
|
|
||||||
projection: Default::default(),
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
ptr = unsafe {
|
ptr = unsafe {
|
||||||
ctx.builder.build_in_bounds_gep(
|
ctx.builder.build_in_bounds_gep(
|
||||||
ptr.get_type(),
|
compile_basic_type(ctx, &local_ty),
|
||||||
ptr,
|
ptr,
|
||||||
&[
|
&[
|
||||||
ctx.ctx.context.i32_type().const_int(0, false),
|
ctx.ctx.context.i32_type().const_int(0, false),
|
||||||
value.0.into_int_value(),
|
value.into_int_value(),
|
||||||
],
|
],
|
||||||
"constindex",
|
"constindex",
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
local_ty = match local_ty.kind {
|
||||||
|
ir::TypeKind::Slice(inner, _) => (*inner).clone(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ir::PlaceElem::ConstIndex { index } => {
|
ir::PlaceElem::ConstIndex { index } => {
|
||||||
ptr = unsafe {
|
ptr = unsafe {
|
||||||
ctx.builder.build_in_bounds_gep(
|
ctx.builder.build_in_bounds_gep(
|
||||||
ptr.get_type(),
|
compile_basic_type(ctx, &local_ty),
|
||||||
ptr,
|
ptr,
|
||||||
&[ctx
|
&[
|
||||||
.ctx
|
ctx.ctx.context.i32_type().const_int(0, false),
|
||||||
.context
|
ctx.ctx
|
||||||
.i32_type()
|
.context
|
||||||
.const_int((*index) as u64, false)],
|
.i32_type()
|
||||||
|
.const_int((*index) as u64, false),
|
||||||
|
],
|
||||||
"constindex",
|
"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")?
|
.build_load(compile_basic_type(ctx, &local_ty), ptr, "deref")?
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
}
|
}
|
||||||
ir::PlaceElem::Field { .. } => todo!(),
|
ir::PlaceElem::Field { field_idx } => {
|
||||||
ir::PlaceElem::Index { .. } => todo!(),
|
local_ty = match local_ty.kind {
|
||||||
ir::PlaceElem::ConstIndex { .. } => todo!(),
|
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 target_llvm_ty = compile_basic_type(ctx, &target_ty);
|
||||||
let (value, ty) = compile_load_operand(ctx, fn_id, locals, op)?;
|
let (value, ty) = compile_load_operand(ctx, fn_id, locals, op)?;
|
||||||
let current_ty = compile_basic_type(ctx, &ty);
|
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
|
// int to ptr
|
||||||
let target_llvm_ty = target_llvm_ty.into_pointer_type();
|
let target_llvm_ty = target_llvm_ty.into_pointer_type();
|
||||||
if current_ty.is_int_type() {
|
if current_ty.is_int_type() {
|
||||||
|
@ -1265,8 +1325,44 @@ fn compile_load_place<'ctx>(
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ir::PlaceElem::Index { .. } => todo!(),
|
ir::PlaceElem::Index { value } => {
|
||||||
ir::PlaceElem::ConstIndex { .. } => todo!(),
|
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)
|
write!(f, "*{word} {}", inner.kind)
|
||||||
}
|
}
|
||||||
TypeKind::Ref(is_mut, inner) => {
|
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::Struct(_, name) => write!(f, "{}", name),
|
||||||
TypeKind::Slice(inner, size) => {
|
TypeKind::Slice(inner, size) => {
|
||||||
|
@ -483,11 +483,11 @@ pub struct Place {
|
||||||
pub projection: SmallVec<[PlaceElem; 1]>,
|
pub projection: SmallVec<[PlaceElem; 1]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum PlaceElem {
|
pub enum PlaceElem {
|
||||||
Deref,
|
Deref,
|
||||||
Field { field_idx: usize },
|
Field { field_idx: usize },
|
||||||
Index { local: usize },
|
Index { value: Box<RValue> },
|
||||||
ConstIndex { index: usize },
|
ConstIndex { index: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1357,7 +1357,30 @@ fn lower_path(
|
||||||
unimplemented!()
|
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 } => {
|
ast::PathSegment::Method { value, span } => {
|
||||||
// is while fine? auto deref
|
// is while fine? auto deref
|
||||||
while let TypeKind::Ref(_, inner) = ty {
|
while let TypeKind::Ref(_, inner) = ty {
|
||||||
|
|
Loading…
Reference in a new issue