mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 04:24:43 +00:00
Add HIRDesugerer::desugar_class_member
This commit is contained in:
parent
b3428d8129
commit
65254a19e5
3 changed files with 55 additions and 18 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue