Omit class names in member access

This commit is contained in:
Shunsuke Shibayama 2022-09-10 17:52:03 +09:00
parent 048e281268
commit fe969299d7
4 changed files with 40 additions and 4 deletions

View file

@ -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);

View file

@ -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) => {

View file

@ -528,7 +528,7 @@ impl Accessor {
}
}
// 参照するオブジェクト自体が持っている固有の名前
// 参照するオブジェクト自体が持っている固有の名前(クラス、モジュールなど)
pub fn __name__(&self) -> Option<&str> {
match self {
Self::Ident(ident) => ident.__name__.as_ref().map(|s| &s[..]),

View file

@ -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()