1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-11 02:02:58 +00:00

analyzer: add four new warning diagnostics

Extends the analyzer with the warnings listed under "Error message
polish" in docs/future-work.md:

- W0102 (existing): now also fires for `while true { ... }` and
  `loop { if cond { continue } }`. `continue` is explicitly not
  counted as an exit — the loop still spins forever.
- W0105 (new): palette declarations whose sub-palette first-bytes
  disagree. The NES mirrors $3F10/$3F14/$3F18/$3F1C onto $3F00/
  $3F04/$3F08/$3F0C, so a 32-byte sequential write silently
  overwrites the background universal colour; the grouped
  `universal:` form auto-fixes this so only flat `colors: [...]`
  declarations can trip it.
- W0106 (new): a call at statement position whose callee has a
  declared return type — the value is silently dropped.
- W0107 (new): `fast` variables with fewer than three observed
  reads+writes, which don't justify holding a scarce zero-page
  slot. Leading-underscore names are exempt.

All four are warnings only — no IR, codegen, or runtime changes,
so every committed example ROM rebuilds byte-identical and no
emulator goldens flip. Tests added in src/analyzer/tests.rs.

One legitimate W0106 surfaces on examples/platformer.ne (the
`resolve_enemy_hit` helper uses early-return for control flow
but its return value is discarded by the caller); fixing it
would shift the ROM and flip goldens, so it is left in place
as an informational hint rather than a hard fix.

https://claude.ai/code/session_01MaNVcDmK9gsspRkdxowQAM
This commit is contained in:
Claude 2026-04-14 01:35:08 +00:00
parent 68184b7296
commit d2cfce595b
No known key found for this signature in database
3 changed files with 556 additions and 2 deletions

View file

@ -39,6 +39,9 @@ pub enum ErrorCode {
W0102, // loop without break or wait_frame
W0103, // unused variable
W0104, // unreachable code after terminator, or unreachable state
W0105, // palette sub-palette universal mismatch (mirror collision)
W0106, // implicit drop of non-void function return value
W0107, // `fast` variable rarely accessed (wastes zero-page slot)
}
impl fmt::Display for ErrorCode {
@ -62,6 +65,9 @@ impl fmt::Display for ErrorCode {
Self::W0102 => "W0102",
Self::W0103 => "W0103",
Self::W0104 => "W0104",
Self::W0105 => "W0105",
Self::W0106 => "W0106",
Self::W0107 => "W0107",
};
write!(f, "{code}")
}
@ -70,7 +76,13 @@ impl fmt::Display for ErrorCode {
impl ErrorCode {
pub fn level(self) -> Level {
match self {
Self::W0101 | Self::W0102 | Self::W0103 | Self::W0104 => Level::Warning,
Self::W0101
| Self::W0102
| Self::W0103
| Self::W0104
| Self::W0105
| Self::W0106
| Self::W0107 => Level::Warning,
_ => Level::Error,
}
}