Merge branch 'erg-lang:main' into main

This commit is contained in:
Cai Bingjun 2022-10-15 12:23:25 +08:00 committed by GitHub
commit 9eaa0918b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 467 additions and 342 deletions

View file

@ -43,5 +43,6 @@ jobs:
with:
bin: erg
target: ${{ matrix.target }}
features: no_build_rs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

8
Cargo.lock generated
View file

@ -4,7 +4,7 @@ version = 3
[[package]]
name = "erg"
version = "0.5.9-nightly.6"
version = "0.5.9"
dependencies = [
"erg_common",
"erg_compiler",
@ -13,7 +13,7 @@ dependencies = [
[[package]]
name = "erg_common"
version = "0.5.9-nightly.6"
version = "0.5.9"
dependencies = [
"hermit-abi",
"libc",
@ -22,7 +22,7 @@ dependencies = [
[[package]]
name = "erg_compiler"
version = "0.5.9-nightly.6"
version = "0.5.9"
dependencies = [
"erg_common",
"erg_parser",
@ -30,7 +30,7 @@ dependencies = [
[[package]]
name = "erg_parser"
version = "0.5.9-nightly.6"
version = "0.5.9"
dependencies = [
"erg_common",
]

View file

@ -1,6 +1,6 @@
[package]
name = "erg"
version = "0.5.9-nightly.6"
version = "0.5.9"
description = "The Erg programming language"
authors = ["erg-lang team <moderation.erglang@gmail.com>"]
license = "MIT OR Apache-2.0"
@ -18,7 +18,7 @@ members = [
]
[workspace.package]
version = "0.5.9-nightly.6"
version = "0.5.9"
authors = ["erg-lang team <moderation.erglang@gmail.com>"]
license = "MIT OR Apache-2.0"
edition = "2021"
@ -47,12 +47,13 @@ traditional_chinese = [
"erg_parser/traditional_chinese",
"erg_compiler/traditional_chinese",
]
no_build_rs = ["erg_compiler/no_build_rs"]
pre-commit = []
[dependencies]
erg_common = { version = "0.5.9-nightly.6", path = "./compiler/erg_common" }
erg_parser = { version = "0.5.9-nightly.6", path = "./compiler/erg_parser" }
erg_compiler = { version = "0.5.9-nightly.6", path = "./compiler/erg_compiler" }
erg_common = { version = "0.5.9", path = "./compiler/erg_common" }
erg_parser = { version = "0.5.9", path = "./compiler/erg_parser" }
erg_compiler = { version = "0.5.9", path = "./compiler/erg_compiler" }
# [workspace]
# member = ["cm", "dyne"]

View file

@ -22,10 +22,11 @@ traditional_chinese = [
"erg_common/traditional_chinese",
"erg_parser/traditional_chinese",
]
no_build_rs = []
[dependencies]
erg_common = { version = "0.5.9-nightly.6", path = "../erg_common" }
erg_parser = { version = "0.5.9-nightly.6", path = "../erg_parser" }
erg_common = { version = "0.5.9", path = "../erg_common" }
erg_parser = { version = "0.5.9", path = "../erg_parser" }
[lib]
path = "lib.rs"

View file

@ -5,6 +5,9 @@ use std::fs;
use std::path;
fn main() -> std::io::Result<()> {
if cfg!(feature = "no_build_rs") {
return Ok(());
}
// Create a ".erg" directory
let erg_path = env::home_dir()
.expect("failed to get the location of the home dir")

View file

@ -2051,27 +2051,36 @@ impl CodeGenerator {
}
fn load_prelude_py(&mut self) {
self.emit_global_import_items(
Identifier::public("sys"),
vec![(
Identifier::public("path"),
Some(Identifier::private("#path")),
)],
);
self.emit_load_name_instr(Identifier::private("#path"));
self.emit_load_method_instr("Array!", None, Identifier::public("push!"));
self.emit_load_const(env!("ERG_STD_PATH"));
self.write_instr(CALL_METHOD);
self.write_arg(1u8);
self.stack_dec();
self.emit_pop_top();
self.emit_global_import_items(
Identifier::public("_erg_std_prelude"),
vec![(
Identifier::public("in_operator"),
Some(Identifier::private("#in_operator")),
)],
);
if let Some(std_path) = option_env!("ERG_STD_PATH") {
self.emit_global_import_items(
Identifier::public("sys"),
vec![(
Identifier::public("path"),
Some(Identifier::private("#path")),
)],
);
self.emit_load_name_instr(Identifier::private("#path"));
self.emit_load_method_instr("Array!", None, Identifier::public("push!"));
self.emit_load_const(std_path);
self.write_instr(CALL_METHOD);
self.write_arg(1u8);
self.stack_dec();
self.emit_pop_top();
self.emit_global_import_items(
Identifier::public("_erg_std_prelude"),
vec![(
Identifier::public("in_operator"),
Some(Identifier::private("#in_operator")),
)],
);
} else {
self.emit_load_name_instr(Identifier::private("exec"));
self.emit_load_const(include_str!("std/_erg_std_prelude.py"));
self.write_instr(CALL_FUNCTION);
self.write_arg(1u8);
self.stack_dec();
self.emit_pop_top();
}
}
fn load_record_type(&mut self) {

View file

@ -921,15 +921,10 @@ impl Context {
}
// in Methods
if self.name == sub.qual_name() {
if let Ok(obj) = self.get_const_local(&Token::symbol(&rhs), &self.name) {
if let ValueObj::Type(quant_t) = obj {
let subst_ctx = SubstContext::new(&sub, self, t_loc);
let t = subst_ctx.substitute(quant_t.typ().clone())?;
let t = self.eval_t_params(t, level, t_loc)?;
return Ok(t);
} else {
todo!()
}
if let Some(t) =
self.validate_and_project(&sub, opt_sup.as_ref(), &rhs, self, level, t_loc)
{
return Ok(t);
}
}
for ty_ctx in self.get_nominal_super_type_ctxs(&sub).ok_or_else(|| {
@ -942,15 +937,10 @@ impl Context {
None, // TODO:
)
})? {
if let Ok(obj) = ty_ctx.get_const_local(&Token::symbol(&rhs), &self.name) {
if let ValueObj::Type(quant_t) = obj {
let subst_ctx = SubstContext::new(&sub, self, t_loc);
let t = subst_ctx.substitute(quant_t.typ().clone())?;
let t = self.eval_t_params(t, level, t_loc)?;
return Ok(t);
} else {
todo!()
}
if let Some(t) =
self.validate_and_project(&sub, opt_sup.as_ref(), &rhs, ty_ctx, level, t_loc)
{
return Ok(t);
}
for (class, methods) in ty_ctx.methods_list.iter() {
match (class, &opt_sup) {
@ -966,15 +956,10 @@ impl Context {
}
_ => {}
}
if let Ok(obj) = methods.get_const_local(&Token::symbol(&rhs), &self.name) {
if let ValueObj::Type(quant_t) = obj {
let subst_ctx = SubstContext::new(&sub, self, t_loc);
let t = subst_ctx.substitute(quant_t.typ().clone())?;
let t = self.eval_t_params(t, level, t_loc)?;
return Ok(t);
} else {
todo!()
}
if let Some(t) =
self.validate_and_project(&sub, opt_sup.as_ref(), &rhs, methods, level, t_loc)
{
return Ok(t);
}
}
}
@ -1014,6 +999,37 @@ impl Context {
}
}
fn validate_and_project(
&self,
sub: &Type,
opt_sup: Option<&Type>,
rhs: &str,
methods: &Context,
level: usize,
t_loc: Location,
) -> Option<Type> {
if let Ok(obj) = methods.get_const_local(&Token::symbol(rhs), &self.name) {
#[allow(clippy::single_match)]
match (&opt_sup, methods.impl_of()) {
(Some(sup), Some(trait_)) => {
if !self.supertype_of(&trait_, sup) {
return None;
}
}
_ => {}
}
if let ValueObj::Type(quant_t) = obj {
let subst_ctx = SubstContext::new(sub, self, t_loc);
let t = subst_ctx.substitute(quant_t.typ().clone()).ok()?;
let t = self.eval_t_params(t, level, t_loc).ok()?;
return Some(t);
} else {
todo!()
}
}
None
}
fn eval_proj_call(
&self,
lhs: TyParam,

View file

@ -37,12 +37,19 @@ use Visibility::*;
impl Context {
fn register_builtin_decl(&mut self, name: &'static str, t: Type, vis: Visibility) {
let impl_of = if let ContextKind::MethodDefs(Some(tr)) = &self.kind {
Some(tr.clone())
} else {
None
};
let name = VarName::from_static(name);
if self.decls.get(&name).is_some() {
panic!("already registered: {name}");
} else {
self.decls
.insert(name, VarInfo::new(t, Immutable, vis, Builtin, None));
self.decls.insert(
name,
VarInfo::new(t, Immutable, vis, Builtin, None, impl_of),
);
}
}
@ -53,21 +60,42 @@ impl Context {
muty: Mutability,
vis: Visibility,
) {
let impl_of = if let ContextKind::MethodDefs(Some(tr)) = &self.kind {
Some(tr.clone())
} else {
None
};
let name = VarName::from_static(name);
if self.locals.get(&name).is_some() {
panic!("already registered: {name}");
} else {
self.locals
.insert(name, VarInfo::new(t, muty, vis, Builtin, None));
.insert(name, VarInfo::new(t, muty, vis, Builtin, None, impl_of));
}
}
fn register_builtin_immutable_private_var(&mut self, name: &'static str, t: Type) {
self.register_builtin_impl(name, t, Immutable, Private)
}
fn register_builtin_const(&mut self, name: &str, vis: Visibility, obj: ValueObj) {
if self.rec_get_const_obj(name).is_some() {
panic!("already registered: {name}");
} else {
let impl_of = if let ContextKind::MethodDefs(Some(tr)) = &self.kind {
Some(tr.clone())
} else {
None
};
// TODO: not all value objects are comparable
let vi = VarInfo::new(v_enum(set! {obj.clone()}), Const, vis, Builtin, None);
let vi = VarInfo::new(
v_enum(set! {obj.clone()}),
Const,
vis,
Builtin,
None,
impl_of,
);
self.consts.insert(VarName::from_str(Str::rc(name)), obj);
self.locals.insert(VarName::from_str(Str::rc(name)), vi);
}
@ -116,8 +144,10 @@ impl Context {
ContextKind::Trait => Type::TraitType,
_ => Type::Type,
};
self.locals
.insert(name.clone(), VarInfo::new(meta_t, muty, vis, Builtin, None));
self.locals.insert(
name.clone(),
VarInfo::new(meta_t, muty, vis, Builtin, None, None),
);
self.consts
.insert(name.clone(), ValueObj::builtin_t(t.clone()));
for impl_trait in ctx.super_traits.iter() {
@ -166,8 +196,10 @@ impl Context {
ContextKind::Trait => Type::TraitType,
_ => Type::Type,
};
self.locals
.insert(name.clone(), VarInfo::new(meta_t, muty, vis, Builtin, None));
self.locals.insert(
name.clone(),
VarInfo::new(meta_t, muty, vis, Builtin, None, None),
);
self.consts
.insert(name.clone(), ValueObj::builtin_t(t.clone()));
for impl_trait in ctx.super_traits.iter() {
@ -215,8 +247,10 @@ impl Context {
panic!("{} has already been registered", name);
} else {
let name = VarName::from_static(name);
self.locals
.insert(name.clone(), VarInfo::new(Patch, muty, vis, Builtin, None));
self.locals.insert(
name.clone(),
VarInfo::new(Patch, muty, vis, Builtin, None, None),
);
for method_name in ctx.locals.keys() {
if let Some(patches) = self.method_impl_patches.get_mut(method_name) {
patches.push(name.clone());
@ -231,25 +265,10 @@ impl Context {
fn init_builtin_consts(&mut self) {
// TODO: this is not a const, but a special property
self.register_builtin_impl("__name__", Str, Immutable, Private);
self.register_builtin_impl(
"license",
mono("_sitebuiltins._Printer"),
Immutable,
Private,
);
self.register_builtin_impl(
"credits",
mono("_sitebuiltins._Printer"),
Immutable,
Private,
);
self.register_builtin_impl(
"copyright",
mono("_sitebuiltins._Printer"),
Immutable,
Private,
);
self.register_builtin_immutable_private_var("__name__", Str);
self.register_builtin_immutable_private_var("license", mono("_sitebuiltins._Printer"));
self.register_builtin_immutable_private_var("credits", mono("_sitebuiltins._Printer"));
self.register_builtin_immutable_private_var("copyright", mono("_sitebuiltins._Printer"));
}
/// see std/prelude.er
@ -519,12 +538,12 @@ impl Context {
Public,
);
obj.register_builtin_impl("__bytes__", fn0_met(Obj, mono("Bytes")), Immutable, Public);
let mut obj_in = Self::builtin_methods("In", 2);
let mut obj_in = Self::builtin_methods(Some(poly("In", vec![ty_tp(Type)])), 2);
obj_in.register_builtin_impl("__in__", fn1_met(Obj, Type, Bool), Const, Public);
obj.register_trait(Obj, poly("In", vec![ty_tp(Type)]), obj_in);
let mut obj_mutizable = Self::builtin_methods("Mutizable", 1);
obj.register_trait(Obj, obj_in);
let mut obj_mutizable = Self::builtin_methods(Some(mono("Mutizable")), 1);
obj_mutizable.register_builtin_const("MutType!", Public, ValueObj::builtin_t(mono("Obj!")));
obj.register_trait(Obj, mono("Mutizable"), obj_mutizable);
obj.register_trait(Obj, obj_mutizable);
// Obj does not implement Eq
/* Float */
@ -536,53 +555,51 @@ impl Context {
float.register_builtin_impl("Imag", Float, Const, Public);
float.register_marker_trait(mono("Num"));
float.register_marker_trait(mono("Ord"));
let mut float_partial_ord = Self::builtin_methods("PartialOrd", 2);
let mut float_partial_ord =
Self::builtin_methods(Some(poly("PartialOrd", vec![ty_tp(Float)])), 2);
float_partial_ord.register_builtin_impl(
"__cmp__",
fn1_met(Float, Float, mono("Ordering")),
Const,
Public,
);
float.register_trait(
Float,
poly("PartialOrd", vec![ty_tp(Float)]),
float_partial_ord,
);
float.register_trait(Float, float_partial_ord);
// Float doesn't have an `Eq` implementation
let op_t = fn1_met(Float, Float, Float);
let mut float_add = Self::builtin_methods("Add", 2);
let mut float_add = Self::builtin_methods(Some(poly("Add", vec![ty_tp(Float)])), 2);
float_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
float_add.register_builtin_const("Output", Public, ValueObj::builtin_t(Float));
float.register_trait(Float, poly("Add", vec![ty_tp(Float)]), float_add);
let mut float_sub = Self::builtin_methods("Sub", 2);
float.register_trait(Float, float_add);
let mut float_sub = Self::builtin_methods(Some(poly("Sub", vec![ty_tp(Float)])), 2);
float_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
float_sub.register_builtin_const("Output", Public, ValueObj::builtin_t(Float));
float.register_trait(Float, poly("Sub", vec![ty_tp(Float)]), float_sub);
let mut float_mul = Self::builtin_methods("Mul", 2);
float.register_trait(Float, float_sub);
let mut float_mul = Self::builtin_methods(Some(poly("Mul", vec![ty_tp(Float)])), 2);
float_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public);
float_mul.register_builtin_const("Output", Public, ValueObj::builtin_t(Float));
float_mul.register_builtin_const("PowOutput", Public, ValueObj::builtin_t(Float));
float.register_trait(Float, poly("Mul", vec![ty_tp(Float)]), float_mul);
let mut float_div = Self::builtin_methods("Div", 2);
float.register_trait(Float, float_mul);
let mut float_div = Self::builtin_methods(Some(poly("Div", vec![ty_tp(Float)])), 2);
float_div.register_builtin_impl("__div__", op_t.clone(), Const, Public);
float_div.register_builtin_const("Output", Public, ValueObj::builtin_t(Float));
float_div.register_builtin_const("ModOutput", Public, ValueObj::builtin_t(Float));
float.register_trait(Float, poly("Div", vec![ty_tp(Float)]), float_div);
let mut float_floordiv = Self::builtin_methods("FloorDiv", 2);
float.register_trait(Float, float_div);
let mut float_floordiv =
Self::builtin_methods(Some(poly("FloorDiv", vec![ty_tp(Float)])), 2);
float_floordiv.register_builtin_impl("__floordiv__", op_t, Const, Public);
float_floordiv.register_builtin_const("Output", Public, ValueObj::builtin_t(Float));
float.register_trait(Float, poly("FloorDiv", vec![ty_tp(Float)]), float_floordiv);
let mut float_mutizable = Self::builtin_methods("Mutizable", 2);
float.register_trait(Float, float_floordiv);
let mut float_mutizable = Self::builtin_methods(Some(mono("Mutizable")), 2);
float_mutizable.register_builtin_const(
"MutType!",
Public,
ValueObj::builtin_t(mono("Float!")),
);
float.register_trait(Float, mono("Mutizable"), float_mutizable);
let mut float_show = Self::builtin_methods("Show", 1);
float.register_trait(Float, float_mutizable);
let mut float_show = Self::builtin_methods(Some(mono("Show")), 1);
let t = fn0_met(Float, Str);
float_show.register_builtin_impl("to_str", t, Immutable, Public);
float.register_trait(Float, mono("Show"), float_show);
float.register_trait(Float, float_show);
/* Ratio */
// TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat)
@ -592,55 +609,53 @@ impl Context {
ratio.register_builtin_impl("Imag", Ratio, Const, Public);
ratio.register_marker_trait(mono("Num"));
ratio.register_marker_trait(mono("Ord"));
let mut ratio_partial_ord = Self::builtin_methods("PartialOrd", 2);
let mut ratio_partial_ord =
Self::builtin_methods(Some(poly("PartialOrd", vec![ty_tp(Ratio)])), 2);
ratio_partial_ord.register_builtin_impl(
"__cmp__",
fn1_met(Ratio, Ratio, mono("Ordering")),
Const,
Public,
);
ratio.register_trait(
Ratio,
poly("PartialOrd", vec![ty_tp(Ratio)]),
ratio_partial_ord,
);
let mut ratio_eq = Self::builtin_methods("Eq", 2);
ratio.register_trait(Ratio, ratio_partial_ord);
let mut ratio_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Ratio)])), 2);
ratio_eq.register_builtin_impl("__eq__", fn1_met(Ratio, Ratio, Bool), Const, Public);
ratio.register_trait(Ratio, poly("Eq", vec![ty_tp(Ratio)]), ratio_eq);
ratio.register_trait(Ratio, ratio_eq);
let op_t = fn1_met(Ratio, Ratio, Ratio);
let mut ratio_add = Self::builtin_methods("Add", 2);
let mut ratio_add = Self::builtin_methods(Some(poly("Add", vec![ty_tp(Ratio)])), 2);
ratio_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
ratio_add.register_builtin_const("Output", Public, ValueObj::builtin_t(Ratio));
ratio.register_trait(Ratio, poly("Add", vec![ty_tp(Ratio)]), ratio_add);
let mut ratio_sub = Self::builtin_methods("Sub", 2);
ratio.register_trait(Ratio, ratio_add);
let mut ratio_sub = Self::builtin_methods(Some(poly("Sub", vec![ty_tp(Ratio)])), 2);
ratio_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
ratio_sub.register_builtin_const("Output", Public, ValueObj::builtin_t(Ratio));
ratio.register_trait(Ratio, poly("Sub", vec![ty_tp(Ratio)]), ratio_sub);
let mut ratio_mul = Self::builtin_methods("Mul", 2);
ratio.register_trait(Ratio, ratio_sub);
let mut ratio_mul = Self::builtin_methods(Some(poly("Mul", vec![ty_tp(Ratio)])), 2);
ratio_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public);
ratio_mul.register_builtin_const("Output", Public, ValueObj::builtin_t(Ratio));
ratio_mul.register_builtin_const("PowOutput", Public, ValueObj::builtin_t(Ratio));
ratio.register_trait(Ratio, poly("Mul", vec![ty_tp(Ratio)]), ratio_mul);
let mut ratio_div = Self::builtin_methods("Div", 2);
ratio.register_trait(Ratio, ratio_mul);
let mut ratio_div = Self::builtin_methods(Some(poly("Div", vec![ty_tp(Ratio)])), 2);
ratio_div.register_builtin_impl("__div__", op_t.clone(), Const, Public);
ratio_div.register_builtin_const("Output", Public, ValueObj::builtin_t(Ratio));
ratio_div.register_builtin_const("ModOutput", Public, ValueObj::builtin_t(Ratio));
ratio.register_trait(Ratio, poly("Div", vec![ty_tp(Ratio)]), ratio_div);
let mut ratio_floordiv = Self::builtin_methods("FloorDiv", 2);
ratio.register_trait(Ratio, ratio_div);
let mut ratio_floordiv =
Self::builtin_methods(Some(poly("FloorDiv", vec![ty_tp(Ratio)])), 2);
ratio_floordiv.register_builtin_impl("__floordiv__", op_t, Const, Public);
ratio_floordiv.register_builtin_const("Output", Public, ValueObj::builtin_t(Ratio));
ratio.register_trait(Ratio, poly("FloorDiv", vec![ty_tp(Ratio)]), ratio_floordiv);
let mut ratio_mutizable = Self::builtin_methods("Mutizable", 2);
ratio.register_trait(Ratio, ratio_floordiv);
let mut ratio_mutizable = Self::builtin_methods(Some(mono("Mutizable")), 2);
ratio_mutizable.register_builtin_const(
"MutType!",
Public,
ValueObj::builtin_t(mono("Ratio!")),
);
ratio.register_trait(Ratio, mono("Mutizable"), ratio_mutizable);
let mut ratio_show = Self::builtin_methods("Show", 1);
ratio.register_trait(Ratio, ratio_mutizable);
let mut ratio_show = Self::builtin_methods(Some(mono("Show")), 1);
let t = fn0_met(Ratio, Str);
ratio_show.register_builtin_impl("to_str", t, Immutable, Public);
ratio.register_trait(Ratio, mono("Show"), ratio_show);
ratio.register_trait(Ratio, ratio_show);
/* Int */
let mut int = Self::builtin_mono_class("Int", 2);
@ -651,43 +666,44 @@ impl Context {
// class("Rational"),
// class("Integral"),
int.register_builtin_impl("abs", fn0_met(Int, Nat), Immutable, Public);
let mut int_partial_ord = Self::builtin_methods("PartialOrd", 2);
let mut int_partial_ord =
Self::builtin_methods(Some(poly("PartialOrd", vec![ty_tp(Int)])), 2);
int_partial_ord.register_builtin_impl(
"__partial_cmp__",
fn1_met(Int, Int, or(mono("Ordering"), NoneType)),
Const,
Public,
);
int.register_trait(Int, poly("PartialOrd", vec![ty_tp(Int)]), int_partial_ord);
let mut int_eq = Self::builtin_methods("Eq", 2);
int.register_trait(Int, int_partial_ord);
let mut int_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Int)])), 2);
int_eq.register_builtin_impl("__eq__", fn1_met(Int, Int, Bool), Const, Public);
int.register_trait(Int, poly("Eq", vec![ty_tp(Int)]), int_eq);
int.register_trait(Int, int_eq);
// __div__ is not included in Int (cast to Ratio)
let op_t = fn1_met(Int, Int, Int);
let mut int_add = Self::builtin_methods("Add", 2);
let mut int_add = Self::builtin_methods(Some(poly("Add", vec![ty_tp(Int)])), 2);
int_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
int_add.register_builtin_const("Output", Public, ValueObj::builtin_t(Int));
int.register_trait(Int, poly("Add", vec![ty_tp(Int)]), int_add);
let mut int_sub = Self::builtin_methods("Sub", 2);
int.register_trait(Int, int_add);
let mut int_sub = Self::builtin_methods(Some(poly("Sub", vec![ty_tp(Int)])), 2);
int_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public);
int_sub.register_builtin_const("Output", Public, ValueObj::builtin_t(Int));
int.register_trait(Int, poly("Sub", vec![ty_tp(Int)]), int_sub);
let mut int_mul = Self::builtin_methods("Mul", 2);
int.register_trait(Int, int_sub);
let mut int_mul = Self::builtin_methods(Some(poly("Mul", vec![ty_tp(Int)])), 2);
int_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public);
int_mul.register_builtin_const("Output", Public, ValueObj::builtin_t(Int));
int_mul.register_builtin_const("PowOutput", Public, ValueObj::builtin_t(Nat));
int.register_trait(Int, poly("Mul", vec![ty_tp(Int)]), int_mul);
let mut int_floordiv = Self::builtin_methods("FloorDiv", 2);
int.register_trait(Int, int_mul);
let mut int_floordiv = Self::builtin_methods(Some(poly("FloorDiv", vec![ty_tp(Int)])), 2);
int_floordiv.register_builtin_impl("__floordiv__", op_t, Const, Public);
int_floordiv.register_builtin_const("Output", Public, ValueObj::builtin_t(Int));
int.register_trait(Int, poly("FloorDiv", vec![ty_tp(Int)]), int_floordiv);
let mut int_mutizable = Self::builtin_methods("Mutizable", 2);
int.register_trait(Int, int_floordiv);
let mut int_mutizable = Self::builtin_methods(Some(mono("Mutizable")), 2);
int_mutizable.register_builtin_const("MutType!", Public, ValueObj::builtin_t(mono("Int!")));
int.register_trait(Int, mono("Mutizable"), int_mutizable);
let mut int_show = Self::builtin_methods("Show", 1);
int.register_trait(Int, int_mutizable);
let mut int_show = Self::builtin_methods(Some(mono("Show")), 1);
let t = fn0_met(Int, Str);
int_show.register_builtin_impl("to_str", t, Immutable, Public);
int.register_trait(Int, mono("Show"), int_show);
int.register_trait(Int, int_show);
int.register_builtin_impl("Real", Int, Const, Public);
int.register_builtin_impl("Imag", Int, Const, Public);
@ -710,34 +726,35 @@ impl Context {
);
nat.register_marker_trait(mono("Num"));
nat.register_marker_trait(mono("Ord"));
let mut nat_eq = Self::builtin_methods("Eq", 2);
let mut nat_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Nat)])), 2);
nat_eq.register_builtin_impl("__eq__", fn1_met(Nat, Nat, Bool), Const, Public);
nat.register_trait(Nat, poly("Eq", vec![ty_tp(Nat)]), nat_eq);
let mut nat_partial_ord = Self::builtin_methods("PartialOrd", 2);
nat.register_trait(Nat, nat_eq);
let mut nat_partial_ord =
Self::builtin_methods(Some(poly("PartialOrd", vec![ty_tp(Nat)])), 2);
nat_partial_ord.register_builtin_impl(
"__cmp__",
fn1_met(Nat, Nat, mono("Ordering")),
Const,
Public,
);
nat.register_trait(Nat, poly("PartialOrd", vec![ty_tp(Nat)]), nat_partial_ord);
nat.register_trait(Nat, nat_partial_ord);
// __sub__, __div__ is not included in Nat (cast to Int/ Ratio)
let op_t = fn1_met(Nat, Nat, Nat);
let mut nat_add = Self::builtin_methods("Add", 2);
let mut nat_add = Self::builtin_methods(Some(poly("Add", vec![ty_tp(Nat)])), 2);
nat_add.register_builtin_impl("__add__", op_t.clone(), Const, Public);
nat_add.register_builtin_const("Output", Public, ValueObj::builtin_t(Nat));
nat.register_trait(Nat, poly("Add", vec![ty_tp(Nat)]), nat_add);
let mut nat_mul = Self::builtin_methods("Mul", 2);
nat.register_trait(Nat, nat_add);
let mut nat_mul = Self::builtin_methods(Some(poly("Mul", vec![ty_tp(Nat)])), 2);
nat_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public);
nat_mul.register_builtin_const("Output", Public, ValueObj::builtin_t(Nat));
nat.register_trait(Nat, poly("Mul", vec![ty_tp(Nat)]), nat_mul);
let mut nat_floordiv = Self::builtin_methods("FloorDiv", 2);
nat.register_trait(Nat, nat_mul);
let mut nat_floordiv = Self::builtin_methods(Some(poly("FloorDiv", vec![ty_tp(Nat)])), 2);
nat_floordiv.register_builtin_impl("__floordiv__", op_t, Const, Public);
nat_floordiv.register_builtin_const("Output", Public, ValueObj::builtin_t(Nat));
nat.register_trait(Nat, poly("FloorDiv", vec![ty_tp(Nat)]), nat_floordiv);
let mut nat_mutizable = Self::builtin_methods("Mutizable", 2);
nat.register_trait(Nat, nat_floordiv);
let mut nat_mutizable = Self::builtin_methods(Some(mono("Mutizable")), 2);
nat_mutizable.register_builtin_const("MutType!", Public, ValueObj::builtin_t(mono("Nat!")));
nat.register_trait(Nat, mono("Mutizable"), nat_mutizable);
nat.register_trait(Nat, nat_mutizable);
nat.register_builtin_impl("Real", Nat, Const, Public);
nat.register_builtin_impl("Imag", Nat, Const, Public);
@ -751,31 +768,28 @@ impl Context {
bool_.register_builtin_impl("__or__", fn1_met(Bool, Bool, Bool), Const, Public);
bool_.register_marker_trait(mono("Num"));
bool_.register_marker_trait(mono("Ord"));
let mut bool_partial_ord = Self::builtin_methods("PartialOrd", 2);
let mut bool_partial_ord =
Self::builtin_methods(Some(poly("PartialOrd", vec![ty_tp(Bool)])), 2);
bool_partial_ord.register_builtin_impl(
"__cmp__",
fn1_met(Bool, Bool, mono("Ordering")),
Const,
Public,
);
bool_.register_trait(
Bool,
poly("PartialOrd", vec![ty_tp(Bool)]),
bool_partial_ord,
);
let mut bool_eq = Self::builtin_methods("Eq", 2);
bool_.register_trait(Bool, bool_partial_ord);
let mut bool_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Bool)])), 2);
bool_eq.register_builtin_impl("__eq__", fn1_met(Bool, Bool, Bool), Const, Public);
bool_.register_trait(Bool, poly("Eq", vec![ty_tp(Bool)]), bool_eq);
let mut bool_mutizable = Self::builtin_methods("Mutizable", 2);
bool_.register_trait(Bool, bool_eq);
let mut bool_mutizable = Self::builtin_methods(Some(mono("Mutizable")), 2);
bool_mutizable.register_builtin_const(
"MutType!",
Public,
ValueObj::builtin_t(mono("Bool!")),
);
bool_.register_trait(Bool, mono("Mutizable"), bool_mutizable);
let mut bool_show = Self::builtin_methods("Show", 1);
bool_.register_trait(Bool, bool_mutizable);
let mut bool_show = Self::builtin_methods(Some(mono("Show")), 1);
bool_show.register_builtin_impl("to_str", fn0_met(Bool, Str), Immutable, Public);
bool_.register_trait(Bool, mono("Show"), bool_show);
bool_.register_trait(Bool, bool_show);
/* Str */
let mut str_ = Self::builtin_mono_class("Str", 10);
str_.register_superclass(Obj, &obj);
@ -805,49 +819,49 @@ impl Context {
Immutable,
Public,
);
let mut str_eq = Self::builtin_methods("Eq", 2);
let mut str_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Str)])), 2);
str_eq.register_builtin_impl("__eq__", fn1_met(Str, Str, Bool), Const, Public);
str_.register_trait(Str, poly("Eq", vec![ty_tp(Str)]), str_eq);
let mut str_seq = Self::builtin_methods("Seq", 2);
str_.register_trait(Str, str_eq);
let mut str_seq = Self::builtin_methods(Some(poly("Seq", vec![ty_tp(Str)])), 2);
str_seq.register_builtin_impl("len", fn0_met(Str, Nat), Const, Public);
str_seq.register_builtin_impl("get", fn1_met(Str, Nat, Str), Const, Public);
str_.register_trait(Str, poly("Seq", vec![ty_tp(Str)]), str_seq);
let mut str_add = Self::builtin_methods("Add", 2);
str_.register_trait(Str, str_seq);
let mut str_add = Self::builtin_methods(Some(poly("Add", vec![ty_tp(Str)])), 2);
str_add.register_builtin_impl("__add__", fn1_met(Str, Str, Str), Const, Public);
str_add.register_builtin_const("Output", Public, ValueObj::builtin_t(Str));
str_.register_trait(Str, poly("Add", vec![ty_tp(Str)]), str_add);
let mut str_mul = Self::builtin_methods("Mul", 2);
str_.register_trait(Str, str_add);
let mut str_mul = Self::builtin_methods(Some(poly("Mul", vec![ty_tp(Nat)])), 2);
str_mul.register_builtin_impl("__mul__", fn1_met(Str, Nat, Str), Const, Public);
str_mul.register_builtin_const("Output", Public, ValueObj::builtin_t(Str));
str_.register_trait(Str, poly("Mul", vec![ty_tp(Nat)]), str_mul);
let mut str_mutizable = Self::builtin_methods("Mutizable", 2);
str_.register_trait(Str, str_mul);
let mut str_mutizable = Self::builtin_methods(Some(mono("Mutizable")), 2);
str_mutizable.register_builtin_const("MutType!", Public, ValueObj::builtin_t(mono("Str!")));
str_.register_trait(Str, mono("Mutizable"), str_mutizable);
let mut str_show = Self::builtin_methods("Show", 1);
str_.register_trait(Str, str_mutizable);
let mut str_show = Self::builtin_methods(Some(mono("Show")), 1);
str_show.register_builtin_impl("to_str", fn0_met(Str, Str), Immutable, Public);
str_.register_trait(Str, mono("Show"), str_show);
let mut str_iterable = Self::builtin_methods("Iterable", 2);
str_.register_trait(Str, str_show);
let mut str_iterable = Self::builtin_methods(Some(poly("Iterable", vec![ty_tp(Str)])), 2);
str_iterable.register_builtin_impl(
"iter",
fn0_met(Str, mono("StrIterator")),
Immutable,
Public,
);
str_.register_trait(Str, poly("Iterable", vec![ty_tp(Str)]), str_iterable);
str_.register_trait(Str, str_iterable);
/* NoneType */
let mut nonetype = Self::builtin_mono_class("NoneType", 10);
nonetype.register_superclass(Obj, &obj);
let mut nonetype_eq = Self::builtin_methods("Eq", 2);
let mut nonetype_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(NoneType)])), 2);
nonetype_eq.register_builtin_impl(
"__eq__",
fn1_met(NoneType, NoneType, Bool),
Const,
Public,
);
nonetype.register_trait(NoneType, poly("Eq", vec![ty_tp(NoneType)]), nonetype_eq);
let mut nonetype_show = Self::builtin_methods("Show", 1);
nonetype.register_trait(NoneType, nonetype_eq);
let mut nonetype_show = Self::builtin_methods(Some(mono("Show")), 1);
nonetype_show.register_builtin_impl("to_str", fn0_met(NoneType, Str), Immutable, Public);
nonetype.register_trait(NoneType, mono("Show"), nonetype_show);
nonetype.register_trait(NoneType, nonetype_show);
/* Type */
let mut type_ = Self::builtin_mono_class("Type", 2);
type_.register_superclass(Obj, &obj);
@ -858,47 +872,44 @@ impl Context {
Public,
);
type_.register_marker_trait(mono("Named"));
let mut type_eq = Self::builtin_methods("Eq", 2);
let mut type_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(Type)])), 2);
type_eq.register_builtin_impl("__eq__", fn1_met(Type, Type, Bool), Const, Public);
type_.register_trait(Type, poly("Eq", vec![ty_tp(Type)]), type_eq);
type_.register_trait(Type, type_eq);
let mut class_type = Self::builtin_mono_class("ClassType", 2);
class_type.register_superclass(Type, &type_);
class_type.register_marker_trait(mono("Named"));
let mut class_eq = Self::builtin_methods("Eq", 2);
let mut class_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(ClassType)])), 2);
class_eq.register_builtin_impl(
"__eq__",
fn1_met(ClassType, ClassType, Bool),
Const,
Public,
);
class_type.register_trait(ClassType, poly("Eq", vec![ty_tp(ClassType)]), class_eq);
class_type.register_trait(ClassType, class_eq);
let mut trait_type = Self::builtin_mono_class("TraitType", 2);
trait_type.register_superclass(Type, &type_);
trait_type.register_marker_trait(mono("Named"));
let mut trait_eq = Self::builtin_methods("Eq", 2);
let mut trait_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(TraitType)])), 2);
trait_eq.register_builtin_impl(
"__eq__",
fn1_met(TraitType, TraitType, Bool),
Const,
Public,
);
trait_type.register_trait(TraitType, poly("Eq", vec![ty_tp(TraitType)]), trait_eq);
trait_type.register_trait(TraitType, trait_eq);
let g_module_t = mono("GenericModule");
let mut generic_module = Self::builtin_mono_class("GenericModule", 2);
generic_module.register_superclass(Obj, &obj);
generic_module.register_marker_trait(mono("Named"));
let mut generic_module_eq = Self::builtin_methods("Eq", 2);
let mut generic_module_eq =
Self::builtin_methods(Some(poly("Eq", vec![ty_tp(g_module_t.clone())])), 2);
generic_module_eq.register_builtin_impl(
"__eq__",
fn1_met(g_module_t.clone(), g_module_t.clone(), Bool),
Const,
Public,
);
generic_module.register_trait(
g_module_t.clone(),
poly("Eq", vec![ty_tp(g_module_t.clone())]),
generic_module_eq,
);
generic_module.register_trait(g_module_t.clone(), generic_module_eq);
let module_t = module(mono_q_tp("Path"));
let mut module = Self::builtin_poly_class("Module", vec![PS::named_nd("Path", Str)], 2);
module.register_superclass(g_module_t.clone(), &generic_module);
@ -961,35 +972,28 @@ impl Context {
None,
)));
array_.register_builtin_const("__getitem__", Public, get_item);
let mut array_eq = Self::builtin_methods("Eq", 2);
let mut array_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(arr_t.clone())])), 2);
array_eq.register_builtin_impl(
"__eq__",
fn1_met(arr_t.clone(), arr_t.clone(), Bool),
Const,
Public,
);
array_.register_trait(
arr_t.clone(),
poly("Eq", vec![ty_tp(arr_t.clone())]),
array_eq,
);
array_.register_trait(arr_t.clone(), array_eq);
array_.register_marker_trait(mono("Mutizable"));
array_.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))]));
let mut array_show = Self::builtin_methods("Show", 1);
let mut array_show = Self::builtin_methods(Some(mono("Show")), 1);
array_show.register_builtin_impl("to_str", fn0_met(arr_t.clone(), Str), Immutable, Public);
array_.register_trait(arr_t.clone(), mono("Show"), array_show);
let mut array_iterable = Self::builtin_methods("Iterable", 2);
array_.register_trait(arr_t.clone(), array_show);
let mut array_iterable =
Self::builtin_methods(Some(poly("Iterable", vec![ty_tp(mono_q("T"))])), 2);
array_iterable.register_builtin_impl(
"iter",
fn0_met(Str, mono("ArrayIterator")),
Immutable,
Public,
);
array_.register_trait(
arr_t.clone(),
poly("Iterable", vec![ty_tp(mono_q("T"))]),
array_iterable,
);
array_.register_trait(arr_t.clone(), array_iterable);
/* Set */
let mut set_ =
Self::builtin_poly_class("Set", vec![PS::t_nd("T"), PS::named_nd("N", Nat)], 10);
@ -1015,38 +1019,31 @@ impl Context {
vec![TyParam::t(mono_q("T")), TyParam::mono_q("N").mutate()],
));
set_.register_builtin_const("MutType!", Public, mut_type);
let mut set_eq = Self::builtin_methods("Eq", 2);
let mut set_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(set_t.clone())])), 2);
set_eq.register_builtin_impl(
"__eq__",
fn1_met(set_t.clone(), set_t.clone(), Bool),
Const,
Public,
);
set_.register_trait(
set_t.clone(),
poly("Eq", vec![ty_tp(set_t.clone())]),
set_eq,
);
set_.register_trait(set_t.clone(), set_eq);
set_.register_marker_trait(mono("Mutizable"));
set_.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))]));
let mut set_show = Self::builtin_methods("Show", 1);
let mut set_show = Self::builtin_methods(Some(mono("Show")), 1);
set_show.register_builtin_impl("to_str", fn0_met(set_t.clone(), Str), Immutable, Public);
set_.register_trait(set_t.clone(), mono("Show"), set_show);
set_.register_trait(set_t.clone(), set_show);
let g_dict_t = mono("GenericDict");
let mut generic_dict = Self::builtin_mono_class("GenericDict", 2);
generic_dict.register_superclass(Obj, &obj);
let mut generic_dict_eq = Self::builtin_methods("Eq", 2);
let mut generic_dict_eq =
Self::builtin_methods(Some(poly("Eq", vec![ty_tp(g_dict_t.clone())])), 2);
generic_dict_eq.register_builtin_impl(
"__eq__",
fn1_met(g_dict_t.clone(), g_dict_t.clone(), Bool),
Const,
Public,
);
generic_dict.register_trait(
g_dict_t.clone(),
poly("Eq", vec![ty_tp(g_dict_t.clone())]),
generic_dict_eq,
);
generic_dict.register_trait(g_dict_t.clone(), generic_dict_eq);
let dict_t = poly("Dict", vec![mono_q_tp("D")]);
let mut dict_ =
// TODO: D <: GenericDict
@ -1075,18 +1072,15 @@ impl Context {
bytes.register_superclass(Obj, &obj);
let mut generic_tuple = Self::builtin_mono_class("GenericTuple", 1);
generic_tuple.register_superclass(Obj, &obj);
let mut tuple_eq = Self::builtin_methods("Eq", 2);
let mut tuple_eq =
Self::builtin_methods(Some(poly("Eq", vec![ty_tp(mono("GenericTuple"))])), 2);
tuple_eq.register_builtin_impl(
"__eq__",
fn1_met(mono("GenericTuple"), mono("GenericTuple"), Bool),
Const,
Public,
);
generic_tuple.register_trait(
mono("GenericTuple"),
poly("Eq", vec![ty_tp(mono("GenericTuple"))]),
tuple_eq,
);
generic_tuple.register_trait(mono("GenericTuple"), tuple_eq);
// Ts <: GenericArray
let tuple_t = poly("Tuple", vec![mono_q_tp("Ts")]);
let mut tuple_ =
@ -1120,7 +1114,7 @@ impl Context {
/* Float_mut */
let mut float_mut = Self::builtin_mono_class("Float!", 2);
float_mut.register_superclass(Float, &float);
let mut float_mut_mutable = Self::builtin_methods("Mutable", 2);
let mut float_mut_mutable = Self::builtin_methods(Some(mono("Mutable")), 2);
float_mut_mutable.register_builtin_const("ImmutType", Public, ValueObj::builtin_t(Float));
let f_t = kw("f", func(vec![kw("old", Float)], None, vec![], Float));
let t = pr_met(
@ -1131,11 +1125,11 @@ impl Context {
NoneType,
);
float_mut_mutable.register_builtin_impl("update!", t, Immutable, Public);
float_mut.register_trait(mono("Float!"), mono("Mutable"), float_mut_mutable);
float_mut.register_trait(mono("Float!"), float_mut_mutable);
/* Ratio_mut */
let mut ratio_mut = Self::builtin_mono_class("Ratio!", 2);
ratio_mut.register_superclass(Ratio, &ratio);
let mut ratio_mut_mutable = Self::builtin_methods("Mutable", 2);
let mut ratio_mut_mutable = Self::builtin_methods(Some(mono("Mutable")), 2);
ratio_mut_mutable.register_builtin_const("ImmutType", Public, ValueObj::builtin_t(Ratio));
let f_t = kw("f", func(vec![kw("old", Ratio)], None, vec![], Ratio));
let t = pr_met(
@ -1146,12 +1140,12 @@ impl Context {
NoneType,
);
ratio_mut_mutable.register_builtin_impl("update!", t, Immutable, Public);
ratio_mut.register_trait(mono("Ratio!"), mono("Mutable"), ratio_mut_mutable);
ratio_mut.register_trait(mono("Ratio!"), ratio_mut_mutable);
/* Int_mut */
let mut int_mut = Self::builtin_mono_class("Int!", 2);
int_mut.register_superclass(Int, &int);
int_mut.register_superclass(mono("Float!"), &float_mut);
let mut int_mut_mutable = Self::builtin_methods("Mutable", 2);
let mut int_mut_mutable = Self::builtin_methods(Some(mono("Mutable")), 2);
int_mut_mutable.register_builtin_const("ImmutType", Public, ValueObj::builtin_t(Int));
let f_t = kw("f", func(vec![kw("old", Int)], None, vec![], Int));
let t = pr_met(
@ -1162,12 +1156,12 @@ impl Context {
NoneType,
);
int_mut_mutable.register_builtin_impl("update!", t, Immutable, Public);
int_mut.register_trait(mono("Int!"), mono("Mutable"), int_mut_mutable);
int_mut.register_trait(mono("Int!"), int_mut_mutable);
let mut nat_mut = Self::builtin_mono_class("Nat!", 2);
nat_mut.register_superclass(Nat, &nat);
nat_mut.register_superclass(mono("Int!"), &int_mut);
/* Nat_mut */
let mut nat_mut_mutable = Self::builtin_methods("Mutable", 2);
let mut nat_mut_mutable = Self::builtin_methods(Some(mono("Mutable")), 2);
nat_mut_mutable.register_builtin_const("ImmutType", Public, ValueObj::builtin_t(Nat));
let f_t = kw("f", func(vec![kw("old", Nat)], None, vec![], Nat));
let t = pr_met(
@ -1178,12 +1172,12 @@ impl Context {
NoneType,
);
nat_mut_mutable.register_builtin_impl("update!", t, Immutable, Public);
nat_mut.register_trait(mono("Nat!"), mono("Mutable"), nat_mut_mutable);
nat_mut.register_trait(mono("Nat!"), nat_mut_mutable);
/* Bool_mut */
let mut bool_mut = Self::builtin_mono_class("Bool!", 2);
bool_mut.register_superclass(Bool, &bool_);
bool_mut.register_superclass(mono("Nat!"), &nat_mut);
let mut bool_mut_mutable = Self::builtin_methods("Mutable", 2);
let mut bool_mut_mutable = Self::builtin_methods(Some(mono("Mutable")), 2);
bool_mut_mutable.register_builtin_const("ImmutType", Public, ValueObj::builtin_t(Bool));
let f_t = kw("f", func(vec![kw("old", Bool)], None, vec![], Bool));
let t = pr_met(
@ -1194,11 +1188,11 @@ impl Context {
NoneType,
);
bool_mut_mutable.register_builtin_impl("update!", t, Immutable, Public);
bool_mut.register_trait(mono("Bool!"), mono("Mutable"), bool_mut_mutable);
bool_mut.register_trait(mono("Bool!"), bool_mut_mutable);
/* Str_mut */
let mut str_mut = Self::builtin_mono_class("Str!", 2);
str_mut.register_superclass(Str, &nonetype);
let mut str_mut_mutable = Self::builtin_methods("Mutable", 2);
let mut str_mut_mutable = Self::builtin_methods(Some(mono("Mutable")), 2);
str_mut_mutable.register_builtin_const("ImmutType", Public, ValueObj::builtin_t(Str));
let f_t = kw("f", func(vec![kw("old", Str)], None, vec![], Str));
let t = pr_met(
@ -1209,10 +1203,10 @@ impl Context {
NoneType,
);
str_mut_mutable.register_builtin_impl("update!", t, Immutable, Public);
str_mut.register_trait(mono("Str!"), mono("Mutable"), str_mut_mutable);
str_mut.register_trait(mono("Str!"), str_mut_mutable);
/* File_mut */
let mut file_mut = Self::builtin_mono_class("File!", 2);
let mut file_mut_readable = Self::builtin_methods("Readable!", 1);
let mut file_mut_readable = Self::builtin_methods(Some(mono("Readable!")), 1);
file_mut_readable.register_builtin_impl(
"read!",
pr_met(
@ -1225,15 +1219,15 @@ impl Context {
Immutable,
Public,
);
file_mut.register_trait(mono("File!"), mono("Readable!"), file_mut_readable);
let mut file_mut_writable = Self::builtin_methods("Writable!", 1);
file_mut.register_trait(mono("File!"), file_mut_readable);
let mut file_mut_writable = Self::builtin_methods(Some(mono("Writable!")), 1);
file_mut_writable.register_builtin_impl(
"write!",
pr1_kw_met(ref_mut(mono("File!"), None), kw("s", Str), Nat),
Immutable,
Public,
);
file_mut.register_trait(mono("File!"), mono("Writable!"), file_mut_writable);
file_mut.register_trait(mono("File!"), file_mut_writable);
/* Array_mut */
let array_mut_t = poly("Array!", vec![ty_tp(mono_q("T")), mono_q_tp("N")]);
let mut array_mut_ = Self::builtin_poly_class(
@ -1283,9 +1277,9 @@ impl Context {
vec![],
NoneType,
);
let mut array_mut_mutable = Self::builtin_methods("Mutable", 2);
let mut array_mut_mutable = Self::builtin_methods(Some(mono("Mutable")), 2);
array_mut_mutable.register_builtin_impl("update!", t, Immutable, Public);
array_mut_.register_trait(array_mut_t.clone(), mono("Mutable"), array_mut_mutable);
array_mut_.register_trait(array_mut_t.clone(), array_mut_mutable);
/* Set_mut */
let set_mut_t = poly("Set!", vec![ty_tp(mono_q("T")), mono_q_tp("N")]);
let mut set_mut_ = Self::builtin_poly_class(
@ -1336,27 +1330,23 @@ impl Context {
vec![],
NoneType,
);
let mut set_mut_mutable = Self::builtin_methods("Mutable", 2);
let mut set_mut_mutable = Self::builtin_methods(Some(mono("Mutable")), 2);
set_mut_mutable.register_builtin_impl("update!", t, Immutable, Public);
set_mut_.register_trait(set_mut_t.clone(), mono("Mutable"), set_mut_mutable);
set_mut_.register_trait(set_mut_t.clone(), set_mut_mutable);
/* Range */
let range_t = poly("Range", vec![TyParam::t(mono_q("T"))]);
let mut range = Self::builtin_poly_class("Range", vec![PS::t_nd("T")], 2);
// range.register_superclass(Obj, &obj);
range.register_superclass(Type, &type_);
range.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))]));
let mut range_eq = Self::builtin_methods("Eq", 2);
let mut range_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(range_t.clone())])), 2);
range_eq.register_builtin_impl(
"__eq__",
fn1_met(range_t.clone(), range_t.clone(), Bool),
Const,
Public,
);
range.register_trait(
range_t.clone(),
poly("Eq", vec![ty_tp(range_t.clone())]),
range_eq,
);
range.register_trait(range_t.clone(), range_eq);
/* Proc */
let mut proc = Self::builtin_mono_class("Proc", 2);
proc.register_superclass(Obj, &obj);
@ -1816,28 +1806,27 @@ impl Context {
PS::named_nd("O", Int),
PS::named_nd("P", Int),
];
let class = Type::from(&m..=&n);
// Interval is a bounding patch connecting M..N and (Add(O..P, M+O..N..P), Sub(O..P, M-P..N-O))
let mut interval = Self::builtin_poly_patch("Interval", Type::from(&m..=&n), params, 2);
let mut interval = Self::builtin_poly_patch("Interval", class.clone(), params, 2);
let op_t = fn1_met(
Type::from(&m..=&n),
class.clone(),
Type::from(&o..=&p),
Type::from(m.clone() + o.clone()..=n.clone() + p.clone()),
);
let mut interval_add = Self::builtin_methods("Add", 2);
let mut interval_add =
Self::builtin_methods(Some(poly("Add", vec![TyParam::from(&o..=&p)])), 2);
interval_add.register_builtin_impl("__add__", op_t, Const, Public);
interval_add.register_builtin_const(
"Output",
Public,
ValueObj::builtin_t(Type::from(m.clone() + o.clone()..=n.clone() + p.clone())),
);
interval.register_trait(
Type::from(&m..=&n),
poly("Add", vec![TyParam::from(&o..=&p)]),
interval_add,
);
let mut interval_sub = Self::builtin_methods("Sub", 2);
interval.register_trait(class.clone(), interval_add);
let mut interval_sub =
Self::builtin_methods(Some(poly("Sub", vec![TyParam::from(&o..=&p)])), 2);
let op_t = fn1_met(
Type::from(&m..=&n),
class.clone(),
Type::from(&o..=&p),
Type::from(m.clone() - p.clone()..=n.clone() - o.clone()),
);
@ -1845,13 +1834,9 @@ impl Context {
interval_sub.register_builtin_const(
"Output",
Public,
ValueObj::builtin_t(Type::from(m.clone() - p.clone()..=n.clone() - o.clone())),
);
interval.register_trait(
Type::from(&m..=&n),
poly("Sub", vec![TyParam::from(&o..=&p)]),
interval_sub,
ValueObj::builtin_t(Type::from(m - p..=n - o)),
);
interval.register_trait(class, interval_sub);
self.register_builtin_patch("Interval", interval, Private, Const);
// eq.register_impl("__ne__", op_t, Const, Public);
// ord.register_impl("__le__", op_t.clone(), Const, Public);

View file

@ -1150,9 +1150,9 @@ impl Context {
if let Some(obj) = self.consts.get(name.inspect()) {
Ok(obj.clone())
} else {
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
/*if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
return parent.get_const_local(name, namespace);
}
}*/
Err(TyCheckError::no_var_error(
self.cfg.input.clone(),
line!() as usize,

View file

@ -225,7 +225,7 @@ pub enum ContextKind {
Func,
Proc,
Class,
MethodDefs,
MethodDefs(Option<Type>), // Type: trait implemented
Trait,
StructuralTrait,
Patch(Type),
@ -250,7 +250,7 @@ impl From<DefKind> for ContextKind {
impl ContextKind {
pub const fn is_method_def(&self) -> bool {
matches!(self, Self::MethodDefs)
matches!(self, Self::MethodDefs(_))
}
pub const fn is_type(&self) -> bool {
@ -462,13 +462,13 @@ impl Context {
let idx = ParamIdx::Nth(idx);
let kind = VarKind::parameter(id, idx, param.default_info);
let muty = Mutability::from(name);
let vi = VarInfo::new(param.t, muty, Private, kind, None);
let vi = VarInfo::new(param.t, muty, Private, kind, None, None);
params_.push((Some(VarName::new(Token::static_symbol(name))), vi));
} else {
let idx = ParamIdx::Nth(idx);
let kind = VarKind::parameter(id, idx, param.default_info);
let muty = Mutability::Immutable;
let vi = VarInfo::new(param.t, muty, Private, kind, None);
let vi = VarInfo::new(param.t, muty, Private, kind, None, None);
params_.push((None, vi));
}
}
@ -677,18 +677,23 @@ impl Context {
}
#[inline]
pub fn methods<S: Into<Str>>(
name: S,
pub fn methods(
impl_trait: Option<Type>,
cfg: ErgConfig,
mod_cache: Option<SharedModuleCache>,
py_mod_cache: Option<SharedModuleCache>,
capacity: usize,
level: usize,
) -> Self {
let name = if let Some(tr) = &impl_trait {
tr.local_name()
} else {
Str::ever("Methods")
};
Self::with_capacity(
name.into(),
name,
cfg,
ContextKind::MethodDefs,
ContextKind::MethodDefs(impl_trait),
vec![],
None,
mod_cache,
@ -699,9 +704,9 @@ impl Context {
}
#[inline]
pub fn builtin_methods<S: Into<Str>>(name: S, capacity: usize) -> Self {
pub fn builtin_methods(impl_trait: Option<Type>, capacity: usize) -> Self {
Self::methods(
name,
impl_trait,
ErgConfig::default(),
None,
None,
@ -811,6 +816,14 @@ impl Context {
self.outer.as_ref().map(|x| x.as_ref())
}
pub(crate) fn impl_of(&self) -> Option<Type> {
if let ContextKind::MethodDefs(Some(tr)) = &self.kind {
Some(tr.clone())
} else {
None
}
}
pub(crate) fn path(&self) -> Str {
// NOTE: this need to be changed if we want to support nested classes/traits
if let Some(outer) = self.get_outer() {

View file

@ -86,7 +86,7 @@ impl Context {
} else {
self.decls.insert(
ident.name.clone(),
VarInfo::new(sig_t, muty, vis, kind, None),
VarInfo::new(sig_t, muty, vis, kind, None, self.impl_of()),
);
Ok(())
}
@ -121,11 +121,12 @@ impl Context {
vis,
kind.clone(),
Some(comptime_decos.clone()),
self.impl_of(),
);
self.decls.insert(sig.ident.name.clone(), vi);
e
})?;
let vi = VarInfo::new(t, muty, vis, kind, Some(comptime_decos));
let vi = VarInfo::new(t, muty, vis, kind, Some(comptime_decos), self.impl_of());
if let Some(_decl) = self.decls.remove(name) {
Err(TyCheckErrors::from(TyCheckError::duplicate_decl_error(
self.cfg.input.clone(),
@ -161,7 +162,15 @@ impl Context {
let generalized = self.generalize_t(body_t.clone());
self.decls.remove(ident.inspect());
let vis = ident.vis();
let vi = VarInfo::new(generalized, muty, vis, VarKind::Defined(id), None);
let vi = VarInfo::new(
generalized,
muty,
vis,
VarKind::Defined(id),
None,
self.impl_of(),
);
log!(info "Registered {}::{}: {} {:?}", self.name, ident.name, vi.t, vi.impl_of);
self.locals.insert(ident.name.clone(), vi);
Ok(())
}
@ -211,7 +220,7 @@ impl Context {
let muty = Mutability::from(&name.inspect()[..]);
self.params.push((
Some(name.clone()),
VarInfo::new(spec_t, muty, Private, kind, None),
VarInfo::new(spec_t, muty, Private, kind, None, None),
));
Ok(())
}
@ -250,7 +259,7 @@ impl Context {
VarKind::parameter(DefId(get_hash(&(&self.name, name))), idx, default);
self.params.push((
Some(name.clone()),
VarInfo::new(spec_t, Immutable, Private, kind, None),
VarInfo::new(spec_t, Immutable, Private, kind, None, None),
));
Ok(())
}
@ -289,7 +298,7 @@ impl Context {
VarKind::parameter(DefId(get_hash(&(&self.name, name))), idx, default);
self.params.push((
Some(name.clone()),
VarInfo::new(spec_t, Immutable, Private, kind, None),
VarInfo::new(spec_t, Immutable, Private, kind, None, None),
));
Ok(())
}
@ -451,9 +460,10 @@ impl Context {
sig.ident.vis(),
VarKind::Defined(id),
Some(comptime_decos),
self.impl_of(),
);
let t = vi.t.clone();
log!(info "Registered {}::{name}: {}", self.name, t);
log!(info "Registered {}::{name}: {t}", self.name);
self.locals.insert(name.clone(), vi);
Ok(t)
}
@ -487,6 +497,7 @@ impl Context {
sig.ident.vis(),
VarKind::DoesNotExist,
Some(comptime_decos),
self.impl_of(),
);
log!(info "Registered {}::{name}: {}", self.name, &vi.t);
self.locals.insert(name.clone(), vi);
@ -576,8 +587,10 @@ impl Context {
if self.locals.get(&name).is_some() {
panic!("already registered: {name}");
} else {
self.locals
.insert(name, VarInfo::new(t, muty, vis, VarKind::Auto, None));
self.locals.insert(
name,
VarInfo::new(t, muty, vis, VarKind::Auto, None, self.impl_of()),
);
}
}
@ -593,33 +606,55 @@ impl Context {
if self.locals.get(&name).is_some() {
panic!("already registered: {name}");
} else {
self.locals
.insert(name, VarInfo::new(t, muty, vis, VarKind::FixedAuto, None));
self.locals.insert(
name,
VarInfo::new(t, muty, vis, VarKind::FixedAuto, None, self.impl_of()),
);
}
}
fn _register_gen_decl(&mut self, name: VarName, t: Type, vis: Visibility) {
fn _register_gen_decl(
&mut self,
name: VarName,
t: Type,
vis: Visibility,
impl_of: Option<Type>,
) {
if self.decls.get(&name).is_some() {
panic!("already registered: {name}");
} else {
self.decls.insert(
name,
VarInfo::new(t, Immutable, vis, VarKind::Declared, None),
VarInfo::new(t, Immutable, vis, VarKind::Declared, None, impl_of),
);
}
}
fn _register_gen_impl(&mut self, name: VarName, t: Type, muty: Mutability, vis: Visibility) {
fn _register_gen_impl(
&mut self,
name: VarName,
t: Type,
muty: Mutability,
vis: Visibility,
impl_of: Option<Type>,
) {
if self.locals.get(&name).is_some() {
panic!("already registered: {name}");
} else {
let id = DefId(get_hash(&(&self.name, &name)));
self.locals
.insert(name, VarInfo::new(t, muty, vis, VarKind::Defined(id), None));
self.locals.insert(
name,
VarInfo::new(t, muty, vis, VarKind::Defined(id), None, impl_of),
);
}
}
pub(crate) fn register_trait(&mut self, class: Type, trait_: Type, methods: Self) {
pub(crate) fn register_trait(&mut self, class: Type, methods: Self) {
let trait_ = if let ContextKind::MethodDefs(Some(tr)) = &methods.kind {
tr.clone()
} else {
todo!()
};
self.super_traits.push(trait_.clone());
self.methods_list
.push((ClassDefType::impl_trait(class, trait_), methods));
@ -648,7 +683,9 @@ impl Context {
TypeObj::Generated(gen) => {
self.register_gen_type(ident, gen);
}
TypeObj::Builtin(_t) => panic!("aliasing bug"),
TypeObj::Builtin(t) => {
self.register_type_alias(ident, t);
}
},
// TODO: not all value objects are comparable
other => {
@ -659,9 +696,10 @@ impl Context {
ident.vis(),
VarKind::Defined(id),
None,
self.impl_of(),
);
self.consts.insert(ident.name.clone(), other);
self.decls.insert(ident.name.clone(), vi);
self.consts.insert(ident.name.clone(), other);
}
}
Ok(())
@ -682,7 +720,7 @@ impl Context {
self.level,
);
let mut methods = Self::methods(
gen.t.qual_name(),
None,
self.cfg.clone(),
self.mod_cache.clone(),
self.py_mod_cache.clone(),
@ -720,7 +758,7 @@ impl Context {
ctx.register_superclass(sup, sup_ctx);
}
let mut methods = Self::methods(
gen.t.qual_name(),
None,
self.cfg.clone(),
self.mod_cache.clone(),
self.py_mod_cache.clone(),
@ -778,7 +816,14 @@ impl Context {
} else {
Mutability::Immutable
};
let vi = VarInfo::new(t.clone(), muty, field.vis, VarKind::Declared, None);
let vi = VarInfo::new(
t.clone(),
muty,
field.vis,
VarKind::Declared,
None,
self.impl_of(),
);
ctx.decls
.insert(VarName::from_str(field.symbol.clone()), vi);
}
@ -807,8 +852,14 @@ impl Context {
} else {
Mutability::Immutable
};
let vi =
VarInfo::new(t.clone(), muty, field.vis, VarKind::Declared, None);
let vi = VarInfo::new(
t.clone(),
muty,
field.vis,
VarKind::Declared,
None,
self.impl_of(),
);
ctx.decls
.insert(VarName::from_str(field.symbol.clone()), vi);
}
@ -826,6 +877,31 @@ impl Context {
}
}
pub(crate) fn register_type_alias(&mut self, ident: &Identifier, t: Type) {
if self.mono_types.contains_key(ident.inspect()) {
panic!("{ident} has already been registered");
} else if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() {
panic!("{ident} has already been registered as const");
} else {
let name = &ident.name;
let muty = Mutability::from(&ident.inspect()[..]);
let id = DefId(get_hash(&(&self.name, &name)));
self.decls.insert(
name.clone(),
VarInfo::new(
Type::Type,
muty,
ident.vis(),
VarKind::Defined(id),
None,
self.impl_of(),
),
);
self.consts
.insert(name.clone(), ValueObj::Type(TypeObj::Builtin(t)));
}
}
fn register_gen_mono_type(
&mut self,
ident: &Identifier,
@ -846,7 +922,14 @@ impl Context {
let id = DefId(get_hash(&(&self.name, &name)));
self.decls.insert(
name.clone(),
VarInfo::new(meta_t, muty, ident.vis(), VarKind::Defined(id), None),
VarInfo::new(
meta_t,
muty,
ident.vis(),
VarKind::Defined(id),
None,
self.impl_of(),
),
);
self.consts
.insert(name.clone(), ValueObj::Type(TypeObj::Generated(gen)));

View file

@ -927,12 +927,11 @@ impl ASTLowerer {
}
}
}
let id = body.id;
self.ctx
.outer
.as_mut()
.unwrap()
.assign_var_sig(&sig, found_body_t, id)?;
.assign_var_sig(&sig, found_body_t, body.id)?;
let ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone());
let sig = hir::VarSignature::new(ident, found_body_t.clone());
let body = hir::DefBody::new(body.op, block, body.id);
@ -1087,8 +1086,8 @@ impl ASTLowerer {
self.ctx.get_similar_name(&class.local_name()),
)));
}
self.ctx
.grow(&class.local_name(), ContextKind::MethodDefs, Private, None);
let kind = ContextKind::MethodDefs(impl_trait.as_ref().map(|(t, _)| t.clone()));
self.ctx.grow(&class.local_name(), kind, Private, None);
for def in methods.defs.iter_mut() {
if methods.vis.is(TokenKind::Dot) {
def.sig.ident_mut().unwrap().dot = Some(Token::new(
@ -1110,21 +1109,19 @@ impl ASTLowerer {
}
}
}
match self.ctx.check_decls() {
Ok(()) => {
self.check_override(&class);
if let Some((trait_, _)) = &impl_trait {
self.register_trait_impl(&class, trait_);
}
if let Err(err) = self.check_trait_impl(impl_trait, &class) {
self.errs.push(err);
}
self.check_collision_and_push(class);
}
Err(mut errs) => {
self.errs.append(&mut errs);
}
if let Err(mut errs) = self.ctx.check_decls() {
self.errs.append(&mut errs);
}
if let Some((trait_, _)) = &impl_trait {
self.check_override(&class, Some(trait_));
self.register_trait_impl(&class, trait_);
} else {
self.check_override(&class, None);
}
if let Err(err) = self.check_trait_impl(impl_trait, &class) {
self.errs.push(err);
}
self.check_collision_and_push(class);
}
let class = mono(hir_def.sig.ident().inspect());
let class_ctx = self.ctx.get_nominal_type_ctx(&class).unwrap();
@ -1185,8 +1182,9 @@ impl ASTLowerer {
}
}
fn check_override(&mut self, class: &Type) {
fn check_override(&mut self, class: &Type, impl_trait: Option<&Type>) {
if let Some(sups) = self.ctx.get_nominal_super_type_ctxs(class) {
// exclude the first one because it is the class itself
for sup in sups.into_iter().skip(1) {
for (method_name, vi) in self.ctx.locals.iter().chain(
self.ctx
@ -1194,13 +1192,16 @@ impl ASTLowerer {
.iter()
.flat_map(|(_, c)| c.locals.iter()),
) {
if let Some(_sup_vi) = sup.get_current_scope_var(method_name.inspect()) {
if let Some(sup_vi) = sup.get_current_scope_var(method_name.inspect()) {
// must `@Override`
if let Some(decos) = &vi.comptime_decos {
if decos.contains("Override") {
continue;
}
}
if sup_vi.impl_of.as_ref() != impl_trait {
continue;
}
self.errs.push(LowerError::override_error(
self.cfg.input.clone(),
line!() as usize,
@ -1270,7 +1271,6 @@ impl ASTLowerer {
if let Some((name, vi)) = self.ctx.get_local_kv(decl_name.inspect())
{
unverified_names.remove(name);
log!(err "checking");
if !self.ctx.supertype_of(&decl_vi.t, &vi.t) {
self.errs.push(LowerError::trait_member_type_error(
self.cfg.input.clone(),
@ -1355,14 +1355,16 @@ impl ASTLowerer {
.ctx
.get_mut_nominal_type_ctx(&class)
.unwrap_or_else(|| todo!("{class} not found"));
for (newly_defined_name, _vi) in methods.locals.clone().into_iter() {
for (newly_defined_name, vi) in methods.locals.clone().into_iter() {
for (_, already_defined_methods) in class_root.methods_list.iter_mut() {
// TODO: 特殊化なら同じ名前でもOK
// TODO: 定義のメソッドもエラー表示
if let Some((_already_defined_name, already_defined_vi)) =
already_defined_methods.get_local_kv(newly_defined_name.inspect())
{
if already_defined_vi.kind != VarKind::Auto {
if already_defined_vi.kind != VarKind::Auto
&& already_defined_vi.impl_of == vi.impl_of
{
self.errs.push(LowerError::duplicate_definition_error(
self.cfg.input.clone(),
line!() as usize,
@ -1542,6 +1544,7 @@ impl ASTLowerer {
ident.vis(),
VarKind::Declared,
None,
None,
);
self.ctx.decls.insert(ident.name.clone(), vi);
}

View file

@ -122,6 +122,7 @@ pub struct VarInfo {
pub vis: Visibility,
pub kind: VarKind,
pub comptime_decos: Option<Set<Str>>,
pub impl_of: Option<Type>,
}
impl fmt::Display for VarInfo {
@ -160,6 +161,7 @@ impl VarInfo {
Private,
VarKind::DoesNotExist,
None,
None,
);
pub const fn new(
@ -168,6 +170,7 @@ impl VarInfo {
vis: Visibility,
kind: VarKind,
comptime_decos: Option<Set<Str>>,
impl_of: Option<Type>,
) -> Self {
Self {
t,
@ -175,6 +178,7 @@ impl VarInfo {
vis,
kind,
comptime_decos,
impl_of,
}
}

View file

@ -16,7 +16,7 @@ simplified_chinese = ["erg_common/simplified_chinese"]
traditional_chinese = ["erg_common/traditional_chinese"]
[dependencies]
erg_common = { version = "0.5.9-nightly.6", path = "../erg_common" }
erg_common = { version = "0.5.9", path = "../erg_common" }
[lib]
path = "lib.rs"

View file

@ -6,12 +6,18 @@ Point|Point <: Add(Point)|.
Output = Point
__add__ self, other: Point =
Point.new(self::x + other::x, self::y + other::y)
Point|Point <: Mul(Point)|.
Output = Nat
__mul__ self, other: Point =
self::x * other::x + self::y * other::y
Point|Point <: Eq(Point)|.
__eq__ self, other: Point =
self::x == other::x and self::y == other::y
p = Point.new 1, 2
q = Point.new 3, 4
r = p + q
r: Point = p + q
s: Nat = p * q
assert s == 11
assert r == Point.new 4, 6
assert r.norm() == 52