update list pattern compiling to reflect new jump logic

This commit is contained in:
Scott Richmond 2025-06-18 14:52:15 -04:00
parent a5f2e2a9bd
commit 6bd419125f

View File

@ -747,7 +747,6 @@ impl<'a> Compiler<'a> {
} }
// if we get here--not having jumped on no match--we're matched; jump the "no match" code // if we get here--not having jumped on no match--we're matched; jump the "no match" code
self.match_depth = match_depth + members.len();
let jump_idx = self.jump_stub(Op::Jump); let jump_idx = self.jump_stub(Op::Jump);
// patch up the previous no match jumps to jump to clean-up code // patch up the previous no match jumps to jump to clean-up code
@ -766,38 +765,46 @@ impl<'a> Compiler<'a> {
// patch up the yes-matches unconditional jump // patch up the yes-matches unconditional jump
self.patch_jump(jump_idx, self.len() - jump_idx - 3); self.patch_jump(jump_idx, self.len() - jump_idx - 3);
// finally, for any further matches (e.g. nested lists/tuples)
// add increase the match depth, since we've added a bunch
// of bindings to the stack
self.match_depth = match_depth + members.len();
} }
ListPattern(members) => { ListPattern(members) => {
self.emit_op(Op::MatchList); self.emit_op(Op::MatchList);
self.emit_byte(members.len()); self.emit_byte(members.len());
self.emit_op(Op::JumpIfNoMatch); let before_load_tup_idx = self.jump_stub(Op::JumpIfNoMatch);
let before_load_list_idx = self.len();
self.emit_byte(0xff);
let mut jump_idxes = vec![]; let mut jump_idxes = vec![];
self.match_depth += members.len(); let match_depth = self.match_depth;
self.match_depth = members.len();
self.emit_op(Op::LoadList); self.emit_op(Op::LoadList);
self.stack_depth += members.len(); self.stack_depth += members.len();
for member in members { for member in members {
self.match_depth -= 1; self.match_depth -= 1;
self.emit_op(Op::MatchDepth); self.emit_op(Op::MatchDepth);
self.emit_byte(self.match_depth); self.emit_byte(self.match_depth);
self.visit(member); self.visit(member);
self.emit_op(Op::JumpIfNoMatch); jump_idxes.push(self.jump_stub(Op::JumpIfNoMatch));
jump_idxes.push(self.len());
self.emit_byte(0xff);
} }
self.emit_op(Op::Jump);
let jump_idx = self.len(); let jump_idx = self.jump_stub(Op::Jump);
self.emit_byte(0xff);
for idx in jump_idxes { for idx in jump_idxes {
self.chunk.bytecode[idx] = (self.len() - idx) as u8 - 1; self.patch_jump(idx, self.len() - idx - 2)
} }
for _ in 0..members.len() {
self.emit_op(Op::Pop); self.emit_op(Op::PopN);
} self.emit_byte(members.len());
self.chunk.bytecode[before_load_list_idx] =
(self.len() - before_load_list_idx) as u8 - 1; self.patch_jump(before_load_tup_idx, self.len() - before_load_tup_idx - 3);
self.chunk.bytecode[jump_idx] = (self.len() - jump_idx) as u8 - 1;
self.patch_jump(jump_idx, self.len() - jump_idx - 3);
self.match_depth = match_depth + members.len();
} }
DictPattern(pairs) => { DictPattern(pairs) => {
self.emit_op(Op::MatchDict); self.emit_op(Op::MatchDict);