mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Add Trait
, Subsume
This commit is contained in:
parent
12f22f8bed
commit
bc67677ad6
5 changed files with 116 additions and 16 deletions
|
@ -274,7 +274,10 @@ impl Context {
|
||||||
})?
|
})?
|
||||||
.clone();
|
.clone();
|
||||||
let args = self.eval_args(&call.args, __name__)?;
|
let args = self.eval_args(&call.args, __name__)?;
|
||||||
Ok(subr.call(args, __name__.cloned()))
|
subr.call(args, __name__.cloned()).map_err(|mut e| {
|
||||||
|
e.loc = call.loc();
|
||||||
|
EvalError::new(e, self.caused_by())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Accessor::Attr(_attr) => todo!(),
|
Accessor::Attr(_attr) => todo!(),
|
||||||
Accessor::TupleAttr(_attr) => todo!(),
|
Accessor::TupleAttr(_attr) => todo!(),
|
||||||
|
|
|
@ -2,8 +2,11 @@ use std::mem;
|
||||||
|
|
||||||
use erg_common::Str;
|
use erg_common::Str;
|
||||||
|
|
||||||
|
use erg_common::astr::AtomicStr;
|
||||||
|
use erg_common::color::{RED, RESET};
|
||||||
|
use erg_common::error::{ErrorCore, ErrorKind, Location};
|
||||||
use erg_type::constructors::{and, mono};
|
use erg_type::constructors::{and, mono};
|
||||||
use erg_type::value::{TypeKind, TypeObj, ValueObj};
|
use erg_type::value::{EvalValueResult, TypeKind, TypeObj, ValueObj};
|
||||||
use erg_type::Type;
|
use erg_type::Type;
|
||||||
use erg_type::ValueArgs;
|
use erg_type::ValueArgs;
|
||||||
|
|
||||||
|
@ -20,31 +23,61 @@ fn value_obj_to_t(value: ValueObj) -> TypeObj {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Requirement: Type, Impl := Type -> ClassType
|
/// Requirement: Type, Impl := Type -> ClassType
|
||||||
pub fn class_func(mut args: ValueArgs, __name__: Option<Str>) -> ValueObj {
|
pub fn class_func(mut args: ValueArgs, __name__: Option<Str>) -> EvalValueResult<ValueObj> {
|
||||||
let require = args.remove_left_or_key("Requirement").unwrap();
|
let require = args.remove_left_or_key("Requirement").ok_or_else(|| {
|
||||||
|
ErrorCore::new(
|
||||||
|
line!() as usize,
|
||||||
|
ErrorKind::KeyError,
|
||||||
|
Location::Unknown,
|
||||||
|
AtomicStr::from(format!("{RED}Requirement{RESET} is not passed")),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
let require = value_obj_to_t(require);
|
let require = value_obj_to_t(require);
|
||||||
let impls = args.remove_left_or_key("Impl");
|
let impls = args.remove_left_or_key("Impl");
|
||||||
let impls = impls.map(value_obj_to_t);
|
let impls = impls.map(value_obj_to_t);
|
||||||
let t = mono(__name__.unwrap_or(Str::ever("<Lambda>")));
|
let t = mono(__name__.unwrap_or(Str::ever("<Lambda>")));
|
||||||
ValueObj::gen_t(TypeKind::Class, t, require, impls, None)
|
Ok(ValueObj::gen_t(TypeKind::Class, t, require, impls, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Super: Type, Impl := Type, Additional := Type -> ClassType
|
/// Super: Type, Impl := Type, Additional := Type -> ClassType
|
||||||
pub fn inherit_func(mut args: ValueArgs, __name__: Option<Str>) -> ValueObj {
|
pub fn inherit_func(mut args: ValueArgs, __name__: Option<Str>) -> EvalValueResult<ValueObj> {
|
||||||
let sup = args.remove_left_or_key("Super").unwrap();
|
let sup = args.remove_left_or_key("Super").ok_or_else(|| {
|
||||||
|
ErrorCore::new(
|
||||||
|
line!() as usize,
|
||||||
|
ErrorKind::KeyError,
|
||||||
|
Location::Unknown,
|
||||||
|
AtomicStr::from(format!("{RED}Super{RESET} is not passed")),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
let sup = value_obj_to_t(sup);
|
let sup = value_obj_to_t(sup);
|
||||||
let impls = args.remove_left_or_key("Impl");
|
let impls = args.remove_left_or_key("Impl");
|
||||||
let impls = impls.map(value_obj_to_t);
|
let impls = impls.map(value_obj_to_t);
|
||||||
let additional = args.remove_left_or_key("Additional");
|
let additional = args.remove_left_or_key("Additional");
|
||||||
let additional = additional.map(value_obj_to_t);
|
let additional = additional.map(value_obj_to_t);
|
||||||
let t = mono(__name__.unwrap_or(Str::ever("<Lambda>")));
|
let t = mono(__name__.unwrap_or(Str::ever("<Lambda>")));
|
||||||
ValueObj::gen_t(TypeKind::Subclass, t, sup, impls, additional)
|
Ok(ValueObj::gen_t(
|
||||||
|
TypeKind::Subclass,
|
||||||
|
t,
|
||||||
|
sup,
|
||||||
|
impls,
|
||||||
|
additional,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Class: ClassType -> ClassType (with `InheritableType`)
|
/// Class: ClassType -> ClassType (with `InheritableType`)
|
||||||
/// This function is used by the compiler to mark a class as inheritable and does nothing in terms of actual operation.
|
/// This function is used by the compiler to mark a class as inheritable and does nothing in terms of actual operation.
|
||||||
pub fn inheritable_func(mut args: ValueArgs, __name__: Option<Str>) -> ValueObj {
|
pub fn inheritable_func(mut args: ValueArgs, __name__: Option<Str>) -> EvalValueResult<ValueObj> {
|
||||||
let class = args.remove_left_or_key("Class").unwrap();
|
let class = args.remove_left_or_key("Class").ok_or_else(|| {
|
||||||
|
ErrorCore::new(
|
||||||
|
line!() as usize,
|
||||||
|
ErrorKind::KeyError,
|
||||||
|
Location::Unknown,
|
||||||
|
AtomicStr::from(format!("{RED}Class{RESET} is not passed")),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
match class {
|
match class {
|
||||||
ValueObj::Type(TypeObj::Generated(mut gen)) => {
|
ValueObj::Type(TypeObj::Generated(mut gen)) => {
|
||||||
if let Some(typ) = &mut gen.impls {
|
if let Some(typ) = &mut gen.impls {
|
||||||
|
@ -59,8 +92,52 @@ pub fn inheritable_func(mut args: ValueArgs, __name__: Option<Str>) -> ValueObj
|
||||||
} else {
|
} else {
|
||||||
gen.impls = Some(Box::new(TypeObj::Builtin(mono("InheritableType"))));
|
gen.impls = Some(Box::new(TypeObj::Builtin(mono("InheritableType"))));
|
||||||
}
|
}
|
||||||
ValueObj::Type(TypeObj::Generated(gen))
|
Ok(ValueObj::Type(TypeObj::Generated(gen)))
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Requirement: Type, Impl := Type -> ClassType
|
||||||
|
pub fn trait_func(mut args: ValueArgs, __name__: Option<Str>) -> EvalValueResult<ValueObj> {
|
||||||
|
let require = args.remove_left_or_key("Requirement").ok_or_else(|| {
|
||||||
|
ErrorCore::new(
|
||||||
|
line!() as usize,
|
||||||
|
ErrorKind::KeyError,
|
||||||
|
Location::Unknown,
|
||||||
|
AtomicStr::from(format!("{RED}Requirement{RESET} is not passed")),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
let require = value_obj_to_t(require);
|
||||||
|
let impls = args.remove_left_or_key("Impl");
|
||||||
|
let impls = impls.map(value_obj_to_t);
|
||||||
|
let t = mono(__name__.unwrap_or(Str::ever("<Lambda>")));
|
||||||
|
Ok(ValueObj::gen_t(TypeKind::Trait, t, require, impls, None))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Super: Type, Impl := Type, Additional := Type -> ClassType
|
||||||
|
pub fn subsume_func(mut args: ValueArgs, __name__: Option<Str>) -> EvalValueResult<ValueObj> {
|
||||||
|
let sup = args.remove_left_or_key("Super").ok_or_else(|| {
|
||||||
|
ErrorCore::new(
|
||||||
|
line!() as usize,
|
||||||
|
ErrorKind::KeyError,
|
||||||
|
Location::Unknown,
|
||||||
|
AtomicStr::from(format!("{RED}Super{RESET} is not passed")),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
let sup = value_obj_to_t(sup);
|
||||||
|
let impls = args.remove_left_or_key("Impl");
|
||||||
|
let impls = impls.map(value_obj_to_t);
|
||||||
|
let additional = args.remove_left_or_key("Additional");
|
||||||
|
let additional = additional.map(value_obj_to_t);
|
||||||
|
let t = mono(__name__.unwrap_or(Str::ever("<Lambda>")));
|
||||||
|
Ok(ValueObj::gen_t(
|
||||||
|
TypeKind::Subtrait,
|
||||||
|
t,
|
||||||
|
sup,
|
||||||
|
impls,
|
||||||
|
additional,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ use Type::*;
|
||||||
|
|
||||||
use erg_parser::ast::VarName;
|
use erg_parser::ast::VarName;
|
||||||
|
|
||||||
use crate::context::initialize::const_func::{class_func, inherit_func, inheritable_func};
|
use crate::context::initialize::const_func::*;
|
||||||
use crate::context::instantiate::{ConstTemplate, TyVarContext};
|
use crate::context::instantiate::{ConstTemplate, TyVarContext};
|
||||||
use crate::context::{ClassDefType, Context, ContextKind, DefaultInfo, ParamSpec, TraitInstance};
|
use crate::context::{ClassDefType, Context, ContextKind, DefaultInfo, ParamSpec, TraitInstance};
|
||||||
use crate::varinfo::{Mutability, VarInfo, VarKind};
|
use crate::varinfo::{Mutability, VarInfo, VarKind};
|
||||||
|
@ -1496,6 +1496,22 @@ impl Context {
|
||||||
);
|
);
|
||||||
let inherit = ConstSubr::Builtin(BuiltinConstSubr::new("Inherit", inherit_func, inherit_t));
|
let inherit = ConstSubr::Builtin(BuiltinConstSubr::new("Inherit", inherit_func, inherit_t));
|
||||||
self.register_builtin_const("Inherit", ValueObj::Subr(inherit));
|
self.register_builtin_const("Inherit", ValueObj::Subr(inherit));
|
||||||
|
let trait_t = func(
|
||||||
|
vec![param_t("Requirement", Type)],
|
||||||
|
None,
|
||||||
|
vec![param_t("Impl", Type)],
|
||||||
|
Trait,
|
||||||
|
);
|
||||||
|
let trait_ = ConstSubr::Builtin(BuiltinConstSubr::new("Trait", trait_func, trait_t));
|
||||||
|
self.register_builtin_const("Trait", ValueObj::Subr(trait_));
|
||||||
|
let subsume_t = func(
|
||||||
|
vec![param_t("Super", Trait)],
|
||||||
|
None,
|
||||||
|
vec![param_t("Impl", Type), param_t("Additional", Type)],
|
||||||
|
Trait,
|
||||||
|
);
|
||||||
|
let subsume = ConstSubr::Builtin(BuiltinConstSubr::new("Subsume", subsume_func, subsume_t));
|
||||||
|
self.register_builtin_const("Subsume", ValueObj::Subr(subsume));
|
||||||
// decorators
|
// decorators
|
||||||
let inheritable_t = func1(Class, Class);
|
let inheritable_t = func1(Class, Class);
|
||||||
let inheritable = ConstSubr::Builtin(BuiltinConstSubr::new(
|
let inheritable = ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||||
|
|
|
@ -26,8 +26,8 @@ use crate::free::{
|
||||||
};
|
};
|
||||||
use crate::typaram::{IntervalOp, TyParam};
|
use crate::typaram::{IntervalOp, TyParam};
|
||||||
use crate::value::value_set::*;
|
use crate::value::value_set::*;
|
||||||
use crate::value::ValueObj;
|
|
||||||
use crate::value::ValueObj::{Inf, NegInf};
|
use crate::value::ValueObj::{Inf, NegInf};
|
||||||
|
use crate::value::{EvalValueResult, ValueObj};
|
||||||
|
|
||||||
/// cloneのコストがあるためなるべく.ref_tを使うようにすること
|
/// cloneのコストがあるためなるべく.ref_tを使うようにすること
|
||||||
/// いくつかの構造体は直接Typeを保持していないので、その場合は.tを使う
|
/// いくつかの構造体は直接Typeを保持していないので、その場合は.tを使う
|
||||||
|
@ -157,7 +157,7 @@ impl ValueArgs {
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct BuiltinConstSubr {
|
pub struct BuiltinConstSubr {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
subr: fn(ValueArgs, Option<Str>) -> ValueObj,
|
subr: fn(ValueArgs, Option<Str>) -> EvalValueResult<ValueObj>,
|
||||||
t: Type,
|
t: Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ impl fmt::Display for BuiltinConstSubr {
|
||||||
impl BuiltinConstSubr {
|
impl BuiltinConstSubr {
|
||||||
pub const fn new(
|
pub const fn new(
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
subr: fn(ValueArgs, Option<Str>) -> ValueObj,
|
subr: fn(ValueArgs, Option<Str>) -> EvalValueResult<ValueObj>,
|
||||||
t: Type,
|
t: Type,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { name, subr, t }
|
Self { name, subr, t }
|
||||||
|
@ -195,7 +195,7 @@ impl fmt::Display for ConstSubr {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstSubr {
|
impl ConstSubr {
|
||||||
pub fn call(&self, args: ValueArgs, __name__: Option<Str>) -> ValueObj {
|
pub fn call(&self, args: ValueArgs, __name__: Option<Str>) -> EvalValueResult<ValueObj> {
|
||||||
match self {
|
match self {
|
||||||
ConstSubr::User(_user) => todo!(),
|
ConstSubr::User(_user) => todo!(),
|
||||||
ConstSubr::Builtin(builtin) => (builtin.subr)(args, __name__),
|
ConstSubr::Builtin(builtin) => (builtin.subr)(args, __name__),
|
||||||
|
|
|
@ -9,6 +9,7 @@ use std::ops::Neg;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
|
use erg_common::error::ErrorCore;
|
||||||
use erg_common::rccell::RcCell;
|
use erg_common::rccell::RcCell;
|
||||||
use erg_common::serialize::*;
|
use erg_common::serialize::*;
|
||||||
use erg_common::set;
|
use erg_common::set;
|
||||||
|
@ -22,6 +23,9 @@ use crate::free::fresh_varname;
|
||||||
use crate::typaram::TyParam;
|
use crate::typaram::TyParam;
|
||||||
use crate::{ConstSubr, HasType, Predicate, Type};
|
use crate::{ConstSubr, HasType, Predicate, Type};
|
||||||
|
|
||||||
|
pub type EvalValueError = ErrorCore;
|
||||||
|
pub type EvalValueResult<T> = Result<T, EvalValueError>;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum TypeKind {
|
pub enum TypeKind {
|
||||||
Class,
|
Class,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue