1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-08 08:55:38 +00:00

Add debug.log and debug.assert statements

Parser:
- debug.log(expr, ...) and debug.assert(cond) syntax
- parse_debug_statement() handles both methods
- New AST variants: Statement::DebugLog and Statement::DebugAssert

Codegen:
- CodeGen::with_debug(bool) to toggle debug instrumentation
- DebugLog writes each expression to $4800 (Mesen debug port)
- DebugAssert evaluates condition; on false, writes $FF to $4800 + BRK
- Both are stripped entirely when debug_mode = false (release builds)

CLI:
- --debug flag now wired through to CodeGen
- Without --debug, all debug statements produce zero bytes

Analyzer:
- Type-checks DebugAssert condition as bool
- Walks DebugLog args for reads (used_vars tracking)

IR lowering:
- DebugLog/DebugAssert are no-ops (codegen handles them directly)

254 tests (5 new: 3 parser + 2 codegen).

https://claude.ai/code/session_01W6eQFStA66EuMKHUFo2rx3
This commit is contained in:
Claude 2026-04-12 10:11:32 +00:00
parent 6efef6c4c5
commit 45b2b2a279
No known key found for this signature in database
8 changed files with 199 additions and 3 deletions

View file

@ -787,6 +787,7 @@ impl Parser {
self.expect(&TokenKind::RParen)?;
Ok(Statement::Scroll(x, y, span))
}
TokenKind::KwDebug => self.parse_debug_statement(),
TokenKind::Ident(_) => self.parse_assign_or_call(),
_ => Err(Diagnostic::error(
ErrorCode::E0201,
@ -891,6 +892,38 @@ impl Parser {
}))
}
/// Parse debug.log(...) or debug.assert(...)
fn parse_debug_statement(&mut self) -> Result<Statement, Diagnostic> {
let start = self.current_span();
self.expect(&TokenKind::KwDebug)?;
self.expect(&TokenKind::Dot)?;
let (method, _) = self.expect_ident()?;
self.expect(&TokenKind::LParen)?;
match method.as_str() {
"log" => {
let mut args = Vec::new();
while *self.peek() != TokenKind::RParen && *self.peek() != TokenKind::Eof {
args.push(self.parse_expr()?);
if *self.peek() == TokenKind::Comma {
self.advance();
}
}
self.expect(&TokenKind::RParen)?;
Ok(Statement::DebugLog(args, start))
}
"assert" => {
let cond = self.parse_expr()?;
self.expect(&TokenKind::RParen)?;
Ok(Statement::DebugAssert(cond, start))
}
_ => Err(Diagnostic::error(
ErrorCode::E0201,
format!("unknown debug method '{method}' (expected 'log' or 'assert')"),
start,
)),
}
}
fn parse_assign_or_call(&mut self) -> Result<Statement, Diagnostic> {
let start = self.current_span();
let (name, _) = self.expect_ident()?;