diff --git a/src/ir/upper/ty.rs b/src/ir/upper/ty.rs index 0fab315..9be1473 100644 --- a/src/ir/upper/ty.rs +++ b/src/ir/upper/ty.rs @@ -1,6 +1,4 @@ -use crate::common::CompilerOutput; - -use super::{Len, StructID, UInstruction, UProgram, UVar}; +use super::{Len, StructID, UInstruction, UProgram, UVar, VarID}; #[derive(Clone, PartialEq)] pub enum Type { @@ -46,21 +44,22 @@ impl UProgram { vars[dest.id.0].as_mut().expect("bruh").ty = ret; } UInstruction::Mv { dest, src } => { - let dest_ty = &vars[dest.id.0].as_ref().unwrap().ty; - let src_ty = &vars[src.id.0].as_ref().unwrap().ty; + let dest_ty = get(vars, dest.id); + let src_ty = get(vars, src.id); if let Some(ty) = match_types(dest_ty, src_ty) { - vars[dest.id.0] - .as_mut() - .expect("PARTIAL BORROWING WOULD BE REALLY COOL") - .ty = ty.clone(); - vars[src.id.0] - .as_mut() - .expect("PARTIAL BORROWING WOULD BE REALLY COOL") - .ty = ty; + set(vars, dest.id, ty.clone()); + set(vars, src.id, ty); } } UInstruction::Ref { dest, src } => { - // TODO + let dest_ty = get(vars, dest.id); + let src_ty = get(vars, src.id); + if let Type::Ref(dest_ty) = dest_ty { + if let Some(ty) = match_types(dest_ty, src_ty) { + set(vars, dest.id, ty.clone().rf()); + set(vars, src.id, ty); + } + } } UInstruction::LoadData { dest, src } => { // TODO @@ -94,6 +93,20 @@ impl UProgram { } } +pub fn get(vars: &[Option], id: VarID) -> &Type { + &vars[id.0] + .as_ref() + .expect("PARTIAL BORROWING WOULD BE REALLY COOL") + .ty +} + +pub fn set(vars: &mut [Option], id: VarID, ty: Type) { + vars[id.0] + .as_mut() + .expect("PARTIAL BORROWING WOULD BE REALLY COOL") + .ty = ty; +} + pub fn match_types(dest: &Type, src: &Type) -> Option { if dest == src { return None; diff --git a/src/ir/upper/validate.rs b/src/ir/upper/validate.rs index c4da060..35aa280 100644 --- a/src/ir/upper/validate.rs +++ b/src/ir/upper/validate.rs @@ -37,7 +37,9 @@ impl UProgram { output.check_assign(self, &src.ty, &dest.ty, i.span); } UInstruction::Ref { dest, src } => { - // TODO + let dest = self.expect(dest.id); + let src = self.expect(src.id); + output.check_assign(self, &src.ty.clone().rf(), &dest.ty, i.span); } UInstruction::LoadData { dest, src } => { let dest = self.expect(dest.id);