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> {
|
pub fn form_intrinsic_binops() -> Vec<BinopDefinition> {
|
||||||
let mut intrinsics = Vec::new();
|
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
|
intrinsics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,11 +95,11 @@ impl TypeKind {
|
|||||||
|
|
||||||
/// Return the type that is the result of a binary operator between two
|
/// Return the type that is the result of a binary operator between two
|
||||||
/// values of this type
|
/// values of this type
|
||||||
pub fn simple_binop_type(&self, op: &BinaryOperator) -> TypeKind {
|
pub fn simple_binop_type(&self, op: &BinaryOperator) -> Option<TypeKind> {
|
||||||
// TODO make some type of mechanism that allows to binop two values of
|
if !self.category().is_simple_maths() {
|
||||||
// differing types..
|
return None;
|
||||||
// TODO Return None for arrays later
|
}
|
||||||
match op {
|
Some(match op {
|
||||||
BinaryOperator::Add => self.clone(),
|
BinaryOperator::Add => self.clone(),
|
||||||
BinaryOperator::Minus => self.clone(),
|
BinaryOperator::Minus => self.clone(),
|
||||||
BinaryOperator::Mult => self.clone(),
|
BinaryOperator::Mult => self.clone(),
|
||||||
@ -107,7 +107,7 @@ impl TypeKind {
|
|||||||
BinaryOperator::Cmp(_) => TypeKind::Bool,
|
BinaryOperator::Cmp(_) => TypeKind::Bool,
|
||||||
BinaryOperator::Div => self.clone(),
|
BinaryOperator::Div => self.clone(),
|
||||||
BinaryOperator::Mod => self.clone(),
|
BinaryOperator::Mod => self.clone(),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn binop_type(
|
pub fn binop_type(
|
||||||
@ -127,6 +127,9 @@ impl TypeKind {
|
|||||||
/// Reverse of binop_type, where the given hint is the known required output
|
/// 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.
|
/// 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> {
|
pub fn simple_binop_hint(&self, op: &BinaryOperator) -> Option<TypeKind> {
|
||||||
|
if !self.category().is_simple_maths() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
match op {
|
match op {
|
||||||
BinaryOperator::Add
|
BinaryOperator::Add
|
||||||
| BinaryOperator::Minus
|
| BinaryOperator::Minus
|
||||||
@ -275,7 +278,7 @@ impl TypeKind {
|
|||||||
| TypeKind::F80
|
| TypeKind::F80
|
||||||
| TypeKind::F128PPC => TypeCategory::Real,
|
| TypeKind::F128PPC => TypeCategory::Real,
|
||||||
TypeKind::Void => TypeCategory::Other,
|
TypeKind::Void => TypeCategory::Other,
|
||||||
TypeKind::Bool => TypeCategory::Other,
|
TypeKind::Bool => TypeCategory::Bool,
|
||||||
TypeKind::Array(_, _) => TypeCategory::Other,
|
TypeKind::Array(_, _) => TypeCategory::Other,
|
||||||
TypeKind::CustomType(..) => TypeCategory::Other,
|
TypeKind::CustomType(..) => TypeCategory::Other,
|
||||||
TypeKind::Borrow(_, _) => TypeCategory::Other,
|
TypeKind::Borrow(_, _) => TypeCategory::Other,
|
||||||
@ -329,10 +332,23 @@ impl BinaryOperator {
|
|||||||
pub enum TypeCategory {
|
pub enum TypeCategory {
|
||||||
Integer,
|
Integer,
|
||||||
Real,
|
Real,
|
||||||
|
Bool,
|
||||||
Other,
|
Other,
|
||||||
TypeRef,
|
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 {
|
impl StructType {
|
||||||
pub fn get_field_ty(&self, name: &String) -> Option<&TypeKind> {
|
pub fn get_field_ty(&self, name: &String) -> Option<&TypeKind> {
|
||||||
self.0
|
self.0
|
||||||
|
@ -64,14 +64,16 @@ pub enum ErrorKind {
|
|||||||
ImpossibleMutableBorrow(String),
|
ImpossibleMutableBorrow(String),
|
||||||
#[error("Cannot declare variable {0} as mutable, when it's type is immutable")]
|
#[error("Cannot declare variable {0} as mutable, when it's type is immutable")]
|
||||||
ImpossibleMutLet(String),
|
ImpossibleMutLet(String),
|
||||||
#[error("Cannot produce a negative unsigned value of type {0}!")]
|
#[error("Cannot produce a negative unsigned value of type {0}")]
|
||||||
NegativeUnsignedValue(TypeKind),
|
NegativeUnsignedValue(TypeKind),
|
||||||
#[error("Cannot cast type {0} into type {1}!")]
|
#[error("Cannot cast type {0} into type {1}")]
|
||||||
NotCastableTo(TypeKind, TypeKind),
|
NotCastableTo(TypeKind, TypeKind),
|
||||||
#[error("Cannot divide by zero")]
|
#[error("Cannot divide by zero")]
|
||||||
DivideZero,
|
DivideZero,
|
||||||
#[error("Binary operation between {0} and {1} is already defined!")]
|
#[error("Binary operation {0} between {1} and {2} is already defined")]
|
||||||
BinaryOpAlreadyDefined(TypeKind, TypeKind),
|
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
|
/// 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();
|
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) => {
|
ExprKind::FunctionCall(function_call) => {
|
||||||
|
@ -65,9 +65,12 @@ impl<'t> Pass for TypeInference<'t> {
|
|||||||
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
||||||
operator: binop.op,
|
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(
|
state.note_errors(
|
||||||
&vec![ErrorKind::BinaryOpAlreadyDefined(
|
&vec![ErrorKind::BinaryOpAlreadyDefined(
|
||||||
|
binop.op,
|
||||||
binop.lhs.1.clone(),
|
binop.lhs.1.clone(),
|
||||||
binop.rhs.1.clone(),
|
binop.rhs.1.clone(),
|
||||||
)],
|
)],
|
||||||
@ -323,7 +326,17 @@ impl Expression {
|
|||||||
} else {
|
} else {
|
||||||
let typeref = lhs_ref.narrow(&rhs_ref).unwrap();
|
let typeref = lhs_ref.narrow(&rhs_ref).unwrap();
|
||||||
Ok(type_refs
|
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())
|
.unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user