1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-08 17:06:04 +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:
Claude 2026-04-12 10:57:34 +00:00
parent 21a74652f2
commit 814cbe54bd
No known key found for this signature in database
4 changed files with 105 additions and 3 deletions

View file

@ -414,7 +414,7 @@ impl Parser {
let mut on_enter = None;
let mut on_exit = None;
let mut on_frame = None;
let on_scanline = Vec::new();
let mut on_scanline: Vec<(u8, Block)> = Vec::new();
while *self.peek() != TokenKind::RBrace && *self.peek() != TokenKind::Eof {
match self.peek().clone() {
@ -423,7 +423,7 @@ impl Parser {
}
TokenKind::KwOn => {
self.advance();
let (event, _) = self.expect_ident()?;
let (event, event_span) = self.expect_ident()?;
match event.as_str() {
"enter" => {
on_enter = Some(self.parse_block()?);
@ -434,11 +434,35 @@ impl Parser {
"frame" => {
on_frame = Some(self.parse_block()?);
}
"scanline" => {
// Syntax: `on scanline(N) { ... }`
self.expect(&TokenKind::LParen)?;
let line = if let TokenKind::IntLiteral(v) = self.peek().clone() {
self.advance();
if v > 239 {
return Err(Diagnostic::error(
ErrorCode::E0201,
format!("scanline value {v} out of range (0-239)"),
self.current_span(),
));
}
v as u8
} else {
return Err(Diagnostic::error(
ErrorCode::E0201,
"expected integer scanline number",
self.current_span(),
));
};
self.expect(&TokenKind::RParen)?;
let body = self.parse_block()?;
on_scanline.push((line, body));
}
_ => {
return Err(Diagnostic::error(
ErrorCode::E0201,
format!("unknown event handler 'on {event}'"),
self.current_span(),
event_span,
));
}
}