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
}

View file

@ -3537,12 +3537,12 @@ impl Def {
/// This is not necessary for Erg syntax, but necessary for mapping ASTs in Python
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct AttrDef {
pub struct ReDef {
pub attr: Accessor,
pub expr: Box<Expr>,
}
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, " = ")?;
@ -3550,10 +3550,10 @@ impl NestedDisplay for AttrDef {
}
}
impl_display_from_nested!(AttrDef);
impl_locational!(AttrDef, attr, expr);
impl_display_from_nested!(ReDef);
impl_locational!(ReDef, attr, expr);
impl AttrDef {
impl ReDef {
pub fn new(attr: Accessor, expr: Expr) -> Self {
Self {
attr,
@ -3672,14 +3672,14 @@ pub enum Expr {
Methods(Methods),
ClassDef(ClassDef),
PatchDef(PatchDef),
AttrDef(AttrDef),
ReDef(ReDef),
/// for mapping to Python AST
Dummy(Dummy),
}
impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAsc, Def, Methods, ClassDef, PatchDef, AttrDef, Dummy);
impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAsc, Def, Methods, ClassDef, PatchDef, ReDef, Dummy);
impl_display_from_nested!(Expr);
impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAsc, Def, Methods, ClassDef, PatchDef, AttrDef, Dummy);
impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAsc, Def, Methods, ClassDef, PatchDef, ReDef, Dummy);
impl Expr {
pub fn is_match_call(&self) -> bool {

View file

@ -9,14 +9,14 @@ use erg_common::Str;
use erg_common::{enum_unwrap, get_hash, log, set};
use crate::ast::{
Accessor, Args, Array, ArrayComprehension, ArrayTypeSpec, ArrayWithLength, AttrDef, BinOp,
Block, Call, ClassAttr, ClassAttrs, ClassDef, ConstExpr, DataPack, Def, DefBody, DefId, Dict,
Dummy, Expr, Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal, Methods,
MixedRecord, Module, NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord,
NormalSet, NormalTuple, ParamPattern, ParamRecordAttr, Params, PatchDef, PosArg, Record,
RecordAttrOrIdent, RecordAttrs, Set as astSet, SetWithLength, Signature, SubrSignature, Tuple,
TupleTypeSpec, TypeAppArgs, TypeBoundSpecs, TypeSpec, TypeSpecWithOp, UnaryOp, VarName,
VarPattern, VarRecordAttr, VarSignature,
Accessor, Args, Array, ArrayComprehension, ArrayTypeSpec, ArrayWithLength, BinOp, Block, Call,
ClassAttr, ClassAttrs, ClassDef, ConstExpr, DataPack, Def, DefBody, DefId, Dict, Dummy, Expr,
Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal, Methods, MixedRecord, Module,
NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord, NormalSet, NormalTuple,
ParamPattern, ParamRecordAttr, Params, PatchDef, PosArg, ReDef, Record, RecordAttrOrIdent,
RecordAttrs, Set as astSet, SetWithLength, Signature, SubrSignature, Tuple, TupleTypeSpec,
TypeAppArgs, TypeBoundSpecs, TypeSpec, TypeSpecWithOp, UnaryOp, VarName, VarPattern,
VarRecordAttr, VarSignature,
};
use crate::token::{Token, TokenKind, COLON, DOT};
@ -254,10 +254,10 @@ impl Desugarer {
.collect();
Expr::PatchDef(PatchDef::new(def, methods))
}
Expr::AttrDef(adef) => {
let expr = desugar(*adef.expr);
let attr = Self::perform_desugar_acc(desugar, adef.attr);
Expr::AttrDef(AttrDef::new(attr, expr))
Expr::ReDef(redef) => {
let expr = desugar(*redef.expr);
let attr = Self::perform_desugar_acc(desugar, redef.attr);
Expr::ReDef(ReDef::new(attr, expr))
}
Expr::Lambda(lambda) => {
let mut chunks = vec![];