chore: add ConstExpr::map

This commit is contained in:
Shunsuke Shibayama 2024-10-04 13:01:30 +09:00
parent 3066781092
commit 7c2d6ac59a
3 changed files with 101 additions and 5 deletions

View file

@ -1899,7 +1899,8 @@ impl Context {
Err((tp, errs)) Err((tp, errs))
} }
} }
other => type_feature_error!( ast::ConstExpr::Dummy(_) => Ok(TyParam::Failure),
other @ ast::ConstExpr::Def(_) => type_feature_error!(
self, self,
other.loc(), other.loc(),
&format!("instantiating const expression {other}") &format!("instantiating const expression {other}")

View file

@ -2180,6 +2180,13 @@ impl ConstAccessor {
Self::Subscr(subscr) => Accessor::Subscr(subscr.downgrade()), Self::Subscr(subscr) => Accessor::Subscr(subscr.downgrade()),
} }
} }
pub fn local_name(&self) -> Option<&str> {
match self {
Self::Local(local) => Some(local.inspect()),
_ => None,
}
}
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -2856,13 +2863,14 @@ pub enum ConstExpr {
BinOp(ConstBinOp), BinOp(ConstBinOp),
UnaryOp(ConstUnaryOp), UnaryOp(ConstUnaryOp),
TypeAsc(ConstTypeAsc), TypeAsc(ConstTypeAsc),
Dummy(Dummy),
} }
impl_nested_display_for_chunk_enum!(ConstExpr; Lit, Accessor, App, List, Set, Dict, Tuple, Record, BinOp, UnaryOp, Def, Lambda, Set, TypeAsc); impl_nested_display_for_chunk_enum!(ConstExpr; Lit, Accessor, App, List, Set, Dict, Tuple, Record, BinOp, UnaryOp, Def, Lambda, Set, TypeAsc, Dummy);
impl_display_from_nested!(ConstExpr); impl_display_from_nested!(ConstExpr);
impl_locational_for_enum!(ConstExpr; Lit, Accessor, App, List, Set, Dict, Tuple, Record, BinOp, UnaryOp, Def, Lambda, Set, TypeAsc); impl_locational_for_enum!(ConstExpr; Lit, Accessor, App, List, Set, Dict, Tuple, Record, BinOp, UnaryOp, Def, Lambda, Set, TypeAsc, Dummy);
impl_into_py_for_enum!(ConstExpr; Lit, Accessor, App, List, Set, Dict, Tuple, Record, Def, Lambda, BinOp, UnaryOp, TypeAsc); impl_into_py_for_enum!(ConstExpr; Lit, Accessor, App, List, Set, Dict, Tuple, Record, Def, Lambda, BinOp, UnaryOp, TypeAsc, Dummy);
impl_from_py_for_enum!(ConstExpr; Lit(Literal), Accessor(ConstAccessor), App(ConstApp), List(ConstList), Set(ConstSet), Dict(ConstDict), Tuple(ConstTuple), Record(ConstRecord), Def(ConstDef), Lambda(ConstLambda), BinOp(ConstBinOp), UnaryOp(ConstUnaryOp), TypeAsc(ConstTypeAsc)); impl_from_py_for_enum!(ConstExpr; Lit(Literal), Accessor(ConstAccessor), App(ConstApp), List(ConstList), Set(ConstSet), Dict(ConstDict), Tuple(ConstTuple), Record(ConstRecord), Def(ConstDef), Lambda(ConstLambda), BinOp(ConstBinOp), UnaryOp(ConstUnaryOp), TypeAsc(ConstTypeAsc), Dummy(Dummy));
impl TryFrom<&ParamPattern> for ConstExpr { impl TryFrom<&ParamPattern> for ConstExpr {
type Error = (); type Error = ();
@ -2904,6 +2912,7 @@ impl ConstExpr {
Self::BinOp(binop) => Expr::BinOp(binop.downgrade()), Self::BinOp(binop) => Expr::BinOp(binop.downgrade()),
Self::UnaryOp(unop) => Expr::UnaryOp(unop.downgrade()), Self::UnaryOp(unop) => Expr::UnaryOp(unop.downgrade()),
Self::TypeAsc(type_asc) => Expr::TypeAscription(type_asc.downgrade()), Self::TypeAsc(type_asc) => Expr::TypeAscription(type_asc.downgrade()),
Self::Dummy(dummy) => Expr::Dummy(dummy),
} }
} }
@ -2922,6 +2931,70 @@ impl ConstExpr {
pub fn call_expr(self, args: ConstArgs) -> Self { pub fn call_expr(self, args: ConstArgs) -> Self {
Self::App(self.call(args)) Self::App(self.call(args))
} }
pub fn local_name(&self) -> Option<&str> {
match self {
Self::Accessor(acc) => acc.local_name(),
Self::TypeAsc(type_asc) => type_asc.expr.local_name(),
_ => None,
}
}
pub fn map(self, mut f: impl FnMut(Self) -> Self) -> Self {
match self {
Self::Accessor(ConstAccessor::Attr(attr)) => {
let obj = f(*attr.obj);
obj.attr_expr(attr.name)
}
Self::BinOp(binop) => {
let lhs = f(*binop.lhs);
let rhs = f(*binop.rhs);
Self::BinOp(ConstBinOp::new(binop.op, lhs, rhs))
}
Self::UnaryOp(unop) => {
let expr = f(*unop.expr);
Self::UnaryOp(ConstUnaryOp::new(unop.op, expr))
}
Self::List(ConstList::Normal(normal)) => {
let elems = normal.elems.map(f);
Self::List(ConstList::Normal(ConstNormalList::new(
normal.l_sqbr,
normal.r_sqbr,
elems,
normal.guard.map(|x| *x),
)))
}
Self::Tuple(tuple) => {
let elems = tuple.elems.map(f);
Self::Tuple(ConstTuple::new(elems))
}
Self::Set(ConstSet::Normal(normal)) => {
let elems = normal.elems.map(f);
Self::Set(ConstSet::Normal(ConstNormalSet::new(
normal.l_brace,
normal.r_brace,
elems,
)))
}
Self::Dict(ConstDict {
l_brace,
r_brace,
kvs,
}) => {
let kvs = kvs
.into_iter()
.map(|kv| ConstKeyValue::new(f(kv.key), f(kv.value)))
.collect();
Self::Dict(ConstDict::new(l_brace, r_brace, kvs))
}
Self::App(app) => {
let obj = f(*app.obj);
let args = app.args.map(f);
Self::App(ConstApp::new(obj, app.attr_name, args))
}
_ => self,
}
}
} }
#[pyclass(get_all, set_all)] #[pyclass(get_all, set_all)]
@ -3108,6 +3181,22 @@ impl ConstArgs {
paren, paren,
) )
} }
pub fn map(self, mut f: impl FnMut(ConstExpr) -> ConstExpr) -> Self {
Self::new(
self.pos_args
.into_iter()
.map(|arg| ConstPosArg::new(f(arg.expr)))
.collect(),
self.var_args.map(|arg| ConstPosArg::new(f(arg.expr))),
self.kw_args
.into_iter()
.map(|arg| ConstKwArg::new(arg.keyword, f(arg.expr)))
.collect(),
self.kw_var.map(|arg| ConstPosArg::new(f(arg.expr))),
self.paren,
)
}
} }
#[pyclass(get_all, set_all)] #[pyclass(get_all, set_all)]

View file

@ -44,6 +44,12 @@ impl From<LexError> for ErrorCore {
} }
} }
impl LexError {
pub fn loc(&self) -> Location {
self.0.loc
}
}
#[cfg_attr(feature = "pylib", pyo3::pyclass)] #[cfg_attr(feature = "pylib", pyo3::pyclass)]
#[derive(Debug)] #[derive(Debug)]
pub struct LexErrors(Vec<LexError>); pub struct LexErrors(Vec<LexError>);