mirror of
https://github.com/imjasonh/nescript
synced 2026-07-09 01:16:12 +00:00
Fix bugs found during code review
Issues found by systematic review of all compiler modules. Each fix includes a regression test. Parser fixes: - Add EOF checks to function call arg parsing loops (lines 984, 1269) to prevent infinite loops on unterminated call expressions - Fix span end positions: use .end instead of .start for 9 declaration span computations (var, const, fun, state, bank, sprite, palette, background, block) - Add missing compound assignment operators (&= |= ^=) to parse_assign_op() for array element assignments Codegen fix: - Fix NOT operator: old code used EOR #$FF + AND #$01 which produced wrong results for non-boolean inputs (e.g., NOT 0x42 returned 1 instead of 0). New code uses BEQ/branch to properly map any nonzero value to 0 and zero to 1. Assembler fixes: - Add branch offset range validation: assert offset is in -128..127 range instead of silently wrapping on overflow - Panic on unresolved labels instead of silently leaving placeholder 0x00 bytes in the output Verified non-issues (reviewer false positives): - NMI P register: 6502 hardware pushes P automatically on NMI entry; RTI restores it. PHP/PLP not needed. - Controller read buffer: 8 iterations of LSR+ROL fully replace all 8 bits, so prior contents don't matter. - advance() panic: tokens always has at least Eof from lexer. 4 new regression tests, 225 total. https://claude.ai/code/session_01W6eQFStA66EuMKHUFo2rx3
This commit is contained in:
parent
07dd5bd7e8
commit
bc165ed647
5 changed files with 96 additions and 14 deletions
|
|
@ -328,7 +328,7 @@ impl Parser {
|
|||
var_type,
|
||||
init,
|
||||
placement,
|
||||
span: Span::new(start.file_id, start.start, self.current_span().start),
|
||||
span: Span::new(start.file_id, start.start, self.current_span().end),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -347,7 +347,7 @@ impl Parser {
|
|||
name,
|
||||
const_type,
|
||||
value,
|
||||
span: Span::new(start.file_id, start.start, self.current_span().start),
|
||||
span: Span::new(start.file_id, start.start, self.current_span().end),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -395,7 +395,7 @@ impl Parser {
|
|||
return_type,
|
||||
body,
|
||||
is_inline,
|
||||
span: Span::new(start.file_id, start.start, self.current_span().start),
|
||||
span: Span::new(start.file_id, start.start, self.current_span().end),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -458,7 +458,7 @@ impl Parser {
|
|||
on_exit,
|
||||
on_frame,
|
||||
on_scanline,
|
||||
span: Span::new(start.file_id, start.start, self.current_span().start),
|
||||
span: Span::new(start.file_id, start.start, self.current_span().end),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -484,7 +484,7 @@ impl Parser {
|
|||
Ok(BankDecl {
|
||||
name,
|
||||
bank_type,
|
||||
span: Span::new(start.file_id, start.start, self.current_span().start),
|
||||
span: Span::new(start.file_id, start.start, self.current_span().end),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -538,7 +538,7 @@ impl Parser {
|
|||
Ok(SpriteDecl {
|
||||
name,
|
||||
chr_source,
|
||||
span: Span::new(start.file_id, start.start, self.current_span().start),
|
||||
span: Span::new(start.file_id, start.start, self.current_span().end),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +597,7 @@ impl Parser {
|
|||
Ok(PaletteDecl {
|
||||
name,
|
||||
colors,
|
||||
span: Span::new(start.file_id, start.start, self.current_span().start),
|
||||
span: Span::new(start.file_id, start.start, self.current_span().end),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -638,7 +638,7 @@ impl Parser {
|
|||
Ok(BackgroundDecl {
|
||||
name,
|
||||
chr_source,
|
||||
span: Span::new(start.file_id, start.start, self.current_span().start),
|
||||
span: Span::new(start.file_id, start.start, self.current_span().end),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -715,7 +715,7 @@ impl Parser {
|
|||
|
||||
Ok(Block {
|
||||
statements,
|
||||
span: Span::new(start.file_id, start.start, self.current_span().start),
|
||||
span: Span::new(start.file_id, start.start, self.current_span().end),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -981,7 +981,7 @@ impl Parser {
|
|||
// Function call
|
||||
self.advance();
|
||||
let mut args = Vec::new();
|
||||
while *self.peek() != TokenKind::RParen {
|
||||
while *self.peek() != TokenKind::RParen && *self.peek() != TokenKind::Eof {
|
||||
args.push(self.parse_expr()?);
|
||||
if *self.peek() == TokenKind::Comma {
|
||||
self.advance();
|
||||
|
|
@ -1015,6 +1015,18 @@ impl Parser {
|
|||
self.advance();
|
||||
Ok(AssignOp::MinusAssign)
|
||||
}
|
||||
TokenKind::AmpAssign => {
|
||||
self.advance();
|
||||
Ok(AssignOp::AmpAssign)
|
||||
}
|
||||
TokenKind::PipeAssign => {
|
||||
self.advance();
|
||||
Ok(AssignOp::PipeAssign)
|
||||
}
|
||||
TokenKind::CaretAssign => {
|
||||
self.advance();
|
||||
Ok(AssignOp::CaretAssign)
|
||||
}
|
||||
_ => Err(Diagnostic::error(
|
||||
ErrorCode::E0201,
|
||||
format!("expected assignment operator, found '{}'", self.peek()),
|
||||
|
|
@ -1266,7 +1278,7 @@ impl Parser {
|
|||
if *self.peek() == TokenKind::LParen {
|
||||
self.advance();
|
||||
let mut args = Vec::new();
|
||||
while *self.peek() != TokenKind::RParen {
|
||||
while *self.peek() != TokenKind::RParen && *self.peek() != TokenKind::Eof {
|
||||
args.push(self.parse_expr()?);
|
||||
if *self.peek() == TokenKind::Comma {
|
||||
self.advance();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue