diff options
| author | Miquel Sabaté Solà <mikisabate@gmail.com> | 2025-01-10 12:46:21 +0100 |
|---|---|---|
| committer | Miquel Sabaté Solà <mikisabate@gmail.com> | 2025-01-10 12:46:21 +0100 |
| commit | 126e5eba61c3ca2b74fb9e7d52c91d90e8315a0c (patch) | |
| tree | 21c66cecebb27df553f09f2cc60c7b2ace3f6a30 /lib/xixanta/src/assembler.rs | |
| parent | 68ce788d00fe0b8353b7e6aee5ce8dfae564ea5a (diff) | |
| download | tools.nes-126e5eba61c3ca2b74fb9e7d52c91d90e8315a0c.tar.gz tools.nes-126e5eba61c3ca2b74fb9e7d52c91d90e8315a0c.zip | |
Properly fill the context stack when forcing it
When calling `force_context_switch` the stack was mindlessly pushing the
given name without taking into consideration how scopes are to be laid
out. This made some variables/addresses that were previously preserved
no longer reachable when crunching pending nodes.
This patch also makes `force_context_switch` reset the stack before
doing anything at all, which means that `force_context_pop` was no
longer relevant.
Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'lib/xixanta/src/assembler.rs')
| -rw-r--r-- | lib/xixanta/src/assembler.rs | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs index f190d33..06f0b24 100644 --- a/lib/xixanta/src/assembler.rs +++ b/lib/xixanta/src/assembler.rs @@ -587,8 +587,6 @@ impl<'a> Assembler<'a> { } Err(e) => errors.push(e), } - - self.context.force_context_pop(); } if errors.is_empty() { @@ -2936,6 +2934,54 @@ cpx #(4 * var2)"#, assert_instruction("stx $020, y", &[0x96, 0x20]); } + #[test] + fn jsr_inside_multiple_contexts() { + let res = just_bundles( + r#".scope Movement + .proc accelerate + rts + .endproc + + .proc update + jsr accelerate + rts + .endproc +.endscope + +jsr Movement::accelerate +jsr Movement::update + "#, + ); + + assert_eq!(res.len(), 5); + + // accelerate -> rts + assert_eq!(res[0].size, 1); + assert_eq!(res[0].bytes[0], 0x60); + + // jsr accelerate + assert_eq!(res[1].size, 3); + assert_eq!(res[1].bytes[0], 0x20); + assert_eq!(res[1].bytes[1], 0x00); + assert_eq!(res[1].bytes[2], 0x80); + + // update -> rts + assert_eq!(res[2].size, 1); + assert_eq!(res[2].bytes[0], 0x60); + + // jsr Movement::accelerate + assert_eq!(res[3].size, 3); + assert_eq!(res[3].bytes[0], 0x20); + assert_eq!(res[3].bytes[1], 0x00); + assert_eq!(res[3].bytes[2], 0x80); + + // jsr Movement::update + assert_eq!(res[4].size, 3); + assert_eq!(res[4].bytes[0], 0x20); + assert_eq!(res[4].bytes[1], 0x01); + assert_eq!(res[4].bytes[2], 0x80); + } + // Control statements #[test] |
