diff --git a/compiler/erg_compiler/context/eval.rs b/compiler/erg_compiler/context/eval.rs index c8a3b48d..e046033d 100644 --- a/compiler/erg_compiler/context/eval.rs +++ b/compiler/erg_compiler/context/eval.rs @@ -642,6 +642,15 @@ impl Context { line!(), ))), }, + And => match (lhs, rhs) { + (ValueObj::Bool(l), ValueObj::Bool(r)) => Ok(ValueObj::Bool(l && r)), + (ValueObj::Type(lhs), ValueObj::Type(rhs)) => Ok(self.eval_and_type(lhs, rhs)), + _ => Err(EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + ))), + }, _other => Err(EvalErrors::from(EvalError::unreachable( self.cfg.input.clone(), fn_name!(), @@ -661,6 +670,19 @@ impl Context { } } + fn eval_and_type(&self, lhs: TypeObj, rhs: TypeObj) -> ValueObj { + match (lhs, rhs) { + (TypeObj::Builtin(l), TypeObj::Builtin(r)) => { + ValueObj::builtin_t(self.intersection(&l, &r)) + } + (lhs, rhs) => ValueObj::gen_t(GenTypeObj::intersection( + self.intersection(lhs.typ(), rhs.typ()), + lhs, + rhs, + )), + } + } + pub(crate) fn eval_bin_tp( &self, op: OpKind, diff --git a/compiler/erg_compiler/lib/std/abc.er b/compiler/erg_compiler/lib/std/abc.er index 309d73c1..76108e62 100644 --- a/compiler/erg_compiler/lib/std/abc.er +++ b/compiler/erg_compiler/lib/std/abc.er @@ -3,11 +3,11 @@ .Sized = Trait { .__len__ = (self: Self) -> Nat } # TODO: varargs .Callable = Trait { .__call__ = (self: Self) -> Obj } +# .Iterator T = Trait { .__next__ = (self: Self) -> T } +.Iterator = Trait { .__next__ = (self: Self) -> Obj } # .Iterable T = Trait { .__iter__ = (self: Self) -> Iterator T } .Iterable = Trait { .__iter__ = (self: Self) -> .Iterator } .Collection = Subsume .Container and .Iterable -# .Iterator T = Trait { .__next__ = (self: Self) -> T } -.Iterator = Trait { .__next__ = (self: Self) -> Obj } .Reversible = Trait { .__reversed__ = (self: Self) -> .Iterator } .Genertor = Subsume .Iterator .Sequence = Subsume .Collection and .Sized and .Reversible diff --git a/compiler/erg_compiler/ty/value.rs b/compiler/erg_compiler/ty/value.rs index c0d75868..ceef3432 100644 --- a/compiler/erg_compiler/ty/value.rs +++ b/compiler/erg_compiler/ty/value.rs @@ -135,6 +135,23 @@ impl UnionTypeObj { } } +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct IntersectionTypeObj { + pub t: Type, + pub lhs: Box, + pub rhs: Box, +} + +impl IntersectionTypeObj { + pub fn new(t: Type, lhs: TypeObj, rhs: TypeObj) -> Self { + Self { + t, + lhs: Box::new(lhs), + rhs: Box::new(rhs), + } + } +} + #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct PatchObj { pub t: Type, @@ -160,6 +177,7 @@ pub enum GenTypeObj { Subtrait(SubsumedTypeObj), StructuralTrait(TraitTypeObj), Union(UnionTypeObj), + Intersection(IntersectionTypeObj), Patch(PatchObj), } @@ -204,6 +222,10 @@ impl GenTypeObj { GenTypeObj::Union(UnionTypeObj::new(t, lhs, rhs)) } + pub fn intersection(t: Type, lhs: TypeObj, rhs: TypeObj) -> Self { + GenTypeObj::Intersection(IntersectionTypeObj::new(t, lhs, rhs)) + } + pub fn require_or_sup(&self) -> Option<&TypeObj> { match self { Self::Class(class) => Some(class.require.as_ref()), @@ -261,6 +283,7 @@ impl GenTypeObj { Self::Subtrait(subtrait) => &subtrait.t, Self::StructuralTrait(trait_) => &trait_.t, Self::Union(union_) => &union_.t, + Self::Intersection(intersection) => &intersection.t, Self::Patch(patch) => &patch.t, } } @@ -273,6 +296,7 @@ impl GenTypeObj { Self::Subtrait(subtrait) => &mut subtrait.t, Self::StructuralTrait(trait_) => &mut trait_.t, Self::Union(union_) => &mut union_.t, + Self::Intersection(intersection) => &mut intersection.t, Self::Patch(patch) => &mut patch.t, } } @@ -285,6 +309,7 @@ impl GenTypeObj { Self::Subtrait(subtrait) => subtrait.t, Self::StructuralTrait(trait_) => trait_.t, Self::Union(union_) => union_.t, + Self::Intersection(intersection) => intersection.t, Self::Patch(patch) => patch.t, } }