Skip to content

Commit be4df5d

Browse files
committed
implement SWAP instruction
Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
1 parent 4a73f90 commit be4df5d

File tree

3 files changed

+28
-24
lines changed

3 files changed

+28
-24
lines changed

compiler/codegen/src/compile.rs

+20-24
Original file line numberDiff line numberDiff line change
@@ -217,31 +217,29 @@ macro_rules! emit {
217217
}
218218

219219
struct PatternContext {
220-
// // A list of strings corresponding to name captures. It is used to track:
221-
// // - Repeated name assignments in the same pattern.
222-
// // - Different name assignments in alternatives.
223-
// // - The order of name assignments in alternatives.
224-
// PyObject *stores;
225-
// // If 0, any name captures against our subject will raise.
226-
// int allow_irrefutable;
227-
// // An array of blocks to jump to on failure. Jumping to fail_pop[i] will pop
228-
// // i items off of the stack. The end result looks like this (with each block
229-
// // falling through to the next):
230-
// // fail_pop[4]: POP_TOP
231-
// // fail_pop[3]: POP_TOP
232-
// // fail_pop[2]: POP_TOP
233-
// // fail_pop[1]: POP_TOP
234-
// // fail_pop[0]: NOP
235-
// jump_target_label *fail_pop;
236220
// // The current length of fail_pop.
237221
// Py_ssize_t fail_pop_size;
238-
// // The number of items on top of the stack that need to *stay* on top of the
239-
// // stack. Variable captures go beneath these. All of them will be popped on
240-
// // failure.
241-
// Py_ssize_t on_top;
222+
223+
/// Py_ssize_t on_top;
224+
/// A list of strings corresponding to name captures. It is used to track:
225+
/// - Repeated name assignments in the same pattern.
226+
/// - Different name assignments in alternatives.
227+
/// - The order of name assignments in alternatives.
242228
pub stores: Vec<String>,
229+
/// If 0, any name captures against our subject will raise.
243230
pub allow_irrefutable: bool,
231+
/// An array of blocks to jump to on failure. Jumping to fail_pop[i] will pop
232+
/// i items off of the stack. The end result looks like this (with each block
233+
/// falling through to the next):
234+
/// fail_pop[4]: POP_TOP
235+
/// fail_pop[3]: POP_TOP
236+
/// fail_pop[2]: POP_TOP
237+
/// fail_pop[1]: POP_TOP
238+
/// fail_pop[0]: NOP
244239
pub fail_pop: Vec<BlockIdx>,
240+
/// The number of items on top of the stack that need to *stay* on top of the
241+
/// stack. Variable captures go beneath these. All of them will be popped on
242+
/// failure.
245243
pub on_top: usize,
246244
}
247245

@@ -2055,9 +2053,8 @@ impl Compiler {
20552053
pattern_context: &mut PatternContext,
20562054
) -> CompileResult<()> {
20572055
self.compile_expression(subject)?;
2058-
// Blocks at the end of the switch statement that we jump to after finishing a branch
2059-
// TODO: optimize, we can reuse the same block for all cases
2060-
let mut end_block = self.new_block();
2056+
// Block at the end of the switch statement that we jump to after finishing a branch
2057+
let end_block = self.new_block();
20612058

20622059
let match_case_type = cases.last().expect("cases is not empty");
20632060
let has_default = match_case_type.pattern.is_match_star() && 1 < cases.len();
@@ -2117,7 +2114,6 @@ impl Compiler {
21172114
self.compile_statements(&m.body)?;
21182115
}
21192116

2120-
self.switch_to_block(end_block);
21212117
Ok(())
21222118
}
21232119

compiler/core/src/bytecode.rs

+3
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ pub enum Instruction {
432432
op: Arg<ComparisonOperator>,
433433
},
434434
Pop,
435+
Swap(Arg<u32>),
435436
Rotate2,
436437
Rotate3,
437438
Duplicate,
@@ -1202,6 +1203,7 @@ impl Instruction {
12021203
| TestOperation { .. }
12031204
| CompareOperation { .. } => -1,
12041205
Pop => -1,
1206+
Swap(_) => 0,
12051207
Rotate2 | Rotate3 => 0,
12061208
Duplicate => 1,
12071209
Duplicate2 => 2,
@@ -1398,6 +1400,7 @@ impl Instruction {
13981400
TestOperation { op } => w!(TestOperation, ?op),
13991401
CompareOperation { op } => w!(CompareOperation, ?op),
14001402
Pop => w!(Pop),
1403+
Swap(a) => w!(Swap, a),
14011404
Rotate2 => w!(Rotate2),
14021405
Rotate3 => w!(Rotate3),
14031406
Duplicate => w!(Duplicate),

vm/src/frame.rs

+5
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,11 @@ impl ExecutingFrame<'_> {
673673
self.pop_value();
674674
Ok(None)
675675
}
676+
bytecode::Instruction::Swap(i) => {
677+
let len = self.state.stack.len();
678+
self.state.stack.swap(len - 1, len - 1 - i.get(arg) as usize);
679+
Ok(None)
680+
}
676681
bytecode::Instruction::Duplicate => {
677682
// Duplicate top of stack
678683
let value = self.top_value();

0 commit comments

Comments
 (0)