mirror of
https://github.com/imjasonh/nescript
synced 2026-07-10 01:37:45 +00:00
Parser/analyzer: on scanline(N) handlers
Adds parser support for \`on scanline(N) { ... }\` event handlers
inside state bodies. The analyzer enforces that scanline handlers
are only allowed with the MMC3 mapper (the only mapper we target
with scanline IRQ support), and validates the body like any other
state handler.
Codegen for the scanline IRQ vector is still TODO — the handler
is parsed and validated but not yet hooked up to the MMC3 IRQ
counter. When we get to it, the linker needs to install an IRQ
handler that writes to \$C000/\$C001/\$E000/\$E001.
https://claude.ai/code/session_01W6eQFStA66EuMKHUFo2rx3
This commit is contained in:
parent
21a74652f2
commit
814cbe54bd
4 changed files with 105 additions and 3 deletions
|
|
@ -138,6 +138,18 @@ impl Analyzer {
|
|||
if let Some(block) = &state.on_frame {
|
||||
self.check_block(block, &state_names);
|
||||
}
|
||||
// `on scanline(N)` is only valid with mappers that have a
|
||||
// scanline-counting IRQ source (currently only MMC3).
|
||||
if !state.on_scanline.is_empty() && program.game.mapper != Mapper::MMC3 {
|
||||
self.diagnostics.push(Diagnostic::error(
|
||||
ErrorCode::E0203,
|
||||
"`on scanline` requires the MMC3 mapper",
|
||||
state.span,
|
||||
));
|
||||
}
|
||||
for (_, block) in &state.on_scanline {
|
||||
self.check_block(block, &state_names);
|
||||
}
|
||||
}
|
||||
|
||||
// Type-check function bodies. Parameters are registered as
|
||||
|
|
|
|||
|
|
@ -298,6 +298,38 @@ fn analyze_return_wrong_type() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analyze_on_scanline_requires_mmc3() {
|
||||
let errors = analyze_errors(
|
||||
r#"
|
||||
game "Test" { mapper: NROM }
|
||||
state Main {
|
||||
on frame { wait_frame }
|
||||
on scanline(120) { scroll(0, 0) }
|
||||
}
|
||||
start Main
|
||||
"#,
|
||||
);
|
||||
assert!(
|
||||
errors.contains(&ErrorCode::E0203),
|
||||
"on scanline without MMC3 should produce E0203, got: {errors:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analyze_on_scanline_mmc3_ok() {
|
||||
analyze_ok(
|
||||
r#"
|
||||
game "Test" { mapper: MMC3 }
|
||||
state Main {
|
||||
on frame { wait_frame }
|
||||
on scanline(120) { scroll(0, 0) }
|
||||
}
|
||||
start Main
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analyze_loop_without_exit_warns() {
|
||||
let errors = analyze_errors(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue