Implement GEP instead of the weird thing before
This commit is contained in:
parent
312a777203
commit
cbb1be1161
@ -270,6 +270,7 @@ impl Builder {
|
||||
}
|
||||
Store(ptr, _) => {
|
||||
if let Ok(ty) = ptr.get_type(&self) {
|
||||
dbg!(&ty);
|
||||
if let Type::Ptr(_) = ty {
|
||||
Ok(())
|
||||
} else {
|
||||
@ -279,24 +280,11 @@ impl Builder {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
Extract(arr, idx) => {
|
||||
let arr_ty = arr.get_type(&self)?;
|
||||
if let Type::Array(_, len) = arr_ty {
|
||||
if len > idx { Ok(()) } else { Err(()) }
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
ArrayAlloca(_, _) => Ok(()),
|
||||
Insert(arr, idx, val) => {
|
||||
ArrayGEP(arr, _) => {
|
||||
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 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
if let Type::ArrayPtr(_, _) = arr_ty {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
@ -362,15 +350,14 @@ impl InstructionValue {
|
||||
Alloca(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
|
||||
Load(_, ty) => Ok(ty.clone()),
|
||||
Store(_, value) => value.get_type(builder),
|
||||
Extract(arr, _) => match arr.get_type(builder) {
|
||||
Ok(Type::Array(elem_t, _)) => Ok(*elem_t),
|
||||
ArrayAlloca(ty, len_value) => {
|
||||
Ok(Type::ArrayPtr(Box::new(ty.clone()), len_value.clone()))
|
||||
}
|
||||
ArrayGEP(arr, _) => match arr.get_type(builder) {
|
||||
Ok(Type::ArrayPtr(elem_t, _)) => Ok(Type::Ptr(Box::new(*elem_t))),
|
||||
Ok(_) => Err(()),
|
||||
Err(_) => Err(()),
|
||||
},
|
||||
ArrayAlloca(ty, len_value) => {
|
||||
Ok(Type::Array(Box::new(ty.clone()), len_value.clone()))
|
||||
}
|
||||
Insert(_, _, val) => val.get_type(builder),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -391,15 +378,6 @@ impl ConstValue {
|
||||
ConstValue::U64(_) => U64,
|
||||
ConstValue::U128(_) => U128,
|
||||
ConstValue::Bool(_) => Bool,
|
||||
// ConstValue::Array(arr) => Array(
|
||||
// Box::new(
|
||||
// arr.iter()
|
||||
// .map(|a| a.get_type(builder).unwrap())
|
||||
// .next()
|
||||
// .unwrap_or(Void),
|
||||
// ),
|
||||
// arr.len() as u32,
|
||||
// ),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -420,7 +398,7 @@ impl Type {
|
||||
Type::Bool => true,
|
||||
Type::Void => false,
|
||||
Type::Ptr(_) => false,
|
||||
Type::Array(_, _) => false,
|
||||
Type::ArrayPtr(_, _) => false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,7 +417,7 @@ impl Type {
|
||||
Type::Bool => false,
|
||||
Type::Void => false,
|
||||
Type::Ptr(_) => false,
|
||||
Type::Array(_, _) => false,
|
||||
Type::ArrayPtr(_, _) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -349,29 +349,9 @@ impl InstructionHolder {
|
||||
module.values.get(&val).unwrap().value_ref,
|
||||
module.values.get(&ptr).unwrap().value_ref,
|
||||
),
|
||||
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,
|
||||
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);
|
||||
let array_ty = Type::ArrayPtr(Box::new(ty.clone()), *len);
|
||||
dbg!(
|
||||
&ty.as_llvm(module.context_ref),
|
||||
&array_ty.as_llvm(module.context_ref)
|
||||
@ -383,31 +363,24 @@ impl InstructionHolder {
|
||||
c"array_alloca".as_ptr(),
|
||||
)
|
||||
}
|
||||
Insert(arr, idx, val) => {
|
||||
let indices = &mut [ConstValue::I32(*idx as i32).as_llvm(module.context_ref)];
|
||||
let ptr = LLVMBuildGEP2(
|
||||
ArrayGEP(arr, indices) => {
|
||||
let t = arr.get_type(module.builder).unwrap();
|
||||
let Type::ArrayPtr(elem_t, _) = t else {
|
||||
panic!()
|
||||
};
|
||||
|
||||
let mut indices: Vec<_> = indices
|
||||
.iter()
|
||||
.map(|idx| ConstValue::U32(*idx).as_llvm(module.context_ref))
|
||||
.collect();
|
||||
LLVMBuildGEP2(
|
||||
module.builder_ref,
|
||||
val.get_type(module.builder)
|
||||
.unwrap()
|
||||
.as_llvm(module.context_ref),
|
||||
elem_t.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,
|
||||
ptr,
|
||||
c"array_gep".as_ptr(),
|
||||
)
|
||||
|
||||
// LLVMBuildInsertValue(
|
||||
// module.builder_ref,
|
||||
// ptr,
|
||||
// module.values.get(val).unwrap().value_ref,
|
||||
// *idx,
|
||||
// c"insert".as_ptr(),
|
||||
// )
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -505,7 +478,7 @@ impl Type {
|
||||
Bool => LLVMInt1TypeInContext(context),
|
||||
Void => LLVMVoidType(),
|
||||
Ptr(ty) => LLVMPointerType(ty.as_llvm(context), 0),
|
||||
Array(elem_t, _) => LLVMPointerType(elem_t.as_llvm(context), 0),
|
||||
ArrayPtr(elem_t, _) => LLVMPointerType(elem_t.as_llvm(context), 0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,11 +100,18 @@ impl Debug for Instr {
|
||||
Instr::Alloca(name, ty) => write!(f, "alloca<{:?}>({})", ty, name),
|
||||
Instr::Load(val, ty) => write!(f, "load<{:?}>({:?})", ty, val),
|
||||
Instr::Store(ptr, val) => write!(f, "store({:?} = {:?})", ptr, val),
|
||||
Instr::Extract(instruction_value, idx) => fmt_index(f, instruction_value, idx),
|
||||
Instr::ArrayAlloca(ty, instruction_value) => {
|
||||
write!(f, "array_alloca<{:?}>({:?})", ty, instruction_value)
|
||||
}
|
||||
Instr::Insert(arr, idx, val) => write!(f, "{:?}[{}] = {:?}", arr, idx, val),
|
||||
Instr::ArrayGEP(instruction_value, items) => fmt_index(
|
||||
f,
|
||||
instruction_value,
|
||||
&items
|
||||
.iter()
|
||||
.map(|i| i.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -178,8 +178,7 @@ pub enum Instr {
|
||||
Load(InstructionValue, Type),
|
||||
Store(InstructionValue, InstructionValue),
|
||||
ArrayAlloca(Type, u32),
|
||||
Insert(InstructionValue, u32, InstructionValue),
|
||||
Extract(InstructionValue, u32),
|
||||
ArrayGEP(InstructionValue, Vec<u32>),
|
||||
|
||||
/// Integer Comparison
|
||||
ICmp(CmpPredicate, InstructionValue, InstructionValue),
|
||||
@ -202,7 +201,7 @@ pub enum Type {
|
||||
Bool,
|
||||
Void,
|
||||
Ptr(Box<Type>),
|
||||
Array(Box<Type>, u32),
|
||||
ArrayPtr(Box<Type>, u32),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
|
@ -171,9 +171,11 @@ impl ast::Expression {
|
||||
ast::ExpressionKind::Array(expressions) => {
|
||||
mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect())
|
||||
}
|
||||
ast::ExpressionKind::Index(expression, idx) => {
|
||||
mir::ExprKind::Index(Box::new(expression.process()), *idx)
|
||||
}
|
||||
ast::ExpressionKind::Index(expression, idx) => mir::ExprKind::Index(
|
||||
Box::new(expression.process()),
|
||||
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||
*idx,
|
||||
),
|
||||
};
|
||||
|
||||
mir::Expression(kind, self.1.into())
|
||||
|
@ -334,12 +334,17 @@ impl mir::Expression {
|
||||
None
|
||||
}
|
||||
}
|
||||
mir::ExprKind::Index(expression, idx) => {
|
||||
let expr = expression.codegen(scope)?;
|
||||
mir::ExprKind::Index(expression, val_t, idx) => {
|
||||
let array = expression.codegen(scope)?;
|
||||
let ptr = scope
|
||||
.block
|
||||
.build(Instr::ArrayGEP(array, vec![*idx as u32]))
|
||||
.unwrap();
|
||||
|
||||
Some(
|
||||
scope
|
||||
.block
|
||||
.build(Instr::Extract(expr, *idx as u32))
|
||||
.build(Instr::Load(ptr, val_t.get_type()))
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
@ -354,7 +359,6 @@ impl mir::Expression {
|
||||
.next()
|
||||
.unwrap_or(TypeKind::Void);
|
||||
|
||||
dbg!(&instr_t);
|
||||
let array = scope
|
||||
.block
|
||||
.build(Instr::ArrayAlloca(
|
||||
@ -364,10 +368,11 @@ impl mir::Expression {
|
||||
.unwrap();
|
||||
|
||||
for (i, instr) in instr_list.iter().enumerate() {
|
||||
scope
|
||||
let ptr = scope
|
||||
.block
|
||||
.build(Instr::Insert(array, i as u32, *instr))
|
||||
.build(Instr::ArrayGEP(array, vec![i as u32]))
|
||||
.unwrap();
|
||||
scope.block.build(Instr::Store(ptr, *instr)).unwrap();
|
||||
}
|
||||
|
||||
Some(array)
|
||||
@ -450,7 +455,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::Array(elem_t, len) => {
|
||||
Type::ArrayPtr(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!"),
|
||||
}
|
||||
|
@ -128,8 +128,9 @@ impl Display for ExprKind {
|
||||
ExprKind::FunctionCall(fc) => Display::fmt(fc, f),
|
||||
ExprKind::If(if_exp) => Display::fmt(&if_exp, f),
|
||||
ExprKind::Block(block) => Display::fmt(block, f),
|
||||
ExprKind::Index(expression, idx) => {
|
||||
ExprKind::Index(expression, elem_ty, idx) => {
|
||||
Display::fmt(&expression, f)?;
|
||||
write!(f, "<{}>", elem_ty)?;
|
||||
write_index(f, *idx)
|
||||
}
|
||||
ExprKind::Array(expressions) => {
|
||||
|
@ -208,7 +208,7 @@ pub struct Import(pub String, pub Metadata);
|
||||
#[derive(Debug)]
|
||||
pub enum ExprKind {
|
||||
Variable(NamedVariableRef),
|
||||
Index(Box<Expression>, u64),
|
||||
Index(Box<Expression>, TypeKind, u64),
|
||||
Array(Vec<Expression>),
|
||||
Literal(Literal),
|
||||
BinOp(BinaryOperator, Box<Expression>, Box<Expression>),
|
||||
|
@ -380,7 +380,7 @@ impl Expression {
|
||||
Ok(collapsed)
|
||||
}
|
||||
ExprKind::Block(block) => block.typecheck(state, &hints, hint_t),
|
||||
ExprKind::Index(expression, idx) => {
|
||||
ExprKind::Index(expression, elem_ty, idx) => {
|
||||
// Try to unwrap hint type from array if possible
|
||||
let hint_t = hint_t.map(|t| match t {
|
||||
Array(type_kind, _) => &type_kind,
|
||||
@ -388,11 +388,17 @@ impl Expression {
|
||||
});
|
||||
|
||||
let expr_t = expression.typecheck(state, hints, hint_t)?;
|
||||
if let TypeKind::Array(elem_t, len) = expr_t {
|
||||
if let TypeKind::Array(inferred_ty, len) = expr_t {
|
||||
if len < *idx {
|
||||
return Err(ErrorKind::IndexOutOfBounds(*idx, len));
|
||||
}
|
||||
Ok(*elem_t)
|
||||
let ty = state.or_else(
|
||||
elem_ty.resolve_hinted(hints).collapse_into(&inferred_ty),
|
||||
TypeKind::Vague(Unknown),
|
||||
self.1,
|
||||
);
|
||||
*elem_ty = ty.clone();
|
||||
Ok(ty)
|
||||
} else {
|
||||
Err(ErrorKind::TriedIndexingNonArray(expr_t))
|
||||
}
|
||||
|
@ -263,11 +263,16 @@ impl Expression {
|
||||
ReturnKind::Soft => Ok(block_ref.1),
|
||||
}
|
||||
}
|
||||
ExprKind::Index(expression, _) => {
|
||||
ExprKind::Index(expression, index_ty, _) => {
|
||||
let expr_ty = expression.infer_types(state, type_refs)?;
|
||||
|
||||
let kind = unsafe { expr_ty.resolve_type() };
|
||||
match kind {
|
||||
Array(type_kind, _) => Ok(type_refs.from_type(&type_kind).unwrap()),
|
||||
Array(type_kind, _) => {
|
||||
let elem_ty = type_refs.from_type(&type_kind).unwrap();
|
||||
*index_ty = elem_ty.as_type().clone();
|
||||
Ok(elem_ty)
|
||||
}
|
||||
_ => Err(ErrorKind::TriedIndexingNonArray(kind)),
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ impl ReturnType for Expression {
|
||||
Block(block) => block.return_type(),
|
||||
FunctionCall(fcall) => fcall.return_type(),
|
||||
If(expr) => expr.return_type(),
|
||||
Index(expression, _) => {
|
||||
Index(expression, _, _) => {
|
||||
let expr_type = expression.return_type()?;
|
||||
if let (_, TypeKind::Array(elem_ty, _)) = expr_type {
|
||||
Ok((ReturnKind::Soft, *elem_ty))
|
||||
|
Loading…
Reference in New Issue
Block a user