mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-02 21:44:34 +00:00
Add ast::AttrDef
This commit is contained in:
parent
f1ff0d1ddf
commit
2e60d8c885
3 changed files with 83 additions and 33 deletions
|
@ -1368,6 +1368,21 @@ 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)?;
|
||||
if let Err(err) = self.var_result_t_check(
|
||||
attr.loc(),
|
||||
&Str::from(attr.show()),
|
||||
attr.ref_t(),
|
||||
expr.ref_t(),
|
||||
) {
|
||||
self.errs.push(err);
|
||||
}
|
||||
Ok(hir::AttrDef::new(attr, hir::Block::new(vec![expr])))
|
||||
}
|
||||
|
||||
fn register_trait_impl(
|
||||
&mut self,
|
||||
class: &Type,
|
||||
|
@ -1748,6 +1763,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::TypeAsc(tasc) => Ok(hir::Expr::TypeAsc(self.lower_type_asc(tasc)?)),
|
||||
other => todo!("{other}"),
|
||||
}
|
||||
|
|
|
@ -3385,6 +3385,33 @@ 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 attr: Accessor,
|
||||
pub expr: Box<Expr>,
|
||||
}
|
||||
|
||||
impl NestedDisplay for AttrDef {
|
||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
|
||||
self.attr.fmt_nest(f, level)?;
|
||||
writeln!(f, " = ")?;
|
||||
self.expr.fmt_nest(f, level + 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl_display_from_nested!(AttrDef);
|
||||
impl_locational!(AttrDef, attr, expr);
|
||||
|
||||
impl AttrDef {
|
||||
pub fn new(attr: Accessor, expr: Expr) -> Self {
|
||||
Self {
|
||||
attr,
|
||||
expr: Box::new(expr),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// e.g.
|
||||
/// ```python
|
||||
/// T = Class ...
|
||||
|
@ -3495,11 +3522,12 @@ pub enum Expr {
|
|||
Methods(Methods),
|
||||
ClassDef(ClassDef),
|
||||
PatchDef(PatchDef),
|
||||
AttrDef(AttrDef),
|
||||
}
|
||||
|
||||
impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAsc, Def, Methods, ClassDef, PatchDef);
|
||||
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);
|
||||
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);
|
||||
impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAsc, Def, Methods, ClassDef, PatchDef, AttrDef);
|
||||
|
||||
impl Expr {
|
||||
pub fn is_match_call(&self) -> bool {
|
||||
|
|
|
@ -12,14 +12,14 @@ use erg_common::Str;
|
|||
use erg_common::{enum_unwrap, get_hash, log, set};
|
||||
|
||||
use crate::ast::{
|
||||
Accessor, Args, Array, ArrayComprehension, ArrayTypeSpec, ArrayWithLength, 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, 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, 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,
|
||||
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};
|
||||
|
||||
|
@ -73,6 +73,29 @@ impl Desugarer {
|
|||
Args::new(pos_args, kw_args, paren)
|
||||
}
|
||||
|
||||
fn perform_desugar_acc(mut desugar: impl FnMut(Expr) -> Expr, acc: Accessor) -> Accessor {
|
||||
match acc {
|
||||
Accessor::Ident(ident) => Accessor::Ident(ident),
|
||||
Accessor::Attr(attr) => desugar(*attr.obj).attr(attr.ident),
|
||||
Accessor::TupleAttr(tup) => {
|
||||
let obj = desugar(*tup.obj);
|
||||
obj.tuple_attr(tup.index)
|
||||
}
|
||||
Accessor::Subscr(sub) => {
|
||||
let obj = desugar(*sub.obj);
|
||||
let index = desugar(*sub.index);
|
||||
obj.subscr(index, sub.r_sqbr)
|
||||
}
|
||||
Accessor::TypeApp(tapp) => {
|
||||
let obj = desugar(*tapp.obj);
|
||||
let args = Self::desugar_args(desugar, tapp.type_args.args);
|
||||
let type_args =
|
||||
TypeAppArgs::new(tapp.type_args.l_vbar, args, tapp.type_args.r_vbar);
|
||||
obj.type_app(type_args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn perform_desugar(mut desugar: impl FnMut(Expr) -> Expr, expr: Expr) -> Expr {
|
||||
match expr {
|
||||
Expr::Lit(_) => expr,
|
||||
|
@ -234,6 +257,11 @@ 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::Lambda(lambda) => {
|
||||
let mut chunks = vec![];
|
||||
for chunk in lambda.body.into_iter() {
|
||||
|
@ -267,29 +295,7 @@ impl Desugarer {
|
|||
let new_attrs = ClassAttrs::from(new_attrs);
|
||||
Expr::Methods(Methods::new(method_defs.class, method_defs.vis, new_attrs))
|
||||
}
|
||||
Expr::Accessor(acc) => {
|
||||
let acc = match acc {
|
||||
Accessor::Ident(ident) => Accessor::Ident(ident),
|
||||
Accessor::Attr(attr) => desugar(*attr.obj).attr(attr.ident),
|
||||
Accessor::TupleAttr(tup) => {
|
||||
let obj = desugar(*tup.obj);
|
||||
obj.tuple_attr(tup.index)
|
||||
}
|
||||
Accessor::Subscr(sub) => {
|
||||
let obj = desugar(*sub.obj);
|
||||
let index = desugar(*sub.index);
|
||||
obj.subscr(index, sub.r_sqbr)
|
||||
}
|
||||
Accessor::TypeApp(tapp) => {
|
||||
let obj = desugar(*tapp.obj);
|
||||
let args = Self::desugar_args(desugar, tapp.type_args.args);
|
||||
let type_args =
|
||||
TypeAppArgs::new(tapp.type_args.l_vbar, args, tapp.type_args.r_vbar);
|
||||
obj.type_app(type_args)
|
||||
}
|
||||
};
|
||||
Expr::Accessor(acc)
|
||||
}
|
||||
Expr::Accessor(acc) => Expr::Accessor(Self::perform_desugar_acc(desugar, acc)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue