forked from M-Labs/nac3
better structured primitive magic methods impl
This commit is contained in:
parent
b87c627c41
commit
7e0d55443a
|
@ -1,4 +1,5 @@
|
||||||
use std::{collections::HashMap, rc::Rc};
|
use std::collections::HashMap;
|
||||||
|
use std::rc::Rc;
|
||||||
use rustpython_parser::ast::{Cmpop, Operator, Unaryop};
|
use rustpython_parser::ast::{Cmpop, Operator, Unaryop};
|
||||||
|
|
||||||
pub fn binop_name(op: &Operator) -> &'static str {
|
pub fn binop_name(op: &Operator) -> &'static str {
|
||||||
|
@ -58,291 +59,25 @@ pub fn comparison_name(op: &Cmpop) -> Option<&'static str> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::typecheck::{type_inferencer::*, typedef::{FunSignature, FuncArg, TypeEnum, Unifier}};
|
use crate::typecheck::{type_inferencer::*, typedef::{FunSignature, FuncArg, TypeEnum, Unifier, Type}};
|
||||||
use rustpython_parser::ast;
|
use rustpython_parser::ast;
|
||||||
pub fn set_primirives_magic_methods(store: &PrimitiveStore, unifier: &mut Unifier) {
|
|
||||||
// int32 --------
|
|
||||||
if let Some(TypeEnum::TObj {fields, .. }) = Rc::get_mut(&mut unifier.get_ty(store.int32)) {
|
|
||||||
for op in &[
|
|
||||||
ast::Operator::Add,
|
|
||||||
ast::Operator::Sub,
|
|
||||||
ast::Operator::Mult,
|
|
||||||
ast::Operator::Mod,
|
|
||||||
ast::Operator::Pow,
|
|
||||||
ast::Operator::LShift,
|
|
||||||
ast::Operator::RShift,
|
|
||||||
ast::Operator::BitOr,
|
|
||||||
ast::Operator::BitXor,
|
|
||||||
ast::Operator::BitAnd,
|
|
||||||
ast::Operator::FloorDiv
|
|
||||||
] {
|
|
||||||
fields.insert(
|
|
||||||
binop_name(op).to_string(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.int32,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.int32,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into() // the name does not matter here
|
|
||||||
}],
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
fields.insert(
|
|
||||||
binop_assign_name(op).to_string(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.none,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.int32,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into()
|
|
||||||
}]
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
};
|
|
||||||
// int div int gets float
|
|
||||||
fields.insert(
|
|
||||||
binop_assign_name(&ast::Operator::Div).into(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.float,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.int32,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into()
|
|
||||||
}]
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
|
/// Add, Sub, Mult, Pow
|
||||||
|
pub fn impl_basic_arithmetic(unifier: &mut Unifier, store: &PrimitiveStore, ty: Type, other_ty: Type, ret_ty: Type) {
|
||||||
|
if let Some(TypeEnum::TObj {fields, .. }) = Rc::get_mut(&mut unifier.get_ty(ty)) {
|
||||||
for op in &[
|
for op in &[
|
||||||
ast::Cmpop::Eq,
|
ast::Operator::Add,
|
||||||
ast::Cmpop::NotEq,
|
ast::Operator::Sub,
|
||||||
ast::Cmpop::Lt,
|
ast::Operator::Mult,
|
||||||
ast::Cmpop::LtE,
|
ast::Operator::Pow,
|
||||||
ast::Cmpop::Gt,
|
|
||||||
ast::Cmpop::GtE,
|
|
||||||
] {
|
|
||||||
fields.insert(
|
|
||||||
comparison_name(op).unwrap().to_string(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.bool,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.int32,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into()
|
|
||||||
}],
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for op in &[
|
|
||||||
ast::Unaryop::UAdd,
|
|
||||||
ast::Unaryop::USub,
|
|
||||||
ast::Unaryop::Not,
|
|
||||||
ast::Unaryop::Invert,
|
|
||||||
] {
|
|
||||||
fields.insert(
|
|
||||||
unaryop_name(op).into(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.int32,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![]
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else { unreachable!() }
|
|
||||||
// int32 --------
|
|
||||||
// int64 --------
|
|
||||||
if let Some(TypeEnum::TObj {fields, .. }) = Rc::get_mut(&mut unifier.get_ty(store.int64)) {
|
|
||||||
for op in &[
|
|
||||||
ast::Operator::Add,
|
|
||||||
ast::Operator::Sub,
|
|
||||||
ast::Operator::Mult,
|
|
||||||
ast::Operator::Mod,
|
|
||||||
ast::Operator::Pow,
|
|
||||||
ast::Operator::LShift,
|
|
||||||
ast::Operator::RShift,
|
|
||||||
ast::Operator::BitOr,
|
|
||||||
ast::Operator::BitXor,
|
|
||||||
ast::Operator::BitAnd,
|
|
||||||
ast::Operator::FloorDiv
|
|
||||||
] {
|
|
||||||
fields.insert(
|
|
||||||
binop_name(op).to_string(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.int64,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.int64,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into() // the name does not matter here
|
|
||||||
}],
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
fields.insert(
|
|
||||||
binop_assign_name(op).to_string(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.none,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.int64,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into()
|
|
||||||
}]
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
};
|
|
||||||
fields.insert(
|
|
||||||
binop_assign_name(&ast::Operator::Div).into(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.float,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.int64,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into()
|
|
||||||
}]
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
for op in &[
|
|
||||||
ast::Cmpop::Eq,
|
|
||||||
ast::Cmpop::NotEq,
|
|
||||||
ast::Cmpop::Lt,
|
|
||||||
ast::Cmpop::LtE,
|
|
||||||
ast::Cmpop::Gt,
|
|
||||||
ast::Cmpop::GtE,
|
|
||||||
] {
|
|
||||||
fields.insert(
|
|
||||||
comparison_name(op).unwrap().to_string(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.bool,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.int64,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into()
|
|
||||||
}],
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for op in &[
|
|
||||||
ast::Unaryop::UAdd,
|
|
||||||
ast::Unaryop::USub,
|
|
||||||
ast::Unaryop::Not,
|
|
||||||
ast::Unaryop::Invert,
|
|
||||||
] {
|
|
||||||
fields.insert(
|
|
||||||
unaryop_name(op).into(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.int64,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![]
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else { unreachable!() }
|
|
||||||
// int64 --------
|
|
||||||
// float --------
|
|
||||||
if let Some(TypeEnum::TObj {fields, .. }) = Rc::get_mut(&mut unifier.get_ty(store.float)) {
|
|
||||||
for op in &[
|
|
||||||
ast::Operator::Add,
|
|
||||||
ast::Operator::Sub,
|
|
||||||
ast::Operator::Mult,
|
|
||||||
ast::Operator::Div,
|
|
||||||
ast::Operator::Mod,
|
|
||||||
ast::Operator::Pow,
|
|
||||||
ast::Operator::FloorDiv,
|
|
||||||
] {
|
|
||||||
fields.insert(
|
|
||||||
binop_name(op).to_string(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.float,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.float,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into() // the name does not matter here
|
|
||||||
}],
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
fields.insert(
|
|
||||||
binop_assign_name(op).to_string(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.none,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.float,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into()
|
|
||||||
}]
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
for op in &[
|
|
||||||
ast::Cmpop::Eq,
|
|
||||||
ast::Cmpop::NotEq,
|
|
||||||
ast::Cmpop::Lt,
|
|
||||||
ast::Cmpop::LtE,
|
|
||||||
ast::Cmpop::Gt,
|
|
||||||
ast::Cmpop::GtE,
|
|
||||||
] {
|
|
||||||
fields.insert(
|
|
||||||
comparison_name(op).unwrap().to_string(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.bool,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.float,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into()
|
|
||||||
}],
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for op in &[
|
|
||||||
ast::Unaryop::UAdd,
|
|
||||||
ast::Unaryop::USub,
|
|
||||||
ast::Unaryop::Not,
|
|
||||||
] {
|
|
||||||
fields.insert(
|
|
||||||
unaryop_name(op).into(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.int64,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![]
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else { unreachable!() }
|
|
||||||
// float --------
|
|
||||||
// bool ---------
|
|
||||||
if let Some(TypeEnum::TObj {fields, .. }) = Rc::get_mut(&mut unifier.get_ty(store.bool)) {
|
|
||||||
for op in &[
|
|
||||||
ast::Operator::Add,
|
|
||||||
ast::Operator::Sub,
|
|
||||||
ast::Operator::Mult,
|
|
||||||
ast::Operator::Mod,
|
|
||||||
ast::Operator::Pow,
|
|
||||||
ast::Operator::LShift,
|
|
||||||
ast::Operator::RShift,
|
|
||||||
ast::Operator::FloorDiv
|
|
||||||
] {
|
] {
|
||||||
fields.insert(
|
fields.insert(
|
||||||
binop_name(op).into(),
|
binop_name(op).into(),
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||||
ret: store.int32,
|
ret: ret_ty,
|
||||||
vars: HashMap::new(),
|
vars: HashMap::new(),
|
||||||
args: vec![FuncArg {
|
args: vec![FuncArg {
|
||||||
ty: store.bool,
|
ty: other_ty,
|
||||||
is_optional: false,
|
is_optional: false,
|
||||||
name: "other".into()
|
name: "other".into()
|
||||||
}]
|
}]
|
||||||
|
@ -350,55 +85,204 @@ pub fn set_primirives_magic_methods(store: &PrimitiveStore, unifier: &mut Unifie
|
||||||
);
|
);
|
||||||
|
|
||||||
fields.insert(
|
fields.insert(
|
||||||
binop_name(op).into(),
|
binop_assign_name(op).into(),
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||||
ret: store.int32,
|
ret: store.none,
|
||||||
vars: HashMap::new(),
|
vars: HashMap::new(),
|
||||||
args: vec![FuncArg {
|
args: vec![FuncArg {
|
||||||
ty: store.int32,
|
ty: other_ty,
|
||||||
is_optional: false,
|
is_optional: false,
|
||||||
name: "other".into()
|
name: "other".into()
|
||||||
}]
|
}]
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
} else { unreachable!() }
|
||||||
|
}
|
||||||
|
|
||||||
// binop_assignment will change type?
|
/// LShift, RShift, BitOr, BitXor, BitAnd
|
||||||
/* fields.insert(
|
pub fn impl_bitwise_arithmetic(unifier: &mut Unifier, store: &PrimitiveStore, ty: Type) {
|
||||||
binop_assignment_name(op).into(),
|
if let Some(TypeEnum::TObj {fields, ..}) = Rc::get_mut(&mut unifier.get_ty(ty)) {
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
|
||||||
ret: store.none,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
args: vec![FuncArg {
|
|
||||||
ty: store.bool,
|
|
||||||
is_optional: false,
|
|
||||||
name: "other".into()
|
|
||||||
}]
|
|
||||||
}))
|
|
||||||
); */
|
|
||||||
};
|
|
||||||
|
|
||||||
for op in &[
|
for op in &[
|
||||||
|
ast::Operator::LShift,
|
||||||
|
ast::Operator::RShift,
|
||||||
ast::Operator::BitOr,
|
ast::Operator::BitOr,
|
||||||
ast::Operator::BitXor,
|
ast::Operator::BitXor,
|
||||||
ast::Operator::BitAnd
|
ast::Operator::BitAnd,
|
||||||
] {
|
] {
|
||||||
fields.insert(
|
fields.insert(
|
||||||
binop_name(op).into(),
|
binop_name(op).into(),
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||||
ret: store.bool,
|
ret: ty,
|
||||||
vars: HashMap::new(),
|
vars: HashMap::new(),
|
||||||
args: vec![FuncArg {
|
args: vec![FuncArg {
|
||||||
ty: store.int32,
|
ty,
|
||||||
is_optional: false,
|
is_optional: false,
|
||||||
name: "other".into()
|
name: "other".into()
|
||||||
}]
|
}]
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
|
fields.insert(
|
||||||
|
binop_assign_name(op).into(),
|
||||||
|
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||||
|
ret: store.none,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
args: vec![FuncArg {
|
||||||
|
ty,
|
||||||
|
is_optional: false,
|
||||||
|
name: "other".into()
|
||||||
|
}]
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Div
|
||||||
|
pub fn impl_div(unifier: &mut Unifier, store: &PrimitiveStore, ty: Type, other_ty: Type) {
|
||||||
|
if let Some(TypeEnum::TObj {fields, ..}) = Rc::get_mut(&mut unifier.get_ty(ty)) {
|
||||||
|
fields.insert(
|
||||||
|
binop_name(&ast::Operator::Div).into(),
|
||||||
|
unifier.add_ty(TypeEnum::TFunc(FunSignature{
|
||||||
|
ret: store.float,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
args: vec![FuncArg {
|
||||||
|
ty: other_ty,
|
||||||
|
is_optional: false,
|
||||||
|
name: "other".into()
|
||||||
|
}]
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
fields.insert(
|
||||||
|
binop_assign_name(&ast::Operator::Div).into(),
|
||||||
|
unifier.add_ty(TypeEnum::TFunc(FunSignature{
|
||||||
|
ret: store.none,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
args: vec![FuncArg {
|
||||||
|
ty: other_ty,
|
||||||
|
is_optional: false,
|
||||||
|
name: "other".into()
|
||||||
|
}]
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
} else { unreachable!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// FloorDiv
|
||||||
|
pub fn impl_floordiv(unifier: &mut Unifier, store: &PrimitiveStore, ty: Type, other_ty: Type, ret_ty: Type) {
|
||||||
|
if let Some(TypeEnum::TObj {fields, ..}) = Rc::get_mut(&mut unifier.get_ty(ty)) {
|
||||||
|
fields.insert(
|
||||||
|
binop_name(&ast::Operator::FloorDiv).into(),
|
||||||
|
unifier.add_ty(TypeEnum::TFunc(FunSignature{
|
||||||
|
ret: ret_ty,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
args: vec![FuncArg {
|
||||||
|
ty: other_ty,
|
||||||
|
is_optional: false,
|
||||||
|
name: "other".into()
|
||||||
|
}]
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
fields.insert(
|
||||||
|
binop_assign_name(&ast::Operator::FloorDiv).into(),
|
||||||
|
unifier.add_ty(TypeEnum::TFunc(FunSignature{
|
||||||
|
ret: store.none,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
args: vec![FuncArg {
|
||||||
|
ty: other_ty,
|
||||||
|
is_optional: false,
|
||||||
|
name: "other".into()
|
||||||
|
}]
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
} else { unreachable!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mod
|
||||||
|
pub fn impl_mod(unifier: &mut Unifier, store: &PrimitiveStore, ty: Type, other_ty: Type, ret_ty: Type) {
|
||||||
|
if let Some(TypeEnum::TObj {fields, .. }) = Rc::get_mut(&mut unifier.get_ty(ty)) {
|
||||||
|
fields.insert(
|
||||||
|
binop_name(&ast::Operator::Mod).into(),
|
||||||
|
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||||
|
ret: ret_ty,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
args: vec![FuncArg {
|
||||||
|
ty: other_ty,
|
||||||
|
is_optional: false,
|
||||||
|
name: "other".into()
|
||||||
|
}]
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
fields.insert(
|
||||||
|
binop_assign_name(&ast::Operator::Mod).into(),
|
||||||
|
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||||
|
ret: store.none,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
args: vec![FuncArg {
|
||||||
|
ty: other_ty,
|
||||||
|
is_optional: false,
|
||||||
|
name: "other".into()
|
||||||
|
}]
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
} else { unreachable!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// UAdd, USub
|
||||||
|
pub fn impl_unary_op(unifier: &mut Unifier, _store: &PrimitiveStore, ty: Type) {
|
||||||
|
if let Some(TypeEnum::TObj {fields, ..}) = Rc::get_mut(&mut unifier.get_ty(ty)) {
|
||||||
for op in &[
|
for op in &[
|
||||||
ast::Cmpop::Eq,
|
ast::Unaryop::UAdd,
|
||||||
ast::Cmpop::NotEq,
|
ast::Unaryop::USub
|
||||||
|
] {
|
||||||
|
fields.insert(
|
||||||
|
unaryop_name(op).into(),
|
||||||
|
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||||
|
ret: ty,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
args: vec![]
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else { unreachable!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invert
|
||||||
|
pub fn impl_invert(unifier: &mut Unifier, _store: &PrimitiveStore, ty: Type) {
|
||||||
|
if let Some(TypeEnum::TObj {fields, .. }) = Rc::get_mut(&mut unifier.get_ty(ty)) {
|
||||||
|
fields.insert(
|
||||||
|
unaryop_name(&ast::Unaryop::Invert).into(),
|
||||||
|
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||||
|
ret: ty,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
args: vec![]
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Not
|
||||||
|
pub fn impl_not(unifier: &mut Unifier, store: &PrimitiveStore, ty: Type) {
|
||||||
|
if let Some(TypeEnum::TObj {fields, ..}) = Rc::get_mut(&mut unifier.get_ty(ty)) {
|
||||||
|
fields.insert(
|
||||||
|
unaryop_name(&ast::Unaryop::Not).into(),
|
||||||
|
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||||
|
ret: store.bool,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
args: vec![]
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
} else { unreachable!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lt, LtE, Gt, GtE
|
||||||
|
pub fn impl_comparison(unifier: &mut Unifier, store: &PrimitiveStore, ty: Type, other_ty: Type) {
|
||||||
|
if let Some(TypeEnum::TObj {fields, ..}) = Rc::get_mut(&mut unifier.get_ty(ty)) {
|
||||||
|
for op in &[
|
||||||
ast::Cmpop::Lt,
|
ast::Cmpop::Lt,
|
||||||
ast::Cmpop::LtE,
|
ast::Cmpop::LtE,
|
||||||
ast::Cmpop::Gt,
|
ast::Cmpop::Gt,
|
||||||
|
@ -407,16 +291,112 @@ pub fn set_primirives_magic_methods(store: &PrimitiveStore, unifier: &mut Unifie
|
||||||
fields.insert(
|
fields.insert(
|
||||||
comparison_name(op).unwrap().into(),
|
comparison_name(op).unwrap().into(),
|
||||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||||
ret: store.int32,
|
ret: store.bool,
|
||||||
vars: HashMap::new(),
|
vars: HashMap::new(),
|
||||||
args: vec![FuncArg {
|
args: vec![FuncArg {
|
||||||
ty: store.bool,
|
ty: other_ty,
|
||||||
is_optional: false,
|
is_optional: false,
|
||||||
name: "other".into()
|
name: "other".into()
|
||||||
}]
|
}]
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
} else { unreachable!() }
|
||||||
// bool --------
|
}
|
||||||
|
|
||||||
|
/// Eq, NotEq
|
||||||
|
pub fn impl_eq(unifier: &mut Unifier, store: &PrimitiveStore, ty: Type) {
|
||||||
|
if let Some(TypeEnum::TObj {fields, ..}) = Rc::get_mut(&mut unifier.get_ty(ty)) {
|
||||||
|
for op in &[
|
||||||
|
ast::Cmpop::Eq,
|
||||||
|
ast::Cmpop::NotEq,
|
||||||
|
] {
|
||||||
|
fields.insert(
|
||||||
|
comparison_name(op).unwrap().into(),
|
||||||
|
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||||
|
ret: store.bool,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
args: vec![FuncArg {
|
||||||
|
ty,
|
||||||
|
is_optional: false,
|
||||||
|
name: "other".into()
|
||||||
|
}]
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else { unreachable!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_primirives_magic_methods(store: &PrimitiveStore, unifier: &mut Unifier) {
|
||||||
|
let PrimitiveStore {
|
||||||
|
int32: int32_t,
|
||||||
|
int64: int64_t,
|
||||||
|
float: float_t,
|
||||||
|
bool: bool_t,
|
||||||
|
none: _none_t
|
||||||
|
} = *store;
|
||||||
|
// int32 --------
|
||||||
|
impl_basic_arithmetic(unifier, store, int32_t, int32_t, int32_t);
|
||||||
|
impl_basic_arithmetic(unifier, store, int32_t, int64_t, int64_t);
|
||||||
|
impl_basic_arithmetic(unifier, store, int32_t, float_t, float_t);
|
||||||
|
impl_bitwise_arithmetic(unifier, store, int32_t);
|
||||||
|
impl_div(unifier, store, int32_t, int32_t);
|
||||||
|
impl_div(unifier, store, int32_t, int64_t);
|
||||||
|
impl_div(unifier, store, int32_t, float_t);
|
||||||
|
impl_floordiv(unifier, store, int32_t, int32_t, int32_t);
|
||||||
|
impl_floordiv(unifier, store, int32_t, int64_t, int32_t);
|
||||||
|
impl_floordiv(unifier, store, int32_t, float_t, float_t);
|
||||||
|
impl_mod(unifier, store, int32_t, int32_t, int32_t);
|
||||||
|
impl_mod(unifier, store, int32_t, int64_t, int32_t);
|
||||||
|
impl_mod(unifier, store, int32_t, float_t, float_t);
|
||||||
|
impl_unary_op(unifier, store, int32_t);
|
||||||
|
impl_invert(unifier, store, int32_t);
|
||||||
|
impl_not(unifier, store, int32_t);
|
||||||
|
impl_comparison(unifier, store, int32_t, int32_t);
|
||||||
|
impl_comparison(unifier, store, int32_t, int64_t);
|
||||||
|
impl_comparison(unifier, store, int32_t, float_t);
|
||||||
|
impl_eq(unifier, store, int32_t);
|
||||||
|
// int64 --------
|
||||||
|
impl_basic_arithmetic(unifier, store, int64_t, int32_t, int64_t);
|
||||||
|
impl_basic_arithmetic(unifier, store, int64_t, int64_t, int64_t);
|
||||||
|
impl_basic_arithmetic(unifier, store, int64_t, float_t, float_t);
|
||||||
|
impl_bitwise_arithmetic(unifier, store, int64_t);
|
||||||
|
impl_div(unifier, store, int64_t, int32_t);
|
||||||
|
impl_div(unifier, store, int64_t, int64_t);
|
||||||
|
impl_div(unifier, store, int64_t, float_t);
|
||||||
|
impl_floordiv(unifier, store, int64_t, int32_t, int64_t);
|
||||||
|
impl_floordiv(unifier, store, int64_t, int64_t, int64_t);
|
||||||
|
impl_floordiv(unifier, store, int64_t, float_t, float_t);
|
||||||
|
impl_mod(unifier, store, int64_t, int32_t, int64_t);
|
||||||
|
impl_mod(unifier, store, int64_t, int64_t, int64_t);
|
||||||
|
impl_mod(unifier, store, int64_t, float_t, float_t);
|
||||||
|
impl_unary_op(unifier, store, int64_t);
|
||||||
|
impl_invert(unifier, store, int64_t);
|
||||||
|
impl_not(unifier, store, int64_t);
|
||||||
|
impl_comparison(unifier, store, int64_t, int32_t);
|
||||||
|
impl_comparison(unifier, store, int64_t, int64_t);
|
||||||
|
impl_comparison(unifier, store, int64_t, float_t);
|
||||||
|
impl_eq(unifier, store, int64_t);
|
||||||
|
// float --------
|
||||||
|
impl_basic_arithmetic(unifier, store, float_t, int32_t, float_t);
|
||||||
|
impl_basic_arithmetic(unifier, store, float_t, int64_t, float_t);
|
||||||
|
impl_basic_arithmetic(unifier, store, float_t, float_t, float_t);
|
||||||
|
impl_div(unifier, store, float_t, int32_t);
|
||||||
|
impl_div(unifier, store, float_t, int64_t);
|
||||||
|
impl_div(unifier, store, float_t, float_t);
|
||||||
|
impl_floordiv(unifier, store, float_t, int32_t, float_t);
|
||||||
|
impl_floordiv(unifier, store, float_t, int64_t, float_t);
|
||||||
|
impl_floordiv(unifier, store, float_t, float_t, float_t);
|
||||||
|
impl_mod(unifier, store, float_t, int32_t, float_t);
|
||||||
|
impl_mod(unifier, store, float_t, int64_t, float_t);
|
||||||
|
impl_mod(unifier, store, float_t, float_t, float_t);
|
||||||
|
impl_unary_op(unifier, store, float_t);
|
||||||
|
impl_not(unifier, store, float_t);
|
||||||
|
impl_comparison(unifier, store, float_t, int32_t);
|
||||||
|
impl_comparison(unifier, store, float_t, int64_t);
|
||||||
|
impl_comparison(unifier, store, float_t, float_t);
|
||||||
|
impl_eq(unifier, store, float_t);
|
||||||
|
// bool ---------
|
||||||
|
impl_not(unifier, store, bool_t);
|
||||||
|
impl_eq(unifier, store, bool_t);
|
||||||
}
|
}
|
|
@ -32,6 +32,7 @@ impl From<Location> for CodeLocation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct PrimitiveStore {
|
pub struct PrimitiveStore {
|
||||||
pub int32: Type,
|
pub int32: Type,
|
||||||
pub int64: Type,
|
pub int64: Type,
|
||||||
|
|
Loading…
Reference in New Issue