From 92736e392e88db9afb59e0722f160a52b8b02e87 Mon Sep 17 00:00:00 2001 From: sofia Date: Sun, 13 Jul 2025 15:58:19 +0300 Subject: [PATCH] Refactor Type Hints -> Type Refs --- reid/src/lib.rs | 10 ++-- reid/src/mir/mod.rs | 6 +- reid/src/mir/typecheck.rs | 18 +++--- reid/src/mir/typeinference.rs | 50 ++++++++-------- reid/src/mir/{scopehints.rs => typerefs.rs} | 64 ++++++++++----------- 5 files changed, 74 insertions(+), 74 deletions(-) rename reid/src/mir/{scopehints.rs => typerefs.rs} (79%) diff --git a/reid/src/lib.rs b/reid/src/lib.rs index e423dba..2eff622 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -39,7 +39,7 @@ //! - Loops //! ``` -use mir::{scopehints::TypeHints, typecheck::TypeCheck, typeinference::TypeInference}; +use mir::{typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs}; use reid_lib::Context; use crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream}; @@ -89,13 +89,13 @@ pub fn compile(source: &str) -> Result { println!("{}", &mir_context); - let hints = TypeHints::default(); + let refs = TypeRefs::default(); - let state = mir_context.pass(&mut TypeInference { hints: &hints }); - dbg!(&state, &hints); + let state = mir_context.pass(&mut TypeInference { refs: &refs }); + dbg!(&state, &refs); println!("{}", &mir_context); - let state = mir_context.pass(&mut TypeCheck { hints: &hints }); + let state = mir_context.pass(&mut TypeCheck { refs: &refs }); dbg!(&state); println!("{}", &mir_context); diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 19c2d90..afbbf54 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -6,9 +6,9 @@ use crate::token_stream::TokenRange; mod display; pub mod pass; -pub mod scopehints; pub mod typecheck; pub mod typeinference; +pub mod typerefs; pub mod types; #[derive(Debug, Default, Clone, Copy)] @@ -68,8 +68,8 @@ pub enum VagueType { Unknown, #[error("Number")] Number, - #[error("Hinted({0})")] - Hinted(usize), + #[error("TypeRef({0})")] + TypeRef(usize), } impl TypeKind { diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index 6709e27..7718fe2 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -8,7 +8,7 @@ use VagueType::*; use super::{ pass::{Pass, PassState, ScopeFunction, ScopeVariable}, - scopehints::{ScopeHints, TypeHint, TypeHints}, + typerefs::{ScopeTypeRefs, TypeRef, TypeRefs}, types::{pick_return, ReturnType}, }; @@ -43,7 +43,7 @@ pub enum ErrorKind { /// Struct used to implement a type-checking pass that can be performed on the /// MIR. pub struct TypeCheck<'t> { - pub hints: &'t TypeHints, + pub refs: &'t TypeRefs, } impl<'t> Pass for TypeCheck<'t> { @@ -51,7 +51,7 @@ impl<'t> Pass for TypeCheck<'t> { fn module(&mut self, module: &mut Module, mut state: PassState) { for function in &mut module.functions { - let res = function.typecheck(&self.hints, &mut state); + let res = function.typecheck(&self.refs, &mut state); state.ok(res, function.block_meta()); } } @@ -60,7 +60,7 @@ impl<'t> Pass for TypeCheck<'t> { impl FunctionDefinition { fn typecheck( &mut self, - hints: &TypeHints, + hints: &TypeRefs, state: &mut PassState, ) -> Result { for param in &self.parameters { @@ -101,7 +101,7 @@ impl Block { fn typecheck( &mut self, state: &mut PassState, - hints: &TypeHints, + hints: &TypeRefs, hint_t: Option, ) -> Result { let mut state = state.inner(); @@ -246,7 +246,7 @@ impl Expression { fn typecheck( &mut self, state: &mut PassState, - hints: &TypeHints, + hints: &TypeRefs, hint_t: Option, ) -> Result { match &mut self.0 { @@ -428,7 +428,7 @@ impl TypeKind { Vague(vague_type) => match vague_type { Unknown => Err(ErrorKind::TypeIsVague(*vague_type)), Number => Ok(TypeKind::I32), - Hinted(_) => panic!("Hinted default!"), + TypeRef(_) => panic!("Hinted default!"), }, _ => Ok(*self), } @@ -445,9 +445,9 @@ impl TypeKind { }) } - fn resolve_hinted(&self, hints: &TypeHints) -> TypeKind { + fn resolve_hinted(&self, hints: &TypeRefs) -> TypeKind { match self { - Vague(Hinted(idx)) => hints.retrieve_type(*idx).unwrap(), + Vague(TypeRef(idx)) => hints.retrieve_type(*idx).unwrap(), _ => *self, } } diff --git a/reid/src/mir/typeinference.rs b/reid/src/mir/typeinference.rs index 5a68053..1fa6b4b 100644 --- a/reid/src/mir/typeinference.rs +++ b/reid/src/mir/typeinference.rs @@ -4,8 +4,8 @@ use reid_lib::Function; use super::{ pass::{Pass, PassState, ScopeVariable}, - scopehints::{self, ScopeHints, TypeHint, TypeHints}, typecheck::ErrorKind, + typerefs::{self, ScopeTypeRefs, TypeRef, TypeRefs}, types::{pick_return, ReturnType}, Block, ExprKind, Expression, FunctionDefinition, FunctionDefinitionKind, IfExpression, Module, ReturnKind, StmtKind, @@ -16,7 +16,7 @@ use super::{ /// Struct used to implement a type-checking pass that can be performed on the /// MIR. pub struct TypeInference<'t> { - pub hints: &'t TypeHints, + pub refs: &'t TypeRefs, } impl<'t> Pass for TypeInference<'t> { @@ -24,7 +24,7 @@ impl<'t> Pass for TypeInference<'t> { fn module(&mut self, module: &mut Module, mut state: PassState) { for function in &mut module.functions { - let res = function.infer_hints(&self.hints, &mut state); + let res = function.infer_hints(&self.refs, &mut state); state.ok(res, function.block_meta()); } } @@ -33,7 +33,7 @@ impl<'t> Pass for TypeInference<'t> { impl FunctionDefinition { fn infer_hints( &mut self, - hints: &TypeHints, + type_refs: &TypeRefs, state: &mut PassState, ) -> Result<(), ErrorKind> { for param in &self.parameters { @@ -51,7 +51,7 @@ impl FunctionDefinition { .or(Err(ErrorKind::VariableAlreadyDefined(param.0.clone()))); state.ok(res, self.signature()); } - let scope_hints = ScopeHints::from(hints); + let scope_hints = ScopeTypeRefs::from(type_refs); let return_type = self.return_type.clone(); let return_type_hint = scope_hints.from_type(&return_type).unwrap(); @@ -76,8 +76,8 @@ impl Block { fn infer_hints<'s>( &mut self, state: &mut PassState, - outer_hints: &'s ScopeHints, - ) -> Result<(ReturnKind, TypeHint<'s>), ErrorKind> { + outer_hints: &'s ScopeTypeRefs, + ) -> Result<(ReturnKind, TypeRef<'s>), ErrorKind> { let mut state = state.inner(); let inner_hints = outer_hints.inner(); @@ -140,11 +140,11 @@ impl Expression { fn infer_hints<'s>( &mut self, state: &mut PassState, - hints: &'s ScopeHints<'s>, - ) -> Result, ErrorKind> { + type_refs: &'s ScopeTypeRefs<'s>, + ) -> Result, ErrorKind> { match &mut self.0 { ExprKind::Variable(var) => { - let hint = hints + let hint = type_refs .find_hint(&var.1) .map(|(_, hint)| hint) .ok_or(ErrorKind::VariableNotDefined(var.1.clone())); @@ -153,11 +153,11 @@ impl Expression { } hint } - ExprKind::Literal(literal) => Ok(hints.from_type(&literal.as_type()).unwrap()), + ExprKind::Literal(literal) => Ok(type_refs.from_type(&literal.as_type()).unwrap()), ExprKind::BinOp(op, lhs, rhs) => { - let mut lhs_ref = lhs.infer_hints(state, hints)?; - let mut rhs_ref = rhs.infer_hints(state, hints)?; - hints.binop(op, &mut lhs_ref, &mut rhs_ref) + let mut lhs_ref = lhs.infer_hints(state, type_refs)?; + let mut rhs_ref = rhs.infer_hints(state, type_refs)?; + type_refs.binop(op, &mut lhs_ref, &mut rhs_ref) } ExprKind::FunctionCall(function_call) => { let fn_call = state @@ -172,33 +172,33 @@ impl Expression { for (param_expr, param_t) in function_call.parameters.iter_mut().zip(true_params_iter) { - let expr_res = param_expr.infer_hints(state, hints); + let expr_res = param_expr.infer_hints(state, type_refs); if let Some(mut param_ref) = state.ok(expr_res, param_expr.1) { state.ok( - param_ref.narrow(&mut hints.from_type(param_t).unwrap()), + param_ref.narrow(&mut type_refs.from_type(param_t).unwrap()), param_expr.1, ); } } - Ok(hints.from_type(&fn_call.ret).unwrap()) + Ok(type_refs.from_type(&fn_call.ret).unwrap()) } ExprKind::If(IfExpression(cond, lhs, rhs)) => { - let cond_res = cond.infer_hints(state, hints); + let cond_res = cond.infer_hints(state, type_refs); let cond_hints = state.ok(cond_res, cond.1); if let Some(mut cond_hints) = cond_hints { state.ok( - cond_hints.narrow(&mut hints.from_type(&Bool).unwrap()), + cond_hints.narrow(&mut type_refs.from_type(&Bool).unwrap()), cond.1, ); } - let lhs_res = lhs.infer_hints(state, hints); + let lhs_res = lhs.infer_hints(state, type_refs); let lhs_hints = state.ok(lhs_res, cond.1); if let Some(rhs) = rhs { - let rhs_res = rhs.infer_hints(state, hints); + let rhs_res = rhs.infer_hints(state, type_refs); let rhs_hints = state.ok(rhs_res, cond.1); if let (Some(mut lhs_hints), Some(mut rhs_hints)) = (lhs_hints, rhs_hints) { @@ -206,20 +206,20 @@ impl Expression { Ok(pick_return(lhs_hints, rhs_hints).1) } else { // Failed to retrieve types from either - Ok(hints.from_type(&Vague(Unknown)).unwrap()) + Ok(type_refs.from_type(&Vague(Unknown)).unwrap()) } } else { if let Some((_, type_ref)) = lhs_hints { Ok(type_ref) } else { - Ok(hints.from_type(&Vague(Unknown)).unwrap()) + Ok(type_refs.from_type(&Vague(Unknown)).unwrap()) } } } ExprKind::Block(block) => { - let block_ref = block.infer_hints(state, hints)?; + let block_ref = block.infer_hints(state, type_refs)?; match block_ref.0 { - ReturnKind::Hard => Ok(hints.from_type(&Void).unwrap()), + ReturnKind::Hard => Ok(type_refs.from_type(&Void).unwrap()), ReturnKind::Soft => Ok(block_ref.1), } } diff --git a/reid/src/mir/scopehints.rs b/reid/src/mir/typerefs.rs similarity index 79% rename from reid/src/mir/scopehints.rs rename to reid/src/mir/typerefs.rs index 1223170..726ee12 100644 --- a/reid/src/mir/scopehints.rs +++ b/reid/src/mir/typerefs.rs @@ -10,23 +10,23 @@ use super::{ }; #[derive(Clone)] -pub struct TypeHint<'scope>(TypeIdRef, &'scope ScopeHints<'scope>); +pub struct TypeRef<'scope>(TypeIdRef, &'scope ScopeTypeRefs<'scope>); -impl<'scope> TypeHint<'scope> { +impl<'scope> TypeRef<'scope> { pub unsafe fn resolve_type(&self) -> TypeKind { unsafe { *self.1.types.hints.borrow().get_unchecked(*self.0.borrow()) } } - pub fn narrow(&mut self, other: &TypeHint) -> Result, ErrorKind> { + pub fn narrow(&mut self, other: &TypeRef) -> Result, ErrorKind> { self.1.combine_vars(self, other) } pub fn as_type(&self) -> TypeKind { - TypeKind::Vague(super::VagueType::Hinted(*self.0.borrow())) + TypeKind::Vague(super::VagueType::TypeRef(*self.0.borrow())) } } -impl<'scope> std::fmt::Debug for TypeHint<'scope> { +impl<'scope> std::fmt::Debug for TypeRef<'scope> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("Hint") .field(&self.0) @@ -38,14 +38,14 @@ impl<'scope> std::fmt::Debug for TypeHint<'scope> { type TypeIdRef = Rc>; #[derive(Debug, Default)] -pub struct TypeHints { +pub struct TypeRefs { /// Simple list of types that variables can refrence hints: RefCell>, /// Indirect ID-references, referring to hints-vec type_refs: RefCell>, } -impl TypeHints { +impl TypeRefs { pub fn new(&self, ty: TypeKind) -> TypeIdRef { let idx = self.hints.borrow().len(); let typecell = Rc::new(RefCell::new(idx)); @@ -94,16 +94,16 @@ impl TypeHints { } #[derive(Debug)] -pub struct ScopeHints<'outer> { - types: &'outer TypeHints, - outer: Option<&'outer ScopeHints<'outer>>, +pub struct ScopeTypeRefs<'outer> { + types: &'outer TypeRefs, + outer: Option<&'outer ScopeTypeRefs<'outer>>, /// Mapping of what types variables point to variables: RefCell>, } -impl<'outer> ScopeHints<'outer> { - pub fn from(types: &'outer TypeHints) -> ScopeHints<'outer> { - ScopeHints { +impl<'outer> ScopeTypeRefs<'outer> { + pub fn from(types: &'outer TypeRefs) -> ScopeTypeRefs<'outer> { + ScopeTypeRefs { types, outer: Default::default(), variables: Default::default(), @@ -115,7 +115,7 @@ impl<'outer> ScopeHints<'outer> { name: String, mutable: bool, initial_ty: TypeKind, - ) -> Result, ErrorKind> { + ) -> Result, ErrorKind> { if self.variables.borrow().contains_key(&name) { return Err(ErrorKind::VariableAlreadyDefined(name)); } @@ -123,12 +123,12 @@ impl<'outer> ScopeHints<'outer> { self.variables .borrow_mut() .insert(name, (mutable, idx.clone())); - Ok(TypeHint(idx, self)) + Ok(TypeRef(idx, self)) } - pub fn from_type(&'outer self, ty: &TypeKind) -> Option> { + pub fn from_type(&'outer self, ty: &TypeKind) -> Option> { let idx = match ty { - TypeKind::Vague(super::VagueType::Hinted(idx)) => { + TypeKind::Vague(super::VagueType::TypeRef(idx)) => { let inner_idx = unsafe { *self.types.recurse_type_ref(*idx).borrow() }; self.types.type_refs.borrow().get(inner_idx).cloned()? } @@ -141,27 +141,27 @@ impl<'outer> ScopeHints<'outer> { } } }; - Some(TypeHint(idx, self)) + Some(TypeRef(idx, self)) } fn narrow_to_type( &'outer self, - hint: &TypeHint, + hint: &TypeRef, ty: &TypeKind, - ) -> Result, ErrorKind> { + ) -> Result, ErrorKind> { unsafe { let mut hints = self.types.hints.borrow_mut(); let existing = hints.get_unchecked_mut(*hint.0.borrow()); *existing = existing.collapse_into(&ty)?; - Ok(TypeHint(hint.0.clone(), self)) + Ok(TypeRef(hint.0.clone(), self)) } } fn combine_vars( &'outer self, - hint1: &TypeHint, - hint2: &TypeHint, - ) -> Result, ErrorKind> { + hint1: &TypeRef, + hint2: &TypeRef, + ) -> Result, ErrorKind> { unsafe { let ty = self .types @@ -175,32 +175,32 @@ impl<'outer> ScopeHints<'outer> { *idx.borrow_mut() = *hint1.0.borrow(); } } - Ok(TypeHint(hint1.0.clone(), self)) + Ok(TypeRef(hint1.0.clone(), self)) } } - pub fn inner(&'outer self) -> ScopeHints<'outer> { - ScopeHints { + pub fn inner(&'outer self) -> ScopeTypeRefs<'outer> { + ScopeTypeRefs { types: self.types, outer: Some(self), variables: Default::default(), } } - pub fn find_hint(&'outer self, name: &String) -> Option<(bool, TypeHint<'outer>)> { + pub fn find_hint(&'outer self, name: &String) -> Option<(bool, TypeRef<'outer>)> { self.variables .borrow() .get(name) - .map(|(mutable, idx)| (*mutable, TypeHint(idx.clone(), self))) + .map(|(mutable, idx)| (*mutable, TypeRef(idx.clone(), self))) .or(self.outer.map(|o| o.find_hint(name)).flatten()) } pub fn binop( &'outer self, op: &BinaryOperator, - lhs: &mut TypeHint<'outer>, - rhs: &mut TypeHint<'outer>, - ) -> Result, ErrorKind> { + lhs: &mut TypeRef<'outer>, + rhs: &mut TypeRef<'outer>, + ) -> Result, ErrorKind> { let ty = lhs.narrow(rhs)?; Ok(match op { BinaryOperator::Add => ty,