mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
fix: array pattern matching
This commit is contained in:
parent
5a6cea0df1
commit
952e6ccd2e
5 changed files with 121 additions and 2 deletions
|
@ -290,6 +290,13 @@ impl PyCodeGenerator {
|
|||
self.cur_block().lasti
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
fn debug_print(&mut self, value: impl Into<ValueObj>) {
|
||||
self.emit_load_const(value);
|
||||
self.emit_print_expr();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
fn emit_print_expr(&mut self) {
|
||||
|
|
|
@ -252,8 +252,8 @@ impl ASTLowerer {
|
|||
arr.l_sqbr,
|
||||
arr.r_sqbr,
|
||||
Type::Failure,
|
||||
len,
|
||||
elem,
|
||||
len,
|
||||
)))
|
||||
}
|
||||
ast::Array::Normal(arr) => {
|
||||
|
|
|
@ -2128,6 +2128,21 @@ impl_nested_display_for_chunk_enum!(ConstExpr; Lit, Accessor, App, Array, Set, D
|
|||
impl_display_from_nested!(ConstExpr);
|
||||
impl_locational_for_enum!(ConstExpr; Lit, Accessor, App, Array, Set, Dict, Tuple, Record, BinOp, UnaryOp, Def, Lambda, Set, TypeAsc);
|
||||
|
||||
impl TryFrom<&ParamPattern> for ConstExpr {
|
||||
type Error = ();
|
||||
fn try_from(value: &ParamPattern) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
ParamPattern::VarName(name) => {
|
||||
Ok(ConstExpr::Accessor(ConstAccessor::local(name.0.clone())))
|
||||
}
|
||||
ParamPattern::Lit(lit) => Ok(ConstExpr::Lit(lit.clone())),
|
||||
ParamPattern::Array(array) => ConstExpr::try_from(array),
|
||||
ParamPattern::Tuple(tuple) => ConstExpr::try_from(tuple),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConstExpr {
|
||||
pub fn need_to_be_closed(&self) -> bool {
|
||||
match self {
|
||||
|
@ -2249,6 +2264,10 @@ impl ConstArgs {
|
|||
Self::new(pos_args, None, vec![], paren)
|
||||
}
|
||||
|
||||
pub fn single(expr: ConstExpr) -> Self {
|
||||
Self::pos_only(vec![ConstPosArg::new(expr)], None)
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn deconstruct(
|
||||
self,
|
||||
|
@ -3691,6 +3710,41 @@ impl NestedDisplay for ParamArrayPattern {
|
|||
impl_display_from_nested!(ParamArrayPattern);
|
||||
impl_locational!(ParamArrayPattern, l_sqbr, r_sqbr);
|
||||
|
||||
impl TryFrom<&ParamArrayPattern> for Expr {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: &ParamArrayPattern) -> Result<Self, Self::Error> {
|
||||
let mut new = vec![];
|
||||
for elem in value.elems.non_defaults.iter() {
|
||||
new.push(PosArg::new(Expr::try_from(&elem.pat)?));
|
||||
}
|
||||
let elems = Args::pos_only(new, None);
|
||||
Ok(Expr::Array(Array::Normal(NormalArray::new(
|
||||
value.l_sqbr.clone(),
|
||||
value.r_sqbr.clone(),
|
||||
elems,
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&ParamArrayPattern> for ConstExpr {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: &ParamArrayPattern) -> Result<Self, Self::Error> {
|
||||
let mut new = vec![];
|
||||
for elem in value.elems.non_defaults.iter() {
|
||||
new.push(ConstPosArg::new(ConstExpr::try_from(&elem.pat)?));
|
||||
}
|
||||
let elems = ConstArgs::pos_only(new, None);
|
||||
Ok(ConstExpr::Array(ConstArray::Normal(ConstNormalArray::new(
|
||||
value.l_sqbr.clone(),
|
||||
value.r_sqbr.clone(),
|
||||
elems,
|
||||
None,
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
||||
impl ParamArrayPattern {
|
||||
pub const fn new(l_sqbr: Token, elems: Params, r_sqbr: Token) -> Self {
|
||||
Self {
|
||||
|
@ -3722,6 +3776,32 @@ impl NestedDisplay for ParamTuplePattern {
|
|||
impl_display_from_nested!(ParamTuplePattern);
|
||||
impl_locational!(ParamTuplePattern, elems);
|
||||
|
||||
impl TryFrom<&ParamTuplePattern> for Expr {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: &ParamTuplePattern) -> Result<Self, Self::Error> {
|
||||
let mut new = vec![];
|
||||
for elem in value.elems.non_defaults.iter() {
|
||||
new.push(PosArg::new(Expr::try_from(&elem.pat)?));
|
||||
}
|
||||
let elems = Args::pos_only(new, value.elems.parens.clone());
|
||||
Ok(Expr::Tuple(Tuple::Normal(NormalTuple::new(elems))))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&ParamTuplePattern> for ConstExpr {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: &ParamTuplePattern) -> Result<Self, Self::Error> {
|
||||
let mut new = vec![];
|
||||
for elem in value.elems.non_defaults.iter() {
|
||||
new.push(ConstPosArg::new(ConstExpr::try_from(&elem.pat)?));
|
||||
}
|
||||
let elems = ConstArgs::pos_only(new, value.elems.parens.clone());
|
||||
Ok(ConstExpr::Tuple(ConstTuple::new(elems)))
|
||||
}
|
||||
}
|
||||
|
||||
impl ParamTuplePattern {
|
||||
pub const fn new(elems: Params) -> Self {
|
||||
Self { elems }
|
||||
|
@ -3829,6 +3909,20 @@ impl NestedDisplay for ParamPattern {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&ParamPattern> for Expr {
|
||||
type Error = ();
|
||||
fn try_from(value: &ParamPattern) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
// ParamPattern::Discard(token) => Ok(Expr::Accessor(Accessor::local(token.clone()))),
|
||||
ParamPattern::VarName(name) => Ok(Expr::Accessor(Accessor::local(name.0.clone()))),
|
||||
ParamPattern::Lit(lit) => Ok(Expr::Literal(lit.clone())),
|
||||
ParamPattern::Array(array) => Expr::try_from(array),
|
||||
ParamPattern::Tuple(tuple) => Expr::try_from(tuple),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_display_from_nested!(ParamPattern);
|
||||
impl_locational_for_enum!(ParamPattern; Discard, VarName, Lit, Array, Tuple, Record, Ref, RefMut);
|
||||
|
||||
|
|
|
@ -1068,6 +1068,7 @@ impl Desugarer {
|
|||
param.pat = buf_param;
|
||||
}
|
||||
ParamPattern::Array(arr) => {
|
||||
let expr = Expr::try_from(&*arr);
|
||||
let (buf_name, buf_param) = self.gen_buf_nd_param(arr.loc());
|
||||
for (n, elem) in arr.elems.non_defaults.iter_mut().enumerate() {
|
||||
insertion_idx = self.desugar_nested_param_pattern(
|
||||
|
@ -1093,7 +1094,17 @@ impl Desugarer {
|
|||
ConstExpr::Lit(len.clone()),
|
||||
Some((arr.l_sqbr.clone(), arr.r_sqbr.clone())),
|
||||
);
|
||||
let t_spec_as_expr = Self::dummy_array_expr(len);
|
||||
// [1, 2] -> ...
|
||||
// => _: {[1, 2]} -> ...
|
||||
let t_spec_as_expr = if let Ok(expr) = expr {
|
||||
Expr::Set(astSet::Normal(NormalSet::new(
|
||||
Token::DUMMY,
|
||||
Token::DUMMY,
|
||||
Args::single(PosArg::new(expr)),
|
||||
)))
|
||||
} else {
|
||||
Self::dummy_array_expr(len)
|
||||
};
|
||||
param.t_spec = Some(TypeSpecWithOp::new(
|
||||
Token::dummy(TokenKind::Colon, ":"),
|
||||
TypeSpec::Array(t_spec),
|
||||
|
|
|
@ -51,6 +51,13 @@ match! k:
|
|||
0 => print! "zero"
|
||||
_ => print! "\{k}"
|
||||
|
||||
ab = match ["a", "b"]:
|
||||
["a", "a"] -> "aa"
|
||||
["b", "a"] -> "ba"
|
||||
["a", "b"] -> "ab"
|
||||
[_, _] -> "other"
|
||||
assert ab == "ab"
|
||||
|
||||
arrs = [[0, 1], [2, 3]]
|
||||
|
||||
for! arrs, arr =>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue