Refactor: AttrDef -> ReDef

This commit is contained in:
Shunsuke Shibayama 2022-12-27 14:07:39 +09:00
parent 24627eb26c
commit a249de98b3
10 changed files with 83 additions and 68 deletions

View file

@ -37,8 +37,8 @@ use erg_parser::token::{Token, TokenKind};
use crate::compile::{AccessKind, Name, StoreLoadKind};
use crate::error::CompileError;
use crate::hir::{
Accessor, Args, Array, AttrDef, BinOp, Block, Call, ClassDef, Def, DefBody, Expr, Identifier,
Lambda, Literal, Params, PatchDef, PosArg, Record, Signature, SubrSignature, Tuple, UnaryOp,
Accessor, Args, Array, BinOp, Block, Call, ClassDef, Def, DefBody, Expr, Identifier, Lambda,
Literal, Params, PatchDef, PosArg, ReDef, Record, Signature, SubrSignature, Tuple, UnaryOp,
VarSignature, HIR,
};
use crate::ty::value::ValueObj;
@ -1220,10 +1220,10 @@ impl PyCodeGenerator {
}
}
fn emit_attr_def(&mut self, attr_def: AttrDef) {
log!(info "entered {} ({attr_def})", fn_name!());
self.emit_frameless_block(attr_def.block, vec![]);
self.store_acc(attr_def.attr);
fn emit_redef(&mut self, redef: ReDef) {
log!(info "entered {} ({redef})", fn_name!());
self.emit_frameless_block(redef.block, vec![]);
self.store_acc(redef.attr);
}
fn emit_var_def(&mut self, sig: VarSignature, mut body: DefBody) {
@ -2640,7 +2640,7 @@ impl PyCodeGenerator {
Expr::Def(def) => self.emit_def(def),
Expr::ClassDef(class) => self.emit_class_def(class),
Expr::PatchDef(patch) => self.emit_patch_def(patch),
Expr::AttrDef(attr) => self.emit_attr_def(attr),
Expr::ReDef(attr) => self.emit_redef(attr),
Expr::Lambda(lambda) => self.emit_lambda(lambda),
Expr::UnaryOp(unary) => self.emit_unaryop(unary),
Expr::BinOp(bin) => self.emit_binop(bin),
@ -2669,7 +2669,7 @@ impl PyCodeGenerator {
Expr::Def(def) => self.emit_def(def),
Expr::ClassDef(class) => self.emit_class_def(class),
Expr::PatchDef(patch) => self.emit_patch_def(patch),
Expr::AttrDef(attr) => self.emit_attr_def(attr),
Expr::ReDef(attr) => self.emit_redef(attr),
Expr::Lambda(lambda) => self.emit_lambda(lambda),
Expr::UnaryOp(unary) => self.emit_unaryop(unary),
Expr::BinOp(bin) => self.emit_binop(bin),
@ -2840,8 +2840,8 @@ impl PyCodeGenerator {
dot,
VarName::from_str(field.symbol.clone()),
));
let attr_def = AttrDef::new(attr, Block::new(vec![expr]));
attrs.push(Expr::AttrDef(attr_def));
let redef = ReDef::new(attr, Block::new(vec![expr]));
attrs.push(Expr::ReDef(redef));
}
let none = Token::new(TokenKind::NoneLit, "None", line, 0);
attrs.push(Expr::Lit(Literal::new(ValueObj::None, none)));

View file

@ -869,9 +869,9 @@ impl Context {
}
Ok(())
}
hir::Expr::AttrDef(attr_def) => {
// REVIEW: attr_def.attr is not dereferenced
for chunk in attr_def.block.iter_mut() {
hir::Expr::ReDef(redef) => {
// REVIEW: redef.attr is not dereferenced
for chunk in redef.block.iter_mut() {
self.resolve_expr_t(chunk)?;
}
Ok(())

View file

@ -1,7 +1,7 @@
use erg_common::log;
use erg_common::traits::Stream;
use crate::hir::{Accessor, AttrDef, Block, Expr, HIR};
use crate::hir::{Accessor, Block, Expr, ReDef, HIR};
/// Desugares HIR to make it more like Python semantics.
pub struct HIRDesugarer {}
@ -45,8 +45,8 @@ impl HIRDesugarer {
.map(|expr| match expr {
Expr::Def(def) => {
let acc = class.clone().attr(def.sig.into_ident());
let attr_def = AttrDef::new(acc, def.body.block);
Expr::AttrDef(attr_def)
let redef = ReDef::new(acc, def.body.block);
Expr::ReDef(redef)
}
_ => expr,
})

View file

@ -194,7 +194,7 @@ impl SideEffectChecker {
self.path_stack.pop();
self.block_stack.pop();
}
Expr::AttrDef(_)
Expr::ReDef(_)
| Expr::Code(_)
| Expr::Compound(_)
| Expr::Import(_)
@ -457,7 +457,7 @@ impl SideEffectChecker {
));
}
}
Expr::AttrDef(_)
Expr::ReDef(_)
| Expr::Code(_)
| Expr::Compound(_)
| Expr::Import(_)

View file

@ -2181,12 +2181,12 @@ impl PatchDef {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct AttrDef {
pub struct ReDef {
pub attr: Accessor,
pub block: Block,
}
impl NestedDisplay for AttrDef {
impl NestedDisplay for ReDef {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
self.attr.fmt_nest(f, level)?;
writeln!(f, " = ")?;
@ -2194,7 +2194,7 @@ impl NestedDisplay for AttrDef {
}
}
impl NoTypeDisplay for AttrDef {
impl NoTypeDisplay for ReDef {
fn to_string_notype(&self) -> String {
format!(
"{} = {}",
@ -2204,10 +2204,10 @@ impl NoTypeDisplay for AttrDef {
}
}
impl_display_from_nested!(AttrDef);
impl_locational!(AttrDef, attr, block);
impl_display_from_nested!(ReDef);
impl_locational!(ReDef, attr, block);
impl HasType for AttrDef {
impl HasType for ReDef {
#[inline]
fn ref_t(&self) -> &Type {
Type::NONE
@ -2226,7 +2226,7 @@ impl HasType for AttrDef {
}
}
impl AttrDef {
impl ReDef {
pub const fn new(attr: Accessor, block: Block) -> Self {
Self { attr, block }
}
@ -2297,7 +2297,7 @@ pub enum Expr {
Def(Def),
ClassDef(ClassDef),
PatchDef(PatchDef),
AttrDef(AttrDef),
ReDef(ReDef),
TypeAsc(TypeAscription),
Code(Block), // code object
Compound(Block), // compound statement
@ -2305,11 +2305,11 @@ pub enum Expr {
Dummy(Dummy), // for mapping to Python AST
}
impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, AttrDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_no_type_display_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, AttrDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_no_type_display_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_display_from_nested!(Expr);
impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, AttrDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_t_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, AttrDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_t_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl Default for Expr {
fn default() -> Self {

View file

@ -145,9 +145,9 @@ impl<'a> Linker<'a> {
self.resolve_pymod_path(def);
}
}
Expr::AttrDef(attr_def) => {
Expr::ReDef(redef) => {
// REVIEW:
for chunk in attr_def.block.iter_mut() {
for chunk in redef.block.iter_mut() {
self.resolve_pymod_path(chunk);
}
}
@ -267,9 +267,9 @@ impl<'a> Linker<'a> {
self.replace_import(def);
}
}
Expr::AttrDef(attr_def) => {
Expr::ReDef(redef) => {
// REVIEW:
for chunk in attr_def.block.iter_mut() {
for chunk in redef.block.iter_mut() {
self.replace_import(chunk);
}
}

View file

@ -1473,10 +1473,11 @@ impl ASTLowerer {
Ok(hir::PatchDef::new(hir_def.sig, base, hir_methods))
}
fn lower_attr_def(&mut self, attr_def: ast::AttrDef) -> LowerResult<hir::AttrDef> {
log!(info "entered {}({attr_def})", fn_name!());
let attr = self.lower_acc(attr_def.attr)?;
let expr = self.lower_expr(*attr_def.expr)?;
fn lower_redef(&mut self, redef: ast::ReDef) -> LowerResult<hir::ReDef> {
log!(info "entered {}({redef})", fn_name!());
let loc = redef.loc();
let attr = self.lower_acc(redef.attr)?;
let expr = self.lower_expr(*redef.expr)?;
if let Err(err) = self.var_result_t_check(
attr.loc(),
&Str::from(attr.show()),
@ -1485,7 +1486,21 @@ impl ASTLowerer {
) {
self.errs.push(err);
}
Ok(hir::AttrDef::new(attr, hir::Block::new(vec![expr])))
if !self.ctx.supertype_of(attr.ref_t(), expr.ref_t()) {
self.errs.push(LowerError::type_mismatch_error(
self.cfg.input.clone(),
line!() as usize,
loc,
self.ctx.caused_by(),
&attr.to_string_notype(),
None,
attr.ref_t(),
expr.ref_t(),
None,
None,
));
}
Ok(hir::ReDef::new(attr, hir::Block::new(vec![expr])))
}
fn register_trait_impl(
@ -1960,7 +1975,7 @@ impl ASTLowerer {
ast::Expr::Def(def) => Ok(hir::Expr::Def(self.lower_def(def)?)),
ast::Expr::ClassDef(defs) => Ok(hir::Expr::ClassDef(self.lower_class_def(defs)?)),
ast::Expr::PatchDef(defs) => Ok(hir::Expr::PatchDef(self.lower_patch_def(defs)?)),
ast::Expr::AttrDef(adef) => Ok(hir::Expr::AttrDef(self.lower_attr_def(adef)?)),
ast::Expr::ReDef(redef) => Ok(hir::Expr::ReDef(self.lower_redef(redef)?)),
ast::Expr::TypeAsc(tasc) => Ok(hir::Expr::TypeAsc(self.lower_decl(tasc)?)),
other => self.lower_expr(other),
}

View file

@ -19,8 +19,8 @@ use crate::context::{Context, ContextProvider};
use crate::desugar_hir::HIRDesugarer;
use crate::error::{CompileError, CompileErrors};
use crate::hir::{
Accessor, Args, Array, AttrDef, BinOp, Block, Call, ClassDef, Def, Dict, Expr, Identifier,
Lambda, Literal, Params, PatchDef, Record, Set, Signature, Tuple, UnaryOp, HIR,
Accessor, Args, Array, BinOp, Block, Call, ClassDef, Def, Dict, Expr, Identifier, Lambda,
Literal, Params, PatchDef, ReDef, Record, Set, Signature, Tuple, UnaryOp, HIR,
};
use crate::link::Linker;
use crate::mod_cache::SharedModuleCache;
@ -415,7 +415,7 @@ impl ScriptGenerator {
Expr::Lambda(lambda) => self.transpile_lambda(lambda),
Expr::ClassDef(classdef) => self.transpile_classdef(classdef),
Expr::PatchDef(patchdef) => self.transpile_patchdef(patchdef),
Expr::AttrDef(adef) => self.transpile_attrdef(adef),
Expr::ReDef(redef) => self.transpile_attrdef(redef),
// TODO:
Expr::Compound(comp) => {
let mut code = "".to_string();
@ -916,17 +916,17 @@ impl ScriptGenerator {
code
}
fn transpile_attrdef(&mut self, mut adef: AttrDef) -> String {
let mut code = format!("{} = ", self.transpile_expr(Expr::Accessor(adef.attr)));
if adef.block.len() > 1 {
fn transpile_attrdef(&mut self, mut redef: ReDef) -> String {
let mut code = format!("{} = ", self.transpile_expr(Expr::Accessor(redef.attr)));
if redef.block.len() > 1 {
let name = format!("instant_block_{}__", self.fresh_var_n);
self.fresh_var_n += 1;
let mut code = format!("def {name}():\n");
code += &self.transpile_block(adef.block, Return);
code += &self.transpile_block(redef.block, Return);
self.prelude += &code;
format!("{name}()")
} else {
let expr = adef.block.remove(0);
let expr = redef.block.remove(0);
code += &self.transpile_expr(expr);
code
}