mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
Omit class names in member access
This commit is contained in:
parent
048e281268
commit
fe969299d7
4 changed files with 40 additions and 4 deletions
|
@ -1370,11 +1370,27 @@ impl CodeGenerator {
|
|||
Accessor::Attr(a) => {
|
||||
let class = a.obj.ref_t().name();
|
||||
let uniq_obj_name = a.obj.__name__().map(Str::rc);
|
||||
self.codegen_expr(*a.obj);
|
||||
self.emit_load_attr_instr(&class, uniq_obj_name.as_ref().map(|s| &s[..]), a.ident)
|
||||
// C = Class ...
|
||||
// C.
|
||||
// a = C.x
|
||||
// ↓
|
||||
// class C:
|
||||
// a = x
|
||||
if Some(&self.cur_block_codeobj().name[..]) != a.obj.__name__() {
|
||||
self.codegen_expr(*a.obj);
|
||||
self.emit_load_attr_instr(
|
||||
&class,
|
||||
uniq_obj_name.as_ref().map(|s| &s[..]),
|
||||
a.ident,
|
||||
)
|
||||
.unwrap_or_else(|err| {
|
||||
self.errs.push(err);
|
||||
});
|
||||
} else {
|
||||
self.emit_load_name_instr(a.ident).unwrap_or_else(|err| {
|
||||
self.errs.push(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
Accessor::TupleAttr(t_attr) => {
|
||||
self.codegen_expr(*t_attr.obj);
|
||||
|
|
|
@ -194,6 +194,9 @@ impl Context {
|
|||
if let Some(ctx) = self.rec_get_mod(name.inspect()) {
|
||||
return Some(ctx.name.clone());
|
||||
}
|
||||
if let Some((_, ctx)) = self.rec_get_type(name.inspect()) {
|
||||
return Some(ctx.name.clone());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1280,7 +1283,6 @@ impl Context {
|
|||
}
|
||||
|
||||
fn rec_get_singular_ctx(&self, obj: &hir::Expr) -> Option<&Context> {
|
||||
log!("{}", obj.ref_t());
|
||||
match obj.ref_t() {
|
||||
// TODO: attr
|
||||
Type::Module => self.rec_get_mod(&obj.show_acc()?),
|
||||
|
@ -1415,6 +1417,18 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
fn rec_get_type(&self, name: &str) -> Option<(&Type, &Context)> {
|
||||
if let Some((t, ctx)) = self.mono_types.get(name) {
|
||||
Some((t, ctx))
|
||||
} else if let Some((t, ctx)) = self.poly_types.get(name) {
|
||||
Some((t, ctx))
|
||||
} else if let Some(outer) = &self.outer {
|
||||
outer.rec_get_type(name)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_gen_t_require_attr_t<'a>(&'a self, gen: &'a GenTypeObj, attr: &str) -> Option<&'a Type> {
|
||||
match gen.require_or_sup.typ() {
|
||||
Type::Record(rec) => {
|
||||
|
|
|
@ -528,7 +528,7 @@ impl Accessor {
|
|||
}
|
||||
}
|
||||
|
||||
// 参照するオブジェクト自体が持っている固有の名前
|
||||
// 参照するオブジェクト自体が持っている固有の名前(クラス、モジュールなど)
|
||||
pub fn __name__(&self) -> Option<&str> {
|
||||
match self {
|
||||
Self::Ident(ident) => ident.__name__.as_ref().map(|s| &s[..]),
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
# Inheritance is prohibited by default. Remove this decorator and check for errors.
|
||||
@Inheritable
|
||||
Point2D = Class {x = Int; y = Int}
|
||||
Point2D::
|
||||
one = 1
|
||||
Point2D.
|
||||
zero = Point2D::one - 1
|
||||
norm self = self::x**2 + self::y**2
|
||||
|
||||
Point3D = Inherit Point2D, Additional := {z = Int}
|
||||
|
@ -13,7 +16,10 @@ Point3D.
|
|||
@Override
|
||||
norm self = self::x**2 + self::y**2 + self::z**2
|
||||
|
||||
# `Point2D::__new__` is private, use `Point2D.new` instead
|
||||
p = Point2D.new {x = 1; y = 2}
|
||||
print! p, p.norm()
|
||||
print! Point2D.zero
|
||||
# print! Point2D::one # cannot access private variables
|
||||
q = Point3D.new 1, 2, 3
|
||||
print! q, q.norm()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue