list splatterns!
This commit is contained in:
parent
0acad8b312
commit
7a4bf5ff29
|
@ -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();
|
||||||
|
|
16
src/vm.rs
16
src/vm.rs
|
@ -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)) => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user