Add HIRDesugerer::desugar_class_member

This commit is contained in:
Shunsuke Shibayama 2022-10-14 16:04:14 +09:00
parent b3428d8129
commit 65254a19e5
3 changed files with 55 additions and 18 deletions

View file

@ -812,18 +812,8 @@ impl CodeGenerator {
Accessor::Attr(a) => {
let class = a.obj.ref_t().qual_name();
let uniq_obj_name = a.obj.local_name().map(Str::rc);
if Some(&self.cur_block_codeobj().name[..]) == a.obj.local_name()
&& &self.cur_block_codeobj().name[..] != "<module>"
{
self.emit_load_name_instr(a.ident);
} else {
self.emit_expr(*a.obj);
self.emit_load_attr_instr(
&class,
uniq_obj_name.as_ref().map(|s| &s[..]),
a.ident,
);
}
self.emit_expr(*a.obj);
self.emit_load_attr_instr(&class, uniq_obj_name.as_ref().map(|s| &s[..]), a.ident);
}
Accessor::TupleAttr(t_attr) => {
self.emit_expr(*t_attr.obj);

View file

@ -1,9 +1,16 @@
use crate::hir::HIR;
use erg_common::log;
use erg_common::traits::Stream;
use crate::hir::{Accessor, AttrDef, Block, Expr, HIR};
use crate::ty::Type;
pub struct HIRDesugarer {}
impl HIRDesugarer {
pub fn desugar(hir: HIR) -> HIR {
log!(info "HIR desugaring process has started.");
let hir = Self::desugar_class_member(hir);
log!(info "HIR desugaring process has completed.");
hir
}
@ -14,10 +21,44 @@ impl HIRDesugarer {
// x = 1
// ↓
// class C:
// def _Self(): return C
// def a(): return C.x()
// def x(): return 1
fn _desugar_class_member(_hir: HIR) -> HIR {
_hir
// pass
// C._Self = C
// C.a = C.x
// C.x = 1
fn desugar_class_member(mut hir: HIR) -> HIR {
for chunk in hir.module.iter_mut() {
let static_members = match chunk {
Expr::ClassDef(class_def) => {
let class = Expr::Accessor(Accessor::Ident(class_def.sig.ident().clone()));
let methods = std::mem::take(class_def.methods.ref_mut_payload());
let (methods, static_members): (Vec<_>, Vec<_>) = methods
.into_iter()
.partition(|attr| matches!(attr, Expr::Def(def) if def.sig.is_subr()));
class_def.methods.extend(methods);
static_members
.into_iter()
.map(|expr| match expr {
Expr::Def(def) => {
let acc = Accessor::attr(
class.clone(),
def.sig.into_ident(),
Type::Untyped,
);
let attr_def = AttrDef::new(acc, def.body.block);
Expr::AttrDef(attr_def)
}
_ => expr,
})
.collect()
}
_ => vec![],
};
if !static_members.is_empty() {
*chunk = Expr::Compound(Block::new(
[vec![std::mem::take(chunk)], static_members].concat(),
));
}
}
hir
}
}

View file

@ -1700,6 +1700,12 @@ impl_display_from_nested!(Expr);
impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound, TypeAsc, Set);
impl_t_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound, TypeAsc, Set);
impl Default for Expr {
fn default() -> Self {
Self::Code(Block::default())
}
}
impl Expr {
pub fn receiver_t(&self) -> Option<&Type> {
match self {