diff --git a/.rustfmt.toml b/.rustfmt.toml index e69de29..866c756 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -0,0 +1 @@ +max_width = 120 \ No newline at end of file diff --git a/reid/src/codegen/intrinsics.rs b/reid/src/codegen/intrinsics.rs index 130f68d..53657f2 100644 --- a/reid/src/codegen/intrinsics.rs +++ b/reid/src/codegen/intrinsics.rs @@ -1,98 +1,161 @@ use std::marker::PhantomData; -use reid_lib::{builder::InstructionValue, Instr}; +use reid_lib::{builder::InstructionValue, CmpPredicate, Instr}; use crate::{ codegen::{ErrorKind, StackValueKind}, - mir::{BinaryOperator, BinopDefinition, FunctionDefinition, FunctionDefinitionKind, TypeKind}, + mir::{BinaryOperator, BinopDefinition, CmpOperator, FunctionDefinition, FunctionDefinitionKind, TypeKind}, }; use super::scope::{Scope, StackValue}; +const INTEGERS: [TypeKind; 10] = [ + TypeKind::U8, + TypeKind::U16, + TypeKind::U32, + TypeKind::U64, + TypeKind::U128, + TypeKind::I8, + TypeKind::I16, + TypeKind::I32, + TypeKind::I64, + TypeKind::I128, +]; + +const FLOATS: [TypeKind; 7] = [ + TypeKind::F16, + TypeKind::F32, + TypeKind::F32B, + TypeKind::F64, + TypeKind::F80, + TypeKind::F128, + TypeKind::F128PPC, +]; + pub fn form_intrinsics() -> Vec { let intrinsics = Vec::new(); intrinsics } +fn simple_binop_def(op: BinaryOperator, ty: &TypeKind, fun: T) -> BinopDefinition +where + T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, +{ + BinopDefinition { + lhs: ("lhs".to_owned(), ty.clone()), + op, + rhs: ("rhs".to_owned(), ty.clone()), + return_type: ty.clone(), + fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))), + meta: Default::default(), + } +} + +fn boolean_binop_def(op: BinaryOperator, ty: &TypeKind, fun: T) -> BinopDefinition +where + T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, +{ + BinopDefinition { + lhs: ("lhs".to_owned(), ty.clone()), + op, + rhs: ("rhs".to_owned(), ty.clone()), + return_type: TypeKind::Bool, + fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicBooleanInstr(fun))), + meta: Default::default(), + } +} + pub fn form_intrinsic_binops() -> Vec { let mut intrinsics = Vec::new(); - intrinsics.push(BinopDefinition { - lhs: ("lhs".to_owned(), TypeKind::U32), - op: BinaryOperator::Add, - rhs: ("rhs".to_owned(), TypeKind::U32), - return_type: TypeKind::U32, - fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr( - |scope, lhs, rhs| scope.block.build(Instr::Add(lhs, rhs)).unwrap(), - ))), - meta: Default::default(), - }); + use BinaryOperator::*; - intrinsics.push(BinopDefinition { - lhs: ("lhs".to_owned(), TypeKind::U16), - op: BinaryOperator::Add, - rhs: ("rhs".to_owned(), TypeKind::U16), - return_type: TypeKind::U16, - fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr( - |scope, lhs, rhs| scope.block.build(Instr::Add(lhs, rhs)).unwrap(), - ))), - meta: Default::default(), - }); - - intrinsics.push(BinopDefinition { - lhs: ("lhs".to_owned(), TypeKind::U32), - op: BinaryOperator::Mult, - rhs: ("rhs".to_owned(), TypeKind::U32), - return_type: TypeKind::U32, - fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr( - |scope, lhs, rhs| scope.block.build(Instr::Mul(lhs, rhs)).unwrap(), - ))), - meta: Default::default(), - }); - - intrinsics.push(BinopDefinition { - lhs: ("lhs".to_owned(), TypeKind::U16), - op: BinaryOperator::Mult, - rhs: ("rhs".to_owned(), TypeKind::U16), - return_type: TypeKind::U16, - fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr( - |scope, lhs, rhs| scope.block.build(Instr::Mul(lhs, rhs)).unwrap(), - ))), - meta: Default::default(), - }); - - intrinsics.push(BinopDefinition { - lhs: ("lhs".to_owned(), TypeKind::U32), - op: BinaryOperator::Minus, - rhs: ("rhs".to_owned(), TypeKind::U32), - return_type: TypeKind::U32, - fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr( - |scope, lhs, rhs| scope.block.build(Instr::Sub(lhs, rhs)).unwrap(), - ))), - meta: Default::default(), - }); - - intrinsics.push(BinopDefinition { - lhs: ("lhs".to_owned(), TypeKind::U16), - op: BinaryOperator::Minus, - rhs: ("rhs".to_owned(), TypeKind::U16), - return_type: TypeKind::U16, - fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr( - |scope, lhs, rhs| scope.block.build(Instr::Sub(lhs, rhs)).unwrap(), - ))), - meta: Default::default(), - }); + for ty in INTEGERS { + intrinsics.push(simple_binop_def(Add, &ty, |scope, lhs, rhs| { + scope.block.build(Instr::Add(lhs, rhs)).unwrap() + })); + intrinsics.push(simple_binop_def(Mult, &ty, |scope, lhs, rhs| { + scope.block.build(Instr::Mul(lhs, rhs)).unwrap() + })); + intrinsics.push(simple_binop_def(Minus, &ty, |scope, lhs, rhs| { + scope.block.build(Instr::Sub(lhs, rhs)).unwrap() + })); + if ty.signed() { + intrinsics.push(simple_binop_def(Div, &ty, |scope, lhs, rhs| { + scope.block.build(Instr::SDiv(lhs, rhs)).unwrap() + })); + intrinsics.push(simple_binop_def(Mod, &ty, |scope, lhs, rhs| { + let div = scope.block.build(Instr::SDiv(lhs, rhs)).unwrap(); + let mul = scope.block.build(Instr::Mul(rhs, div)).unwrap(); + scope.block.build(Instr::Sub(lhs, mul)).unwrap() + })); + } else { + intrinsics.push(simple_binop_def(Div, &ty, |scope, lhs, rhs| { + scope.block.build(Instr::UDiv(lhs, rhs)).unwrap() + })); + intrinsics.push(simple_binop_def(Mod, &ty, |scope, lhs, rhs| { + let div = scope.block.build(Instr::UDiv(lhs, rhs)).unwrap(); + let mul = scope.block.build(Instr::Mul(rhs, div)).unwrap(); + scope.block.build(Instr::Sub(lhs, mul)).unwrap() + })); + } + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::GT), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::ICmp(CmpPredicate::GT, lhs, rhs)).unwrap() + })); + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::GE), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::ICmp(CmpPredicate::GE, lhs, rhs)).unwrap() + })); + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::LT), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::ICmp(CmpPredicate::LT, lhs, rhs)).unwrap() + })); + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::LE), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::ICmp(CmpPredicate::LE, lhs, rhs)).unwrap() + })); + } + for ty in INTEGERS.iter().chain(&[TypeKind::Bool, TypeKind::Char]) { + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::EQ), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::ICmp(CmpPredicate::EQ, lhs, rhs)).unwrap() + })); + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::NE), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::ICmp(CmpPredicate::NE, lhs, rhs)).unwrap() + })); + } + for ty in FLOATS { + intrinsics.push(simple_binop_def(BinaryOperator::Add, &ty, |scope, lhs, rhs| { + scope.block.build(Instr::FAdd(lhs, rhs)).unwrap() + })); + intrinsics.push(simple_binop_def(BinaryOperator::Mult, &ty, |scope, lhs, rhs| { + scope.block.build(Instr::FMul(lhs, rhs)).unwrap() + })); + intrinsics.push(simple_binop_def(BinaryOperator::Minus, &ty, |scope, lhs, rhs| { + scope.block.build(Instr::FSub(lhs, rhs)).unwrap() + })); + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::EQ), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::FCmp(CmpPredicate::EQ, lhs, rhs)).unwrap() + })); + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::NE), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::FCmp(CmpPredicate::NE, lhs, rhs)).unwrap() + })); + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::GT), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::FCmp(CmpPredicate::GT, lhs, rhs)).unwrap() + })); + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::GE), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::FCmp(CmpPredicate::GE, lhs, rhs)).unwrap() + })); + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::LT), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::FCmp(CmpPredicate::LT, lhs, rhs)).unwrap() + })); + intrinsics.push(boolean_binop_def(Cmp(CmpOperator::LE), &ty, |scope, lhs, rhs| { + scope.block.build(Instr::FCmp(CmpPredicate::LE, lhs, rhs)).unwrap() + })); + } intrinsics } pub trait IntrinsicFunction: std::fmt::Debug { - fn codegen<'ctx, 'a>( - &self, - scope: &mut Scope<'ctx, 'a>, - params: &[&StackValue], - ) -> Result; + fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[&StackValue]) -> Result; } #[derive(Clone)] @@ -113,11 +176,7 @@ impl IntrinsicFunction for IntrinsicSimpleInstr where T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, { - fn codegen<'b, 'c>( - &self, - scope: &mut Scope<'b, 'c>, - params: &[&StackValue], - ) -> Result { + fn codegen<'b, 'c>(&self, scope: &mut Scope<'b, 'c>, params: &[&StackValue]) -> Result { let lhs = params.get(0).unwrap(); let rhs = params.get(1).unwrap(); let instr = self.clone().0(scope, lhs.instr(), rhs.instr()); @@ -125,6 +184,32 @@ where } } +#[derive(Clone)] +pub struct IntrinsicBooleanInstr(T) +where + T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue; + +impl std::fmt::Debug for IntrinsicBooleanInstr +where + T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("IntrinsicBooleanInstr").finish() + } +} + +impl IntrinsicFunction for IntrinsicBooleanInstr +where + T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, +{ + fn codegen<'b, 'c>(&self, scope: &mut Scope<'b, 'c>, params: &[&StackValue]) -> Result { + let lhs = params.get(0).unwrap(); + let rhs = params.get(1).unwrap(); + let instr = self.clone().0(scope, lhs.instr(), rhs.instr()); + Ok(StackValue(StackValueKind::Literal(instr), TypeKind::Bool)) + } +} + // impl IntrinsicFunction for IntrinsicIAdd { // fn codegen<'ctx, 'a>( // &self, diff --git a/reid/src/lib.rs b/reid/src/lib.rs index 42c024b..6b445bb 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -98,11 +98,7 @@ pub fn compile_module<'map>( let mut statements = Vec::new(); while !matches!(token_stream.peek().unwrap_or(Token::Eof), Token::Eof) { - let statement = ReidError::from_parser( - token_stream.parse::(), - map.clone(), - module_id, - )?; + let statement = ReidError::from_parser(token_stream.parse::(), map.clone(), module_id)?; statements.push(statement); } @@ -189,8 +185,6 @@ pub fn perform_all_passes<'map>( println!("{}", &context); #[cfg(debug_assertions)] dbg!(&state); - dbg!("asd!"); - thread::sleep(Duration::from_millis(100)); if !state.errors.is_empty() { return Err(ReidError::from_kind( diff --git a/reid/src/mir/typecheck/typecheck.rs b/reid/src/mir/typecheck/typecheck.rs index e1c2c24..a9efa5b 100644 --- a/reid/src/mir/typecheck/typecheck.rs +++ b/reid/src/mir/typecheck/typecheck.rs @@ -56,10 +56,7 @@ impl<'t> Pass for TypeCheck<'t> { } if let Some(_) = defmap.insert(&typedef.name, typedef) { - state.ok::<_, Infallible>( - Err(ErrorKind::DuplicateTypeName(name.clone())), - meta.clone(), - ); + state.ok::<_, Infallible>(Err(ErrorKind::DuplicateTypeName(name.clone())), meta.clone()); } } @@ -94,10 +91,7 @@ fn check_typedefs_for_recursion<'a, 'b>( if let TypeKind::CustomType(CustomTypeKey(name, _)) = field_ty { if seen.contains(name) { state.ok::<_, Infallible>( - Err(ErrorKind::RecursiveTypeDefinition( - typedef.name.clone(), - name.clone(), - )), + Err(ErrorKind::RecursiveTypeDefinition(typedef.name.clone(), name.clone())), typedef.meta, ); } else { @@ -113,11 +107,7 @@ fn check_typedefs_for_recursion<'a, 'b>( } impl BinopDefinition { - fn typecheck( - &mut self, - typerefs: &TypeRefs, - state: &mut TypecheckPassState, - ) -> Result { + fn typecheck(&mut self, typerefs: &TypeRefs, state: &mut TypecheckPassState) -> Result { for param in vec![&self.lhs, &self.rhs] { let param_t = state.or_else( param.1.assert_known(typerefs, state), @@ -141,29 +131,21 @@ impl BinopDefinition { let return_type = self.return_type.clone().assert_known(typerefs, state)?; state.scope.return_type_hint = Some(self.return_type.clone()); - let inferred = - self.fn_kind - .typecheck(&typerefs, &mut state.inner(), Some(return_type.clone())); + let inferred = self + .fn_kind + .typecheck(&typerefs, &mut state.inner(), Some(return_type.clone())); match inferred { Ok(t) => return_type .narrow_into(&t.1) .or(Err(ErrorKind::ReturnTypeMismatch(return_type, t.1))), - Err(e) => Ok(state.or_else( - Err(e), - return_type, - self.block_meta().unwrap_or(self.signature()), - )), + Err(e) => Ok(state.or_else(Err(e), return_type, self.block_meta().unwrap_or(self.signature()))), } } } impl FunctionDefinition { - fn typecheck( - &mut self, - typerefs: &TypeRefs, - state: &mut TypecheckPassState, - ) -> Result { + fn typecheck(&mut self, typerefs: &TypeRefs, state: &mut TypecheckPassState) -> Result { for param in &self.parameters { let param_t = state.or_else( param.1.assert_known(typerefs, state), @@ -185,9 +167,7 @@ impl FunctionDefinition { } let return_type = self.return_type.clone().assert_known(typerefs, state)?; - let inferred = self - .kind - .typecheck(typerefs, state, Some(self.return_type.clone())); + let inferred = self.kind.typecheck(typerefs, state, Some(self.return_type.clone())); match inferred { Ok(t) => return_type @@ -210,12 +190,8 @@ impl FunctionDefinitionKind { state.scope.return_type_hint = hint.clone(); block.typecheck(&mut state.inner(), &typerefs, hint.as_ref()) } - FunctionDefinitionKind::Extern(_) => { - Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))) - } - FunctionDefinitionKind::Intrinsic(..) => { - Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))) - } + FunctionDefinitionKind::Extern(_) => Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))), + FunctionDefinitionKind::Intrinsic(..) => Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))), } } } @@ -293,9 +269,7 @@ impl Block { mutable: *mutable, }, ) - .or(Err(ErrorKind::VariableAlreadyDefined( - variable_reference.1.clone(), - ))); + .or(Err(ErrorKind::VariableAlreadyDefined(variable_reference.1.clone()))); state.ok(res, variable_reference.2); None } @@ -344,26 +318,16 @@ impl Block { StmtKind::Expression(expression) => { let res = expression.typecheck(&mut state, &typerefs, None); state.or_else(res, TypeKind::Void, expression.1); - if let Ok((kind, _)) = - expression.return_type(typerefs, state.module_id.unwrap()) - { + if let Ok((kind, _)) = expression.return_type(typerefs, state.module_id.unwrap()) { Some((kind, expression)) } else { None } } - StmtKind::While(WhileStatement { - condition, - block, - meta, - }) => { - let condition_ty = - condition.typecheck(&mut state, typerefs, Some(&TypeKind::Bool))?; + StmtKind::While(WhileStatement { condition, block, meta }) => { + let condition_ty = condition.typecheck(&mut state, typerefs, Some(&TypeKind::Bool))?; if condition_ty.assert_known(typerefs, &state)? != TypeKind::Bool { - state.note_errors( - &vec![ErrorKind::TypesIncompatible(condition_ty, TypeKind::Bool)], - *meta, - ); + state.note_errors(&vec![ErrorKind::TypesIncompatible(condition_ty, TypeKind::Bool)], *meta); } block.typecheck(&mut state, typerefs, None)?; @@ -453,93 +417,23 @@ impl Expression { let rhs_res = rhs.typecheck(state, &typerefs, None); let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1); - if let Some(binop) = state - .scope - .binops + if let Some(binop) = typerefs + .binop_types .find(&pass::ScopeBinopKey { params: (lhs_type.clone(), rhs_type.clone()), operator: *op, }) .map(|v| (v.1.clone())) { - dbg!(&lhs, &rhs); - dbg!(&lhs_type.resolve_ref(typerefs)); - dbg!(&rhs_type.resolve_ref(typerefs)); lhs.typecheck(state, &typerefs, Some(&binop.hands.0))?; rhs.typecheck(state, &typerefs, Some(&binop.hands.1))?; Ok(binop.narrow(&lhs_type, &rhs_type).unwrap().2) } else { - Err(ErrorKind::InvalidBinop(*op, lhs_type, rhs_type)) + dbg!(&op, &lhs, &rhs); + dbg!(&lhs_type); + dbg!(&rhs_type); + panic!() } - - // let cloned = state.scope.binops.clone(); - // let mut iter = cloned.iter(); - // let operator = loop { - // let Some((_, binop)) = iter.next() else { - // break None; - // }; - // if binop.operator != *op { - // continue; - // } - // if let Some(hint_t) = hint_t { - // if binop.return_ty == *hint_t { - // if let Some(_) = TypeKind::narrow_to_binop(&lhs_type, &rhs_type, binop) - // { - // break Some(binop); - // } - // } else { - // continue; - // } - // } - // if let Some(_) = TypeKind::narrow_to_binop(&lhs_type, &rhs_type, binop) { - // break Some(binop); - // } - // }; - - // if let Some(operator) = operator { - // // Re-typecheck with found operator hints - // let (lhs_ty, rhs_ty) = TypeKind::try_collapse_two( - // (&lhs_type, &rhs_type), - // (&operator.hands.0, &operator.hands.1), - // ) - // .unwrap(); - // let lhs_res = lhs.typecheck(state, &typerefs, Some(&lhs_ty)); - // let rhs_res = rhs.typecheck(state, &typerefs, Some(&rhs_ty)); - // state.or_else(lhs_res, TypeKind::Vague(Vague::Unknown), lhs.1); - // state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1); - // Ok(operator.return_ty.clone()) - // } else { - // // Re-typecheck with typical everyday binop - // let lhs_res = lhs.typecheck( - // state, - // &typerefs, - // hint_t.and_then(|t| t.simple_binop_hint(op)).as_ref(), - // ); - // let lhs_type = state.or_else(lhs_res, TypeKind::Vague(Vague::Unknown), lhs.1); - // let rhs_res = rhs.typecheck(state, &typerefs, Some(&lhs_type)); - // let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1); - - // let both_t = lhs_type.narrow_into(&rhs_type)?; - - // if *op == BinaryOperator::Minus && !lhs_type.signed() { - // if let (Some(lhs_val), Some(rhs_val)) = (lhs.num_value()?, rhs.num_value()?) - // { - // if lhs_val < rhs_val { - // return Err(ErrorKind::NegativeUnsignedValue(lhs_type)); - // } - // } - // } - - // if let Some(collapsed) = state.ok(rhs_type.narrow_into(&rhs_type), self.1) { - // // Try to coerce both sides again with collapsed type - // lhs.typecheck(state, &typerefs, Some(&collapsed)).ok(); - // rhs.typecheck(state, &typerefs, Some(&collapsed)).ok(); - // } - - // both_t - // .simple_binop_type(op) - // .ok_or(ErrorKind::InvalidBinop(*op, lhs_type, rhs_type)) - // } } ExprKind::FunctionCall(function_call) => { let true_function = state @@ -571,21 +465,16 @@ impl Expression { .into_iter() .chain(iter::repeat(TypeKind::Vague(Vague::Unknown))); - for (param, true_param_t) in - function_call.parameters.iter_mut().zip(true_params_iter) - { + for (param, true_param_t) in function_call.parameters.iter_mut().zip(true_params_iter) { // Typecheck every param separately let param_res = param.typecheck(state, &typerefs, Some(&true_param_t)); - let param_t = - state.or_else(param_res, TypeKind::Vague(Vague::Unknown), param.1); + let param_t = state.or_else(param_res, TypeKind::Vague(Vague::Unknown), param.1); state.ok(param_t.narrow_into(&true_param_t), param.1); } // Make sure function return type is the same as the claimed // return type - let ret_t = f - .ret - .narrow_into(&function_call.return_type.resolve_ref(typerefs))?; + let ret_t = f.ret.narrow_into(&function_call.return_type.resolve_ref(typerefs))?; // Update typing to be more accurate function_call.return_type = ret_t.clone(); Ok(ret_t.resolve_ref(typerefs)) @@ -604,8 +493,7 @@ impl Expression { let then_ret_t = state.or_else(then_res, TypeKind::Vague(Vague::Unknown), lhs.1); let else_ret_t = if let Some(else_expr) = rhs.as_mut() { let res = else_expr.typecheck(state, &typerefs, hint_t); - let else_ret_t = - state.or_else(res, TypeKind::Vague(Vague::Unknown), else_expr.1); + let else_ret_t = state.or_else(res, TypeKind::Vague(Vague::Unknown), else_expr.1); else_ret_t } else { @@ -682,10 +570,7 @@ impl Expression { for other in iter { state.ok(first.narrow_into(other), self.1); } - Ok(TypeKind::Array( - Box::new(first.clone()), - expressions.len() as u64, - )) + Ok(TypeKind::Array(Box::new(first.clone()), expressions.len() as u64)) } else { Ok(TypeKind::Array(Box::new(TypeKind::Void), 0)) } @@ -705,8 +590,7 @@ impl Expression { // Typecheck expression let expr_res = expression.typecheck(state, typerefs, Some(&expected_ty)); - let expr_ty = - state.or_else(expr_res, TypeKind::Vague(Vague::Unknown), expression.1); + let expr_ty = state.or_else(expr_res, TypeKind::Vague(Vague::Unknown), expression.1); if let TypeKind::CustomType(key) = expr_ty { let struct_type = state @@ -742,18 +626,14 @@ impl Expression { let expected_ty = state.or_else( struct_def .get_field_ty(field_name) - .ok_or(ErrorKind::NoSuchField(format!( - "{}.{}", - struct_name, field_name - ))), + .ok_or(ErrorKind::NoSuchField(format!("{}.{}", struct_name, field_name))), &TypeKind::Vague(VagueType::Unknown), field_expr.1, ); // Typecheck the actual expression let expr_res = field_expr.typecheck(state, typerefs, Some(expected_ty)); - let expr_ty = - state.or_else(expr_res, TypeKind::Vague(Vague::Unknown), field_expr.1); + let expr_ty = state.or_else(expr_res, TypeKind::Vague(Vague::Unknown), field_expr.1); // Make sure both are the same type, report error if not state.ok(expr_ty.narrow_into(&expr_ty), field_expr.1); @@ -829,7 +709,6 @@ impl Literal { /// Try to coerce this literal, ie. convert it to a more specific type in /// regards to the given hint if any. fn try_coerce(self, hint: Option) -> Result { - dbg!(&self, &hint); if let Some(hint) = &hint { use Literal as L; use VagueLiteral as VagueL; diff --git a/reid/src/mir/typecheck/typeinference.rs b/reid/src/mir/typecheck/typeinference.rs index 4a04a59..efc61a0 100644 --- a/reid/src/mir/typecheck/typeinference.rs +++ b/reid/src/mir/typecheck/typeinference.rs @@ -12,9 +12,8 @@ use std::{ use crate::{ mir::{ - BinopDefinition, Block, CustomTypeKey, ExprKind, Expression, FunctionDefinition, - FunctionDefinitionKind, IfExpression, Module, ReturnKind, StmtKind, TypeKind, - WhileStatement, + BinopDefinition, Block, CustomTypeKey, ExprKind, Expression, FunctionDefinition, FunctionDefinitionKind, + IfExpression, Module, ReturnKind, StmtKind, TypeKind, WhileStatement, }, util::try_all, }; @@ -46,10 +45,7 @@ impl<'t> Pass for TypeInference<'t> { for function in &mut module.functions { if let Some(kind) = seen_functions.get(&function.name) { state.note_errors( - &vec![ErrorKind::FunctionAlreadyDefined( - function.name.clone(), - *kind, - )], + &vec![ErrorKind::FunctionAlreadyDefined(function.name.clone(), *kind)], function.signature(), ); } else { @@ -70,8 +66,7 @@ impl<'t> Pass for TypeInference<'t> { params: (binop.lhs.1.clone(), binop.rhs.1.clone()), operator: binop.op, }; - if seen_binops.contains(&binop_key) - || (binop.lhs == binop.rhs && binop.lhs.1.category().is_simple_maths()) + if seen_binops.contains(&binop_key) || (binop.lhs == binop.rhs && binop.lhs.1.category().is_simple_maths()) { state.note_errors( &vec![ErrorKind::BinaryOpAlreadyDefined( @@ -100,18 +95,10 @@ impl<'t> Pass for TypeInference<'t> { } impl BinopDefinition { - fn infer_types( - &mut self, - type_refs: &TypeRefs, - state: &mut TypecheckPassState, - ) -> Result<(), ErrorKind> { + fn infer_types(&mut self, type_refs: &TypeRefs, state: &mut TypecheckPassState) -> Result<(), ErrorKind> { let scope_hints = ScopeTypeRefs::from(type_refs); - let lhs_ty = state.or_else( - self.lhs.1.assert_unvague(), - Vague(Unknown), - self.signature(), - ); + let lhs_ty = state.or_else(self.lhs.1.assert_unvague(), Vague(Unknown), self.signature()); state.ok( scope_hints .new_var(self.lhs.0.clone(), false, &lhs_ty) @@ -119,11 +106,7 @@ impl BinopDefinition { self.signature(), ); - let rhs_ty = state.or_else( - self.rhs.1.assert_unvague(), - Vague(Unknown), - self.signature(), - ); + let rhs_ty = state.or_else(self.rhs.1.assert_unvague(), Vague(Unknown), self.signature()); state.ok( scope_hints @@ -132,9 +115,9 @@ impl BinopDefinition { self.signature(), ); - let ret_ty = - self.fn_kind - .infer_types(state, &scope_hints, Some(self.return_type.clone()))?; + let ret_ty = self + .fn_kind + .infer_types(state, &scope_hints, Some(self.return_type.clone()))?; if let Some(mut ret_ty) = ret_ty { ret_ty.narrow(&scope_hints.from_type(&self.return_type).unwrap()); } @@ -144,11 +127,7 @@ impl BinopDefinition { } impl FunctionDefinition { - fn infer_types( - &mut self, - type_refs: &TypeRefs, - state: &mut TypecheckPassState, - ) -> Result<(), ErrorKind> { + fn infer_types(&mut self, type_refs: &TypeRefs, state: &mut TypecheckPassState) -> Result<(), ErrorKind> { let scope_refs = ScopeTypeRefs::from(type_refs); for param in &self.parameters { let param_t = state.or_else(param.1.assert_unvague(), Vague(Unknown), self.signature()); @@ -221,8 +200,7 @@ impl Block { match &mut statement.0 { StmtKind::Let(var, mutable, expr) => { // Get the TypeRef for this variable declaration - let mut var_ref = - state.ok(inner_refs.new_var(var.1.clone(), *mutable, &var.0), var.2); + let mut var_ref = state.ok(inner_refs.new_var(var.1.clone(), *mutable, &var.0), var.2); // If ok, update the MIR type to this TypeRef if let Some(var_ref) = &var_ref { @@ -235,9 +213,7 @@ impl Block { // Try to narrow the variable type declaration with the // expression - if let (Some(var_ref), Some(expr_ty_ref)) = - (var_ref.as_mut(), expr_ty_ref.as_mut()) - { + if let (Some(var_ref), Some(expr_ty_ref)) = (var_ref.as_mut(), expr_ty_ref.as_mut()) { var_ref.narrow(&expr_ty_ref); } } @@ -260,9 +236,7 @@ impl Block { let expr_res = expr.infer_types(&mut state, &inner_refs); state.ok(expr_res, expr.1); } - StmtKind::While(WhileStatement { - condition, block, .. - }) => { + StmtKind::While(WhileStatement { condition, block, .. }) => { condition.infer_types(&mut state, &inner_refs)?; block.infer_types(&mut state, &inner_refs)?; } @@ -336,11 +310,7 @@ impl Expression { rhs_ref.narrow(&type_refs.from_type(&widened_rhs).unwrap()); Ok(type_refs.from_binop(*op, &lhs_ref, &rhs_ref)) } else { - Err(ErrorKind::InvalidBinop( - *op, - lhs_ref.resolve_deep().unwrap(), - rhs_ref.resolve_deep().unwrap(), - )) + panic!(); } } ExprKind::FunctionCall(function_call) => { @@ -357,9 +327,7 @@ impl Expression { // many were provided) let true_params_iter = fn_call.params.iter().chain(iter::repeat(&Vague(Unknown))); - for (param_expr, param_t) in - function_call.parameters.iter_mut().zip(true_params_iter) - { + for (param_expr, param_t) in function_call.parameters.iter_mut().zip(true_params_iter) { let expr_res = param_expr.infer_types(state, type_refs); if let Some(mut param_ref) = state.ok(expr_res, param_expr.1) { param_ref.narrow(&mut type_refs.from_type(param_t).unwrap()); @@ -390,12 +358,10 @@ impl Expression { // Narrow LHS to the same type as RHS and return it's return type if let (Some(mut lhs_hints), Some(mut rhs_hints)) = (lhs_hints, rhs_hints) { - lhs_hints - .narrow(&mut rhs_hints) - .ok_or(ErrorKind::TypesIncompatible( - lhs_hints.resolve_deep().unwrap(), - rhs_hints.resolve_deep().unwrap(), - )) + lhs_hints.narrow(&mut rhs_hints).ok_or(ErrorKind::TypesIncompatible( + lhs_hints.resolve_deep().unwrap(), + rhs_hints.resolve_deep().unwrap(), + )) } else { // Failed to retrieve types from either Ok(type_refs.from_type(&Vague(Unknown)).unwrap()) @@ -451,15 +417,10 @@ impl Expression { } Ok(type_refs - .from_type(&Array( - Box::new(first.as_type()), - expressions.len() as u64, - )) + .from_type(&Array(Box::new(first.as_type()), expressions.len() as u64)) .unwrap()) } else { - Ok(type_refs - .from_type(&Array(Box::new(TypeKind::Void), 0)) - .unwrap()) + Ok(type_refs.from_type(&Array(Box::new(TypeKind::Void), 0)).unwrap()) } } Err(errors) => { @@ -503,10 +464,7 @@ impl Expression { let expected_struct_ty = state .scope .get_struct_type(&type_key) - .ok_or(ErrorKind::NoSuchType( - struct_name.clone(), - state.module_id.unwrap(), - ))? + .ok_or(ErrorKind::NoSuchType(struct_name.clone(), state.module_id.unwrap()))? .clone(); for field in fields { if let Some(expected_field_ty) = expected_struct_ty.get_field_ty(&field.0) { @@ -516,17 +474,12 @@ impl Expression { } } else { state.ok::<_, Infallible>( - Err(ErrorKind::NoSuchField(format!( - "{}.{}", - struct_name, field.0 - ))), + Err(ErrorKind::NoSuchField(format!("{}.{}", struct_name, field.0))), field.1 .1, ); } } - Ok(type_refs - .from_type(&TypeKind::CustomType(type_key.clone())) - .unwrap()) + Ok(type_refs.from_type(&TypeKind::CustomType(type_key.clone())).unwrap()) } ExprKind::Borrow(var, mutable) => { // Find variable type diff --git a/reid/src/mir/typecheck/typerefs.rs b/reid/src/mir/typecheck/typerefs.rs index c06538a..9cc3f8c 100644 --- a/reid/src/mir/typecheck/typerefs.rs +++ b/reid/src/mir/typecheck/typerefs.rs @@ -15,10 +15,7 @@ use super::{ }; #[derive(Clone)] -pub struct TypeRef<'scope>( - pub(super) TypeIdRef, - pub(super) &'scope ScopeTypeRefs<'scope>, -); +pub struct TypeRef<'scope>(pub(super) TypeIdRef, pub(super) &'scope ScopeTypeRefs<'scope>); impl<'scope> TypeRef<'scope> { /// Resolve current type in a weak manner, not resolving any Arrays or @@ -99,7 +96,7 @@ pub struct TypeRefs { pub(super) hints: RefCell>, /// Indirect ID-references, referring to hints-vec pub(super) type_refs: RefCell>, - binop_types: BinopMap, + pub(super) binop_types: BinopMap, } impl std::fmt::Display for TypeRefs { @@ -132,9 +129,7 @@ impl TypeRefs { let idx = self.hints.borrow().len(); let typecell = Rc::new(RefCell::new(idx)); self.type_refs.borrow_mut().push(typecell.clone()); - self.hints - .borrow_mut() - .push(TypeRefKind::Direct(ty.clone())); + self.hints.borrow_mut().push(TypeRefKind::Direct(ty.clone())); typecell } @@ -183,11 +178,7 @@ impl TypeRefs { pub fn retrieve_wide_type(&self, idx: usize) -> Option { let inner_idx = unsafe { *self.recurse_type_ref(idx).borrow() }; - self.hints - .borrow() - .get(inner_idx) - .cloned() - .map(|t| t.widen(self)) + self.hints.borrow().get(inner_idx).cloned().map(|t| t.widen(self)) } } @@ -218,9 +209,7 @@ impl<'outer> ScopeTypeRefs<'outer> { return Err(ErrorKind::VariableAlreadyDefined(name)); } let type_ref = self.from_type(&initial_ty).unwrap(); - self.variables - .borrow_mut() - .insert(name, (mutable, type_ref.0.clone())); + self.variables.borrow_mut().insert(name, (mutable, type_ref.0.clone())); Ok(type_ref) } @@ -233,8 +222,7 @@ impl<'outer> ScopeTypeRefs<'outer> { TypeKind::Vague(_) => self.types.new(ty), TypeKind::Array(elem_ty, length) => { let elem_ty = self.from_type(elem_ty)?; - self.types - .new(&TypeKind::Array(Box::new(elem_ty.as_type()), *length)) + self.types.new(&TypeKind::Array(Box::new(elem_ty.as_type()), *length)) } TypeKind::Borrow(ty, mutable) => { let inner_ty = self.from_type(ty)?; @@ -252,12 +240,7 @@ impl<'outer> ScopeTypeRefs<'outer> { Some(TypeRef(idx, self)) } - pub fn from_binop( - &'outer self, - op: BinaryOperator, - lhs: &TypeRef, - rhs: &TypeRef, - ) -> TypeRef<'outer> { + pub fn from_binop(&'outer self, op: BinaryOperator, lhs: &TypeRef, rhs: &TypeRef) -> TypeRef<'outer> { TypeRef(self.types.binop(op, lhs, rhs), self) } @@ -276,10 +259,9 @@ impl<'outer> ScopeTypeRefs<'outer> { .iter() .filter(|b| b.1.operator == *op && b.1.return_ty == *ty); for binop in binops { - if let (Ok(lhs_narrow), Ok(rhs_narrow)) = ( - lhs.narrow_into(&binop.1.hands.0), - rhs.narrow_into(&binop.1.hands.1), - ) { + if let (Ok(lhs_narrow), Ok(rhs_narrow)) = + (lhs.narrow_into(&binop.1.hands.0), rhs.narrow_into(&binop.1.hands.1)) + { *lhs = lhs_narrow; *rhs = rhs_narrow }