diff --git a/src/compiler.rs b/src/compiler.rs index 59ac133..8e028d1 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -783,7 +783,7 @@ impl<'a> Compiler<'a> { } ListPattern(members) => { let mut is_splatted = false; - if let Some((Splattern(patt), _)) = members.last() { + if let Some((Splattern(_), _)) = members.last() { is_splatted = true; self.emit_op(Op::MatchSplattedList) } else { @@ -799,6 +799,7 @@ impl<'a> Compiler<'a> { if is_splatted { self.emit_op(Op::LoadSplattedList); + self.emit_byte(members.len()); } else { self.emit_op(Op::LoadList); } @@ -856,8 +857,8 @@ impl<'a> Compiler<'a> { self.patch_jump(before_load_dict_idx, self.len() - before_load_dict_idx - 3); self.patch_jump(jump_idx, self.len() - jump_idx - 3); } - Splattern(..) => { - todo!() + Splattern(patt) => { + self.visit(patt); } InterpolatedPattern(parts, _) => { println!("An interpolated pattern of {} parts", parts.len()); diff --git a/src/main.rs b/src/main.rs index 3930268..9245bd7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -75,7 +75,8 @@ pub fn run(src: &'static str) { pub fn main() { env::set_var("RUST_BACKTRACE", "1"); let src = " -let [] = [] +let [x, ...y] = [1, 2, 3, 4, 5] +y "; run(src); } diff --git a/src/vm.rs b/src/vm.rs index 2552ac6..e67b3af 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -458,16 +458,23 @@ impl Vm { } MatchList => { let idx = self.stack.len() - self.match_depth as usize - 1; - let tuple_len = self.chunk().bytecode[self.ip + 1]; + let list_len = self.chunk().bytecode[self.ip + 1]; let scrutinee = self.stack[idx].clone(); match scrutinee { - Value::List(members) => self.matches = members.len() == tuple_len as usize, + Value::List(members) => self.matches = members.len() == list_len as usize, _ => self.matches = false, }; self.ip += 2; } MatchSplattedList => { - todo!() + let idx = self.stack.len() - self.match_depth as usize - 1; + let patt_len = self.chunk().bytecode[self.ip + 1]; + let scrutinee = self.stack[idx].clone(); + match scrutinee { + Value::List(members) => self.matches = members.len() >= patt_len as usize, + _ => self.matches = false, + } + self.ip += 2; } LoadList => { let idx = self.stack.len() - self.match_depth as usize - 1; @@ -495,7 +502,6 @@ impl Vm { let splatted = Value::List(Box::new(members.skip(loaded_len - 1))); self.push(splatted); self.ip += 2; - todo!() } // PushDict => { // let dict_len = self.chunk().bytecode[self.ip + 1] as usize * 2;