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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1473,10 +1473,11 @@ impl ASTLowerer {
Ok(hir::PatchDef::new(hir_def.sig, base, hir_methods)) Ok(hir::PatchDef::new(hir_def.sig, base, hir_methods))
} }
fn lower_attr_def(&mut self, attr_def: ast::AttrDef) -> LowerResult<hir::AttrDef> { fn lower_redef(&mut self, redef: ast::ReDef) -> LowerResult<hir::ReDef> {
log!(info "entered {}({attr_def})", fn_name!()); log!(info "entered {}({redef})", fn_name!());
let attr = self.lower_acc(attr_def.attr)?; let loc = redef.loc();
let expr = self.lower_expr(*attr_def.expr)?; let attr = self.lower_acc(redef.attr)?;
let expr = self.lower_expr(*redef.expr)?;
if let Err(err) = self.var_result_t_check( if let Err(err) = self.var_result_t_check(
attr.loc(), attr.loc(),
&Str::from(attr.show()), &Str::from(attr.show()),
@ -1485,7 +1486,21 @@ impl ASTLowerer {
) { ) {
self.errs.push(err); 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( fn register_trait_impl(
@ -1960,7 +1975,7 @@ impl ASTLowerer {
ast::Expr::Def(def) => Ok(hir::Expr::Def(self.lower_def(def)?)), 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::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::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)?)), ast::Expr::TypeAsc(tasc) => Ok(hir::Expr::TypeAsc(self.lower_decl(tasc)?)),
other => self.lower_expr(other), other => self.lower_expr(other),
} }

View file

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

View file

@ -3537,12 +3537,12 @@ impl Def {
/// This is not necessary for Erg syntax, but necessary for mapping ASTs in Python /// This is not necessary for Erg syntax, but necessary for mapping ASTs in Python
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct AttrDef { pub struct ReDef {
pub attr: Accessor, pub attr: Accessor,
pub expr: Box<Expr>, pub expr: Box<Expr>,
} }
impl NestedDisplay for AttrDef { impl NestedDisplay for ReDef {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
self.attr.fmt_nest(f, level)?; self.attr.fmt_nest(f, level)?;
writeln!(f, " = ")?; writeln!(f, " = ")?;
@ -3550,10 +3550,10 @@ impl NestedDisplay for AttrDef {
} }
} }
impl_display_from_nested!(AttrDef); impl_display_from_nested!(ReDef);
impl_locational!(AttrDef, attr, expr); impl_locational!(ReDef, attr, expr);
impl AttrDef { impl ReDef {
pub fn new(attr: Accessor, expr: Expr) -> Self { pub fn new(attr: Accessor, expr: Expr) -> Self {
Self { Self {
attr, attr,
@ -3672,14 +3672,14 @@ pub enum Expr {
Methods(Methods), Methods(Methods),
ClassDef(ClassDef), ClassDef(ClassDef),
PatchDef(PatchDef), PatchDef(PatchDef),
AttrDef(AttrDef), ReDef(ReDef),
/// for mapping to Python AST /// for mapping to Python AST
Dummy(Dummy), 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_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 { impl Expr {
pub fn is_match_call(&self) -> bool { 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 erg_common::{enum_unwrap, get_hash, log, set};
use crate::ast::{ use crate::ast::{
Accessor, Args, Array, ArrayComprehension, ArrayTypeSpec, ArrayWithLength, AttrDef, BinOp, Accessor, Args, Array, ArrayComprehension, ArrayTypeSpec, ArrayWithLength, BinOp, Block, Call,
Block, Call, ClassAttr, ClassAttrs, ClassDef, ConstExpr, DataPack, Def, DefBody, DefId, Dict, ClassAttr, ClassAttrs, ClassDef, ConstExpr, DataPack, Def, DefBody, DefId, Dict, Dummy, Expr,
Dummy, Expr, Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal, Methods, Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal, Methods, MixedRecord, Module,
MixedRecord, Module, NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord, NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord, NormalSet, NormalTuple,
NormalSet, NormalTuple, ParamPattern, ParamRecordAttr, Params, PatchDef, PosArg, Record, ParamPattern, ParamRecordAttr, Params, PatchDef, PosArg, ReDef, Record, RecordAttrOrIdent,
RecordAttrOrIdent, RecordAttrs, Set as astSet, SetWithLength, Signature, SubrSignature, Tuple, RecordAttrs, Set as astSet, SetWithLength, Signature, SubrSignature, Tuple, TupleTypeSpec,
TupleTypeSpec, TypeAppArgs, TypeBoundSpecs, TypeSpec, TypeSpecWithOp, UnaryOp, VarName, TypeAppArgs, TypeBoundSpecs, TypeSpec, TypeSpecWithOp, UnaryOp, VarName, VarPattern,
VarPattern, VarRecordAttr, VarSignature, VarRecordAttr, VarSignature,
}; };
use crate::token::{Token, TokenKind, COLON, DOT}; use crate::token::{Token, TokenKind, COLON, DOT};
@ -254,10 +254,10 @@ impl Desugarer {
.collect(); .collect();
Expr::PatchDef(PatchDef::new(def, methods)) Expr::PatchDef(PatchDef::new(def, methods))
} }
Expr::AttrDef(adef) => { Expr::ReDef(redef) => {
let expr = desugar(*adef.expr); let expr = desugar(*redef.expr);
let attr = Self::perform_desugar_acc(desugar, adef.attr); let attr = Self::perform_desugar_acc(desugar, redef.attr);
Expr::AttrDef(AttrDef::new(attr, expr)) Expr::ReDef(ReDef::new(attr, expr))
} }
Expr::Lambda(lambda) => { Expr::Lambda(lambda) => {
let mut chunks = vec![]; let mut chunks = vec![];