diff --git a/src/compiler.rs b/src/compiler.rs index 87a6910..656de41 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -42,6 +42,7 @@ pub enum Op { PushTuple, LoadTuple, MatchList, + MatchSplattedList, LoadList, PushList, AppendList, @@ -162,6 +163,7 @@ impl std::fmt::Display for Op { PushTuple => "push_tuple", LoadTuple => "load_tuple", MatchList => "match_list", + MatchSplattedList => "match_splatted_list", LoadList => "load_list", PushList => "push_list", AppendList => "append_list", @@ -260,9 +262,9 @@ impl Chunk { println!("{i:04}: {:16} {next:03}: {value}", op.to_string()); *i += 1; } - PushBinding | MatchTuple | MatchList | MatchDict | LoadDictValue | PushTuple - | PushBox | MatchDepth | PopN | StoreAt | Call | SetUpvalue | GetUpvalue | Partial - | MatchString | PushStringMatches => { + PushBinding | MatchTuple | MatchList | MatchSplattedList | MatchDict + | LoadDictValue | PushTuple | PushBox | MatchDepth | PopN | StoreAt | Call + | SetUpvalue | GetUpvalue | Partial | MatchString | PushStringMatches => { let next = self.bytecode[*i + 1]; println!("{i:04}: {:16} {next:03}", op.to_string()); *i += 1; @@ -778,7 +780,12 @@ impl<'a> Compiler<'a> { self.match_depth = match_depth + members.len(); } ListPattern(members) => { - self.emit_op(Op::MatchList); + if let Some((Splattern(patt), _)) = members.last() { + self.emit_op(Op::MatchSplattedList) + } else { + self.emit_op(Op::MatchList); + } + // TODO: lists must be able to be longer than 256 elements; fix this self.emit_byte(members.len()); let before_load_tup_idx = self.stub_jump(Op::JumpIfNoMatch); diff --git a/src/main.rs b/src/main.rs index fb8ed5a..3930268 100644 --- a/src/main.rs +++ b/src/main.rs @@ -75,14 +75,7 @@ pub fn run(src: &'static str) { pub fn main() { env::set_var("RUST_BACKTRACE", "1"); let src = " -let foo = loop (1, 2, 3) with { - (0, 0, 1) -> :done - (1, 2, 3) -> recur (4, 5, 6) - (4, 5, 6) -> recur (:foo, :bar, :baz) - (:foo, :bar, :baz) -> recur (0, 0, 0) -} - -(foo, 42) - "; +let [] = [] +"; run(src); } diff --git a/src/vm.rs b/src/vm.rs index 503e63b..ad8c391 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -466,6 +466,9 @@ impl Vm { }; self.ip += 2; } + MatchSplattedList => { + todo!() + } LoadList => { let idx = self.stack.len() - self.match_depth as usize - 1; let tuple = self.stack[idx].clone();