diff --git a/compiler/erg_compiler/codegen.rs b/compiler/erg_compiler/codegen.rs index 612b3e55..4fef9b24 100644 --- a/compiler/erg_compiler/codegen.rs +++ b/compiler/erg_compiler/codegen.rs @@ -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[..] != "" - { - 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); diff --git a/compiler/erg_compiler/desugar_hir.rs b/compiler/erg_compiler/desugar_hir.rs index df5ca175..575920bb 100644 --- a/compiler/erg_compiler/desugar_hir.rs +++ b/compiler/erg_compiler/desugar_hir.rs @@ -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 } } diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index 02ee840d..cc4385f1 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -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 {