Get arrays to compile while still not supporting mutability for a bit

This commit is contained in:
Sofia 2025-07-13 22:04:49 +03:00
parent d62d6e2845
commit 312a777203
4 changed files with 95 additions and 41 deletions

View File

@ -282,7 +282,7 @@ impl Builder {
Extract(arr, idx) => {
let arr_ty = arr.get_type(&self)?;
if let Type::Array(_, len) = arr_ty {
if len < idx { Ok(()) } else { Err(()) }
if len > idx { Ok(()) } else { Err(()) }
} else {
Err(())
}
@ -292,7 +292,7 @@ impl Builder {
let arr_ty = arr.get_type(&self)?;
let val_ty = val.get_type(&self)?;
if let Type::Array(elem_ty, len) = arr_ty {
if val_ty == *elem_ty && len < idx {
if val_ty == *elem_ty && len > idx {
Ok(())
} else {
Err(())

View File

@ -349,14 +349,33 @@ impl InstructionHolder {
module.values.get(&val).unwrap().value_ref,
module.values.get(&ptr).unwrap().value_ref,
),
Extract(instruction_value, idx) => LLVMBuildExtractValue(
Extract(arr, idx) => {
let t = arr.get_type(module.builder).unwrap();
let Type::Array(elem_t, _) = t else { panic!() };
let indices = &mut [ConstValue::I32(*idx as i32).as_llvm(module.context_ref)];
let ptr = LLVMBuildGEP2(
module.builder_ref,
module.values.get(instruction_value).unwrap().value_ref,
*idx as u32,
c"extract".as_ptr(),
),
elem_t.as_llvm(module.context_ref),
module.values.get(arr).unwrap().value_ref,
indices.as_mut_ptr(),
1,
c"insert_gep".as_ptr(),
);
LLVMBuildLoad2(
module.builder_ref,
elem_t.as_llvm(module.context_ref),
ptr,
c"load".as_ptr(),
)
}
ArrayAlloca(ty, len) => {
let array_len = ConstValue::U16(*len as u16).as_llvm(module.context_ref);
let array_ty = Type::Array(Box::new(ty.clone()), *len);
dbg!(
&ty.as_llvm(module.context_ref),
&array_ty.as_llvm(module.context_ref)
);
LLVMBuildArrayAlloca(
module.builder_ref,
ty.as_llvm(module.context_ref),
@ -364,13 +383,32 @@ impl InstructionHolder {
c"array_alloca".as_ptr(),
)
}
Insert(arr, idx, val) => LLVMBuildInsertValue(
Insert(arr, idx, val) => {
let indices = &mut [ConstValue::I32(*idx as i32).as_llvm(module.context_ref)];
let ptr = LLVMBuildGEP2(
module.builder_ref,
val.get_type(module.builder)
.unwrap()
.as_llvm(module.context_ref),
module.values.get(arr).unwrap().value_ref,
indices.as_mut_ptr(),
1,
c"insert_gep".as_ptr(),
);
LLVMBuildStore(
module.builder_ref,
module.values.get(val).unwrap().value_ref,
*idx,
c"insert".as_ptr(),
),
ptr,
)
// LLVMBuildInsertValue(
// module.builder_ref,
// ptr,
// module.values.get(val).unwrap().value_ref,
// *idx,
// c"insert".as_ptr(),
// )
}
}
};
LLVMValue {
@ -449,26 +487,6 @@ impl ConstValue {
ConstValue::U32(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U64(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U128(val) => LLVMConstInt(t, *val as u64, 1),
// ConstValue::Array(const_values) => {
// let elem_ty = const_values
// .iter()
// .map(|e| e.get_type(builder))
// .next()
// .unwrap_or(Ok(Type::Void))
// .unwrap();
// let mut elems = const_values
// .iter()
// .map(|e| e.as_llvm(context))
// .collect::<Vec<_>>();
// LLVMConstArray(
// elem_ty.as_llvm(context),
// elems.as_mut_ptr(),
// elems.len() as u32,
// )
// }
// }
}
}
}
@ -487,7 +505,7 @@ impl Type {
Bool => LLVMInt1TypeInContext(context),
Void => LLVMVoidType(),
Ptr(ty) => LLVMPointerType(ty.as_llvm(context), 0),
Array(elem_t, len) => LLVMArrayType(elem_t.as_llvm(context), *len as u32),
Array(elem_t, _) => LLVMPointerType(elem_t.as_llvm(context), 0),
}
}
}

View File

@ -1,7 +1,7 @@
// Arithmetic, function calls and imports!
fn array() -> [u16; 4] {
return [1, 2, 3, 4];
return [10, 15, 7, 9];
}
fn main() -> u16 {
@ -11,5 +11,5 @@ fn main() -> u16 {
// list[1] = 5;
return list[0];
return list[3];
}

View File

@ -334,8 +334,44 @@ impl mir::Expression {
None
}
}
mir::ExprKind::Index(expression, _) => todo!("codegen for index expression"),
mir::ExprKind::Array(expressions) => todo!("codegen for array expression"),
mir::ExprKind::Index(expression, idx) => {
let expr = expression.codegen(scope)?;
Some(
scope
.block
.build(Instr::Extract(expr, *idx as u32))
.unwrap(),
)
}
mir::ExprKind::Array(expressions) => {
let instr_list = expressions
.iter()
.map(|e| e.codegen(scope).unwrap())
.collect::<Vec<_>>();
let instr_t = expressions
.iter()
.map(|e| e.return_type().unwrap().1)
.next()
.unwrap_or(TypeKind::Void);
dbg!(&instr_t);
let array = scope
.block
.build(Instr::ArrayAlloca(
instr_t.get_type(),
instr_list.len() as u32,
))
.unwrap();
for (i, instr) in instr_list.iter().enumerate() {
scope
.block
.build(Instr::Insert(array, i as u32, *instr))
.unwrap();
}
Some(array)
}
}
}
}
@ -414,9 +450,9 @@ impl TypeKind {
TypeKind::U64 => Type::U64,
TypeKind::U128 => Type::U128,
TypeKind::Bool => Type::Bool,
TypeKind::Array(elem_t, len) => Type::Array(Box::new(elem_t.get_type()), *len as u32),
TypeKind::Void => panic!("Void not a supported type"),
TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
TypeKind::Array(_, _) => todo!("codegen for array type"),
}
}
}