list splatterns!

This commit is contained in:
Scott Richmond 2024-11-18 20:01:27 -05:00
parent 0acad8b312
commit 7a4bf5ff29
2 changed files with 18 additions and 6 deletions

View File

@ -55,7 +55,7 @@ use crate::base::*;
pub fn main() { pub fn main() {
let src = " let src = "
let (x, y, ...z) = (1, 2, 3) let [x, y, ...z] = [1, 2, 3, 4]
z z
"; ";
let (tokens, lex_errs) = lexer().parse(src).into_output_errors(); let (tokens, lex_errs) = lexer().parse(src).into_output_errors();

View File

@ -110,18 +110,30 @@ pub fn match_pattern<'src, 'a>(
Some(ctx) Some(ctx)
} }
(Pattern::List(x), Value::List(y)) => { (Pattern::List(x), Value::List(y)) => {
if x.len() != y.len() { let has_splat = x.iter().any(|patt| {
if let (Pattern::Splattern(_), _) = patt {
true
} else {
false
}
});
if x.len() > y.len() || (!has_splat && x.len() != y.len()) {
return None; return None;
}; };
let to = ctx.len(); let to = ctx.len();
for i in 0..x.len() { for i in 0..x.len() {
if let None = match_pattern(&x[i].0, y.get(i).unwrap(), ctx) { if let Pattern::Splattern(patt) = &x[i].0 {
let list = Value::List(y.skip(i));
match_pattern(&(*patt).0, &list, ctx);
} else {
if let None = match_pattern(&x[i].0, &y.get(i).unwrap(), ctx) {
while ctx.len() > to { while ctx.len() > to {
ctx.pop(); ctx.pop();
} }
return None; return None;
} }
} }
}
Some(ctx) Some(ctx)
} }
(Pattern::Dict(x), Value::Dict(y)) => { (Pattern::Dict(x), Value::Dict(y)) => {