Possibly fix array_structs

This commit is contained in:
Sofia 2025-07-16 23:09:36 +03:00
parent c41aab33a9
commit d034754202
2 changed files with 55 additions and 32 deletions

View File

@ -320,6 +320,7 @@ impl Builder {
} }
Instr::GetStructElemPtr(ptr_val, idx) => { Instr::GetStructElemPtr(ptr_val, idx) => {
let ptr_ty = ptr_val.get_type(&self)?; let ptr_ty = ptr_val.get_type(&self)?;
dbg!(&ptr_ty);
if let Type::Ptr(ty) = ptr_ty { if let Type::Ptr(ty) = ptr_ty {
if let Type::CustomType(val) = *ty { if let Type::CustomType(val) = *ty {
match self.type_data(&val).kind { match self.type_data(&val).kind {

View File

@ -56,6 +56,9 @@ pub struct Scope<'ctx, 'a> {
type_values: &'a HashMap<String, TypeValue>, type_values: &'a HashMap<String, TypeValue>,
functions: &'a HashMap<String, Function<'ctx>>, functions: &'a HashMap<String, Function<'ctx>>,
stack_values: HashMap<String, StackValue>, stack_values: HashMap<String, StackValue>,
// True if the current expression should attemt to load it's pointer value,
// or keep it as a pointer (mainly used for Set-statement).
should_load: bool,
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@ -94,6 +97,7 @@ impl<'ctx, 'a> Scope<'ctx, 'a> {
types: self.types, types: self.types,
type_values: self.type_values, type_values: self.type_values,
stack_values: self.stack_values.clone(), stack_values: self.stack_values.clone(),
should_load: self.should_load,
} }
} }
@ -108,6 +112,13 @@ impl<'ctx, 'a> Scope<'ctx, 'a> {
fn get_typedef(&self, name: &String) -> Option<&TypeDefinitionKind> { fn get_typedef(&self, name: &String) -> Option<&TypeDefinitionKind> {
self.type_values.get(name).and_then(|v| self.types.get(v)) self.type_values.get(name).and_then(|v| self.types.get(v))
} }
/// Sets should load, returning the old value
fn set_should_load(&mut self, should: bool) -> bool {
let old = self.should_load;
self.should_load = should;
old
}
} }
impl mir::Module { impl mir::Module {
@ -196,6 +207,7 @@ impl mir::Module {
types: &types, types: &types,
type_values: &type_values, type_values: &type_values,
stack_values, stack_values,
should_load: true,
}; };
match &mir_function.kind { match &mir_function.kind {
mir::FunctionDefinitionKind::Local(block, _) => { mir::FunctionDefinitionKind::Local(block, _) => {
@ -226,6 +238,7 @@ impl mir::Block {
if let Some((kind, expr)) = &self.return_expression { if let Some((kind, expr)) = &self.return_expression {
match kind { match kind {
mir::ReturnKind::Hard => { mir::ReturnKind::Hard => {
scope.should_load = true;
let ret = expr.codegen(&mut scope)?; let ret = expr.codegen(&mut scope)?;
scope.block.terminate(Term::Ret(ret)).unwrap(); scope.block.terminate(Term::Ret(ret)).unwrap();
None None
@ -278,23 +291,21 @@ impl mir::Statement {
None None
} }
mir::StmtKind::Set(lhs, rhs) => { mir::StmtKind::Set(lhs, rhs) => {
todo!("codegen!"); let old = scope.set_should_load(false);
let lhs_value = lhs
.codegen(scope)
.expect("non-returning LHS snuck into codegen!");
scope.should_load = old;
// if let Some(StackValue(kind, _)) = var.get_stack_value(scope, false) { let rhs_value = rhs.codegen(scope)?;
// match kind {
// StackValueKind::Immutable(_) => { Some(
// panic!("Tried to mutate an immutable variable") scope
// } .block
// StackValueKind::Mutable(ptr) => { .build(Instr::Store(lhs_value, rhs_value))
// let expression = val.codegen(scope).unwrap(); .unwrap(),
// Some(scope.block.build(Instr::Store(ptr, expression)).unwrap()) )
// }
// }
// } else {
// panic!("")
// }
} }
// mir::StmtKind::If(if_expression) => if_expression.codegen(scope),
mir::StmtKind::Import(_) => todo!(), mir::StmtKind::Import(_) => todo!(),
mir::StmtKind::Expression(expression) => expression.codegen(scope), mir::StmtKind::Expression(expression) => expression.codegen(scope),
} }
@ -312,11 +323,17 @@ impl mir::Expression {
.expect("Variable reference not found?!"); .expect("Variable reference not found?!");
Some(match v.0 { Some(match v.0 {
StackValueKind::Immutable(val) => val.clone(), StackValueKind::Immutable(val) => val.clone(),
StackValueKind::Mutable(val) => match v.1 { StackValueKind::Mutable(val) => {
// TODO probably wrong ..? if scope.should_load {
Type::Ptr(_) => val, match v.1 {
_ => scope.block.build(Instr::Load(val, v.1.clone())).unwrap(), // TODO probably wrong ..?
}, Type::Ptr(_) => val,
_ => scope.block.build(Instr::Load(val, v.1.clone())).unwrap(),
}
} else {
val
}
}
}) })
} }
mir::ExprKind::Literal(lit) => Some(lit.as_const(&mut scope.block)), mir::ExprKind::Literal(lit) => Some(lit.as_const(&mut scope.block)),
@ -384,20 +401,22 @@ impl mir::Expression {
mir::ExprKind::Indexed(expression, val_t, idx_expr) => { mir::ExprKind::Indexed(expression, val_t, idx_expr) => {
let array = expression.codegen(scope)?; let array = expression.codegen(scope)?;
let idx = idx_expr.codegen(scope)?; let idx = idx_expr.codegen(scope)?;
let ptr = scope let mut ptr = scope
.block .block
.build(Instr::GetElemPtr(array, vec![idx])) .build(Instr::GetElemPtr(array, vec![idx]))
.unwrap(); .unwrap();
Some( if scope.should_load {
scope ptr = scope
.block .block
.build(Instr::Load( .build(Instr::Load(
ptr, ptr,
val_t.get_type(scope.type_values, scope.types), val_t.get_type(scope.type_values, scope.types),
)) ))
.unwrap(), .unwrap();
) }
Some(ptr)
} }
mir::ExprKind::Array(expressions) => { mir::ExprKind::Array(expressions) => {
let instr_list = expressions let instr_list = expressions
@ -433,7 +452,9 @@ impl mir::Expression {
Some(array) Some(array)
} }
mir::ExprKind::Accessed(expression, type_kind, field) => { mir::ExprKind::Accessed(expression, type_kind, field) => {
let old = scope.set_should_load(true);
let struct_val = expression.codegen(scope)?; let struct_val = expression.codegen(scope)?;
scope.should_load = old;
let struct_ty = expression.return_type().ok()?.1.known().ok()?; let struct_ty = expression.return_type().ok()?.1.known().ok()?;
let TypeKind::CustomType(name) = struct_ty else { let TypeKind::CustomType(name) = struct_ty else {
@ -442,21 +463,22 @@ impl mir::Expression {
let TypeDefinitionKind::Struct(struct_ty) = scope.get_typedef(&name)?; let TypeDefinitionKind::Struct(struct_ty) = scope.get_typedef(&name)?;
let idx = struct_ty.find_index(field)?; let idx = struct_ty.find_index(field)?;
let ptr = scope let mut value = scope
.block .block
.build(Instr::GetStructElemPtr(struct_val, idx as u32)) .build(Instr::GetStructElemPtr(struct_val, idx as u32))
.unwrap(); .unwrap();
dbg!(&type_kind.get_type(scope.type_values, scope.types)); if scope.should_load {
Some( value = scope
scope
.block .block
.build(Instr::Load( .build(Instr::Load(
ptr, value,
type_kind.get_type(scope.type_values, scope.types), type_kind.get_type(scope.type_values, scope.types),
)) ))
.unwrap(), .unwrap();
) }
Some(value)
} }
mir::ExprKind::Struct(name, items) => { mir::ExprKind::Struct(name, items) => {
let struct_ptr = scope let struct_ptr = scope