Embrace having megaintrinsic binops
This commit is contained in:
parent
ccdefe7033
commit
f6425fc37e
0
.rustfmt.toml
Normal file
0
.rustfmt.toml
Normal file
@ -47,42 +47,6 @@ pub fn form_intrinsics() -> Vec<FunctionDefinition> {
|
||||
pub fn form_intrinsic_binops() -> Vec<BinopDefinition> {
|
||||
let mut intrinsics = Vec::new();
|
||||
|
||||
intrinsics.push(intrinsic_binop(
|
||||
BinaryOperator::Add,
|
||||
TypeKind::U8,
|
||||
TypeKind::U8,
|
||||
TypeKind::U8,
|
||||
IntrinsicIAdd(TypeKind::U8),
|
||||
));
|
||||
intrinsics.push(intrinsic_binop(
|
||||
BinaryOperator::Add,
|
||||
TypeKind::U32,
|
||||
TypeKind::U32,
|
||||
TypeKind::U32,
|
||||
IntrinsicIAdd(TypeKind::U32),
|
||||
));
|
||||
intrinsics.push(intrinsic_binop(
|
||||
BinaryOperator::Add,
|
||||
TypeKind::U16,
|
||||
TypeKind::U16,
|
||||
TypeKind::U16,
|
||||
IntrinsicIAdd(TypeKind::U16),
|
||||
));
|
||||
intrinsics.push(intrinsic_binop(
|
||||
BinaryOperator::Div,
|
||||
TypeKind::U16,
|
||||
TypeKind::U16,
|
||||
TypeKind::U16,
|
||||
IntrinsicUDiv(TypeKind::U16),
|
||||
));
|
||||
intrinsics.push(intrinsic_binop(
|
||||
BinaryOperator::Mod,
|
||||
TypeKind::U16,
|
||||
TypeKind::U16,
|
||||
TypeKind::U16,
|
||||
IntrinsicUMod(TypeKind::U16),
|
||||
));
|
||||
|
||||
intrinsics
|
||||
}
|
||||
|
||||
|
@ -95,11 +95,11 @@ impl TypeKind {
|
||||
|
||||
/// Return the type that is the result of a binary operator between two
|
||||
/// values of this type
|
||||
pub fn simple_binop_type(&self, op: &BinaryOperator) -> TypeKind {
|
||||
// TODO make some type of mechanism that allows to binop two values of
|
||||
// differing types..
|
||||
// TODO Return None for arrays later
|
||||
match op {
|
||||
pub fn simple_binop_type(&self, op: &BinaryOperator) -> Option<TypeKind> {
|
||||
if !self.category().is_simple_maths() {
|
||||
return None;
|
||||
}
|
||||
Some(match op {
|
||||
BinaryOperator::Add => self.clone(),
|
||||
BinaryOperator::Minus => self.clone(),
|
||||
BinaryOperator::Mult => self.clone(),
|
||||
@ -107,7 +107,7 @@ impl TypeKind {
|
||||
BinaryOperator::Cmp(_) => TypeKind::Bool,
|
||||
BinaryOperator::Div => self.clone(),
|
||||
BinaryOperator::Mod => self.clone(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn binop_type(
|
||||
@ -127,6 +127,9 @@ impl TypeKind {
|
||||
/// Reverse of binop_type, where the given hint is the known required output
|
||||
/// type of the binop, and the output is the hint for the lhs/rhs type.
|
||||
pub fn simple_binop_hint(&self, op: &BinaryOperator) -> Option<TypeKind> {
|
||||
if !self.category().is_simple_maths() {
|
||||
return None;
|
||||
}
|
||||
match op {
|
||||
BinaryOperator::Add
|
||||
| BinaryOperator::Minus
|
||||
@ -275,7 +278,7 @@ impl TypeKind {
|
||||
| TypeKind::F80
|
||||
| TypeKind::F128PPC => TypeCategory::Real,
|
||||
TypeKind::Void => TypeCategory::Other,
|
||||
TypeKind::Bool => TypeCategory::Other,
|
||||
TypeKind::Bool => TypeCategory::Bool,
|
||||
TypeKind::Array(_, _) => TypeCategory::Other,
|
||||
TypeKind::CustomType(..) => TypeCategory::Other,
|
||||
TypeKind::Borrow(_, _) => TypeCategory::Other,
|
||||
@ -329,10 +332,23 @@ impl BinaryOperator {
|
||||
pub enum TypeCategory {
|
||||
Integer,
|
||||
Real,
|
||||
Bool,
|
||||
Other,
|
||||
TypeRef,
|
||||
}
|
||||
|
||||
impl TypeCategory {
|
||||
pub fn is_simple_maths(&self) -> bool {
|
||||
match self {
|
||||
TypeCategory::Integer => true,
|
||||
TypeCategory::Real => true,
|
||||
TypeCategory::Other => false,
|
||||
TypeCategory::TypeRef => false,
|
||||
TypeCategory::Bool => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StructType {
|
||||
pub fn get_field_ty(&self, name: &String) -> Option<&TypeKind> {
|
||||
self.0
|
||||
|
@ -64,14 +64,16 @@ pub enum ErrorKind {
|
||||
ImpossibleMutableBorrow(String),
|
||||
#[error("Cannot declare variable {0} as mutable, when it's type is immutable")]
|
||||
ImpossibleMutLet(String),
|
||||
#[error("Cannot produce a negative unsigned value of type {0}!")]
|
||||
#[error("Cannot produce a negative unsigned value of type {0}")]
|
||||
NegativeUnsignedValue(TypeKind),
|
||||
#[error("Cannot cast type {0} into type {1}!")]
|
||||
#[error("Cannot cast type {0} into type {1}")]
|
||||
NotCastableTo(TypeKind, TypeKind),
|
||||
#[error("Cannot divide by zero")]
|
||||
DivideZero,
|
||||
#[error("Binary operation between {0} and {1} is already defined!")]
|
||||
BinaryOpAlreadyDefined(TypeKind, TypeKind),
|
||||
#[error("Binary operation {0} between {1} and {2} is already defined")]
|
||||
BinaryOpAlreadyDefined(BinaryOperator, TypeKind, TypeKind),
|
||||
#[error("Binary operation {0} between {1} and {2} is not defined")]
|
||||
InvalidBinop(BinaryOperator, TypeKind, TypeKind),
|
||||
}
|
||||
|
||||
/// Struct used to implement a type-checking pass that can be performed on the
|
||||
@ -580,7 +582,9 @@ impl Expression {
|
||||
rhs.typecheck(state, &typerefs, Some(&collapsed)).ok();
|
||||
}
|
||||
|
||||
Ok(both_t.simple_binop_type(op))
|
||||
both_t
|
||||
.simple_binop_type(op)
|
||||
.ok_or(ErrorKind::InvalidBinop(*op, lhs_type, rhs_type))
|
||||
}
|
||||
}
|
||||
ExprKind::FunctionCall(function_call) => {
|
||||
|
@ -65,9 +65,12 @@ impl<'t> Pass for TypeInference<'t> {
|
||||
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
||||
operator: binop.op,
|
||||
};
|
||||
if seen_binops.contains(&binop_key) {
|
||||
if seen_binops.contains(&binop_key)
|
||||
|| (binop.lhs == binop.rhs && binop.lhs.1.category().is_simple_maths())
|
||||
{
|
||||
state.note_errors(
|
||||
&vec![ErrorKind::BinaryOpAlreadyDefined(
|
||||
binop.op,
|
||||
binop.lhs.1.clone(),
|
||||
binop.rhs.1.clone(),
|
||||
)],
|
||||
@ -323,7 +326,17 @@ impl Expression {
|
||||
} else {
|
||||
let typeref = lhs_ref.narrow(&rhs_ref).unwrap();
|
||||
Ok(type_refs
|
||||
.from_type(&typeref.resolve_deep().unwrap().simple_binop_type(op))
|
||||
.from_type(
|
||||
&typeref
|
||||
.resolve_deep()
|
||||
.unwrap()
|
||||
.simple_binop_type(op)
|
||||
.ok_or(ErrorKind::InvalidBinop(
|
||||
*op,
|
||||
lhs_ref.resolve_deep().unwrap(),
|
||||
rhs_ref.resolve_deep().unwrap(),
|
||||
))?,
|
||||
)
|
||||
.unwrap())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user