add match splatted list opcode
This commit is contained in:
parent
647f3d4463
commit
4871dbd048
|
@ -42,6 +42,7 @@ pub enum Op {
|
||||||
PushTuple,
|
PushTuple,
|
||||||
LoadTuple,
|
LoadTuple,
|
||||||
MatchList,
|
MatchList,
|
||||||
|
MatchSplattedList,
|
||||||
LoadList,
|
LoadList,
|
||||||
PushList,
|
PushList,
|
||||||
AppendList,
|
AppendList,
|
||||||
|
@ -162,6 +163,7 @@ impl std::fmt::Display for Op {
|
||||||
PushTuple => "push_tuple",
|
PushTuple => "push_tuple",
|
||||||
LoadTuple => "load_tuple",
|
LoadTuple => "load_tuple",
|
||||||
MatchList => "match_list",
|
MatchList => "match_list",
|
||||||
|
MatchSplattedList => "match_splatted_list",
|
||||||
LoadList => "load_list",
|
LoadList => "load_list",
|
||||||
PushList => "push_list",
|
PushList => "push_list",
|
||||||
AppendList => "append_list",
|
AppendList => "append_list",
|
||||||
|
@ -260,9 +262,9 @@ impl Chunk {
|
||||||
println!("{i:04}: {:16} {next:03}: {value}", op.to_string());
|
println!("{i:04}: {:16} {next:03}: {value}", op.to_string());
|
||||||
*i += 1;
|
*i += 1;
|
||||||
}
|
}
|
||||||
PushBinding | MatchTuple | MatchList | MatchDict | LoadDictValue | PushTuple
|
PushBinding | MatchTuple | MatchList | MatchSplattedList | MatchDict
|
||||||
| PushBox | MatchDepth | PopN | StoreAt | Call | SetUpvalue | GetUpvalue | Partial
|
| LoadDictValue | PushTuple | PushBox | MatchDepth | PopN | StoreAt | Call
|
||||||
| MatchString | PushStringMatches => {
|
| SetUpvalue | GetUpvalue | Partial | MatchString | PushStringMatches => {
|
||||||
let next = self.bytecode[*i + 1];
|
let next = self.bytecode[*i + 1];
|
||||||
println!("{i:04}: {:16} {next:03}", op.to_string());
|
println!("{i:04}: {:16} {next:03}", op.to_string());
|
||||||
*i += 1;
|
*i += 1;
|
||||||
|
@ -778,7 +780,12 @@ impl<'a> Compiler<'a> {
|
||||||
self.match_depth = match_depth + members.len();
|
self.match_depth = match_depth + members.len();
|
||||||
}
|
}
|
||||||
ListPattern(members) => {
|
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());
|
self.emit_byte(members.len());
|
||||||
let before_load_tup_idx = self.stub_jump(Op::JumpIfNoMatch);
|
let before_load_tup_idx = self.stub_jump(Op::JumpIfNoMatch);
|
||||||
|
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -75,14 +75,7 @@ pub fn run(src: &'static str) {
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
env::set_var("RUST_BACKTRACE", "1");
|
env::set_var("RUST_BACKTRACE", "1");
|
||||||
let src = "
|
let src = "
|
||||||
let foo = loop (1, 2, 3) with {
|
let [] = []
|
||||||
(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)
|
|
||||||
";
|
|
||||||
run(src);
|
run(src);
|
||||||
}
|
}
|
||||||
|
|
|
@ -466,6 +466,9 @@ impl Vm {
|
||||||
};
|
};
|
||||||
self.ip += 2;
|
self.ip += 2;
|
||||||
}
|
}
|
||||||
|
MatchSplattedList => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
LoadList => {
|
LoadList => {
|
||||||
let idx = self.stack.len() - self.match_depth as usize - 1;
|
let idx = self.stack.len() - self.match_depth as usize - 1;
|
||||||
let tuple = self.stack[idx].clone();
|
let tuple = self.stack[idx].clone();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user