erg/compiler/erg_compiler/context/initialize/const_func.rs

150 lines
4.9 KiB
Rust

use std::mem;
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, builtin_mono, mono};
use erg_type::value::{EvalValueResult, TypeKind, TypeObj, ValueObj};
use erg_type::ValueArgs;
/// Requirement: Type, Impl := Type -> ClassType
pub fn class_func(
mut args: ValueArgs,
mod_name: Str,
__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 = require.as_type().unwrap();
let impls = args.remove_left_or_key("Impl");
let impls = impls.map(|v| v.as_type().unwrap());
let t = mono(mod_name, __name__.unwrap_or(Str::ever("<Lambda>")));
Ok(ValueObj::gen_t(TypeKind::Class, t, require, impls, None))
}
/// Super: Type, Impl := Type, Additional := Type -> ClassType
pub fn inherit_func(
mut args: ValueArgs,
mod_name: Str,
__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 = sup.as_type().unwrap();
let impls = args.remove_left_or_key("Impl");
let impls = impls.map(|v| v.as_type().unwrap());
let additional = args.remove_left_or_key("Additional");
let additional = additional.map(|v| v.as_type().unwrap());
let t = mono(mod_name, __name__.unwrap_or(Str::ever("<Lambda>")));
Ok(ValueObj::gen_t(
TypeKind::Subclass,
t,
sup,
impls,
additional,
))
}
/// 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.
pub fn inheritable_func(
mut args: ValueArgs,
_mod_name: Str,
__name__: Option<Str>,
) -> EvalValueResult<ValueObj> {
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 {
ValueObj::Type(TypeObj::Generated(mut gen)) => {
if let Some(typ) = &mut gen.impls {
match typ.as_mut() {
TypeObj::Generated(gen) => {
gen.t = and(mem::take(&mut gen.t), builtin_mono("InheritableType"));
}
TypeObj::Builtin(t) => {
*t = and(mem::take(t), builtin_mono("InheritableType"));
}
}
} else {
gen.impls = Some(Box::new(TypeObj::Builtin(builtin_mono("InheritableType"))));
}
Ok(ValueObj::Type(TypeObj::Generated(gen)))
}
_ => todo!(),
}
}
/// Requirement: Type, Impl := Type -> ClassType
pub fn trait_func(
mut args: ValueArgs,
mod_name: Str,
__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 = require.as_type().unwrap();
let impls = args.remove_left_or_key("Impl");
let impls = impls.map(|v| v.as_type().unwrap());
let t = mono(mod_name, __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,
mod_name: Str,
__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 = sup.as_type().unwrap();
let impls = args.remove_left_or_key("Impl");
let impls = impls.map(|v| v.as_type().unwrap());
let additional = args.remove_left_or_key("Additional");
let additional = additional.map(|v| v.as_type().unwrap());
let t = mono(mod_name, __name__.unwrap_or(Str::ever("<Lambda>")));
Ok(ValueObj::gen_t(
TypeKind::Subtrait,
t,
sup,
impls,
additional,
))
}