diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index c039aed8..4db12b40 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -1476,6 +1476,61 @@ impl Locational for Block { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Dummy(Vec); + +impl HasType for Dummy { + #[inline] + fn ref_t(&self) -> &Type { + Type::FAILURE + } + #[inline] + fn ref_mut_t(&mut self) -> &mut Type { + todo!() + } + #[inline] + fn t(&self) -> Type { + Type::Failure + } + #[inline] + fn signature_t(&self) -> Option<&Type> { + Some(Type::FAILURE) + } + #[inline] + fn signature_mut_t(&mut self) -> Option<&mut Type> { + todo!() + } +} + +impl NestedDisplay for Dummy { + fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { + fmt_lines(self.0.iter(), f, level) + } +} + +impl NoTypeDisplay for Dummy { + fn to_string_notype(&self) -> String { + self.0 + .iter() + .map(|e| e.to_string_notype()) + .collect::>() + .join("; ") + } +} + +impl_display_from_nested!(Dummy); +impl_stream_for_wrapper!(Dummy, Expr); + +impl Locational for Dummy { + fn loc(&self) -> Location { + if self.0.is_empty() { + Location::Unknown + } else { + Location::concat(self.0.first().unwrap(), self.0.last().unwrap()) + } + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct VarSignature { pub ident: Identifier, @@ -2231,7 +2286,7 @@ pub enum Expr { Code(Block), // code object Compound(Block), // compound statement Import(Accessor), - Dummy(Block), // 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); diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index a907314b..dfc94abb 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -1771,7 +1771,7 @@ impl ASTLowerer { ast::Expr::AttrDef(adef) => Ok(hir::Expr::AttrDef(self.lower_attr_def(adef)?)), ast::Expr::TypeAsc(tasc) => Ok(hir::Expr::TypeAsc(self.lower_type_asc(tasc)?)), // Checking is also performed for expressions in Dummy. However, it has no meaning in code generation - ast::Expr::Dummy(dummy) => Ok(hir::Expr::Dummy(self.lower_block(dummy)?)), + ast::Expr::Dummy(dummy) => Ok(hir::Expr::Dummy(self.lower_dummy(dummy)?)), other => todo!("{other}"), } } @@ -1786,6 +1786,16 @@ impl ASTLowerer { Ok(hir::Block::new(hir_block)) } + fn lower_dummy(&mut self, ast_dummy: ast::Dummy) -> LowerResult { + log!(info "entered {}", fn_name!()); + let mut hir_dummy = Vec::with_capacity(ast_dummy.len()); + for chunk in ast_dummy.into_iter() { + let chunk = self.lower_expr(chunk)?; + hir_dummy.push(chunk); + } + Ok(hir::Dummy::new(hir_dummy)) + } + fn declare_or_import_var( &mut self, sig: ast::VarSignature, diff --git a/compiler/erg_parser/ast.rs b/compiler/erg_parser/ast.rs index 013a97bc..f758cb08 100644 --- a/compiler/erg_parser/ast.rs +++ b/compiler/erg_parser/ast.rs @@ -1166,6 +1166,29 @@ impl Locational for Block { impl_stream_for_wrapper!(Block, Expr); +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Dummy(Vec); + +impl NestedDisplay for Dummy { + fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { + fmt_lines(self.0.iter(), f, level) + } +} + +impl_display_from_nested!(Dummy); + +impl Locational for Dummy { + fn loc(&self) -> Location { + if self.0.is_empty() { + Location::Unknown + } else { + Location::concat(self.0.first().unwrap(), self.0.last().unwrap()) + } + } +} + +impl_stream_for_wrapper!(Dummy, Expr); + #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct ConstLocal { pub symbol: Token, @@ -3532,7 +3555,7 @@ pub enum Expr { PatchDef(PatchDef), AttrDef(AttrDef), /// for mapping to Python AST - Dummy(Block), + 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); diff --git a/compiler/erg_parser/desugar.rs b/compiler/erg_parser/desugar.rs index fcf21a71..8ce04c03 100644 --- a/compiler/erg_parser/desugar.rs +++ b/compiler/erg_parser/desugar.rs @@ -14,9 +14,9 @@ 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, - Expr, Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal, Methods, MixedRecord, - Module, NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord, NormalSet, - NormalTuple, ParamPattern, ParamRecordAttr, Params, PatchDef, PosArg, Record, + 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, @@ -301,7 +301,7 @@ impl Desugarer { for chunk in exprs.into_iter() { chunks.push(desugar(chunk)); } - Expr::Dummy(Block::new(chunks)) + Expr::Dummy(Dummy::new(chunks)) } } }