mirror of
https://github.com/imjasonh/nescript
synced 2026-07-08 17:06:04 +00:00
CLI: --memory-map flag
Dumps a human-readable table of variable allocations sorted by
address, separated into zero-page and main RAM sections with a
final byte-usage summary. Struct fields show up as individual
entries under their synthetic \`var.field\` names.
Example output for examples/structs_enums_for.ne:
=== NEScript Memory Map ===
Zero Page (\$00-\$FF):
\$00-\$0F [SYSTEM] reserved (frame flag, input, state, params, scratch)
\$0010 [USER] enemy_y (u8)
\$0011 [USER] i (u8)
RAM (\$0200-\$07FF):
\$0200-\$02FF [SYSTEM] OAM shadow buffer
\$0300 [USER] player.x (u8)
\$0301 [USER] player.y (u8)
\$0302 [USER] player.vx (u8)
...
Zero Page: 2/128 bytes used
Main RAM: 11/1280 bytes used
https://claude.ai/code/session_01W6eQFStA66EuMKHUFo2rx3
This commit is contained in:
parent
496925344d
commit
db234a6ca7
2 changed files with 80 additions and 7 deletions
|
|
@ -937,13 +937,14 @@ nescript build game.ne --asm-dump
|
|||
nescript build game.ne --dump-ir
|
||||
```
|
||||
|
||||
| Flag | Description |
|
||||
|---------------|----------------------------------------------------------------|
|
||||
| `--output` | Set output ROM file path (default: input.nes) |
|
||||
| `--debug` | Enable debug mode with runtime checks |
|
||||
| `--asm-dump` | Dump generated 6502 assembly to stdout |
|
||||
| `--dump-ir` | Dump the lowered IR program (after optimization) to stdout |
|
||||
| `--use-ast` | Use the legacy AST-based codegen (default is the IR codegen) |
|
||||
| Flag | Description |
|
||||
|-----------------|----------------------------------------------------------------|
|
||||
| `--output` | Set output ROM file path (default: input.nes) |
|
||||
| `--debug` | Enable debug mode with runtime checks |
|
||||
| `--asm-dump` | Dump generated 6502 assembly to stdout |
|
||||
| `--dump-ir` | Dump the lowered IR program (after optimization) to stdout |
|
||||
| `--memory-map` | Dump a memory map of variable allocations to stdout |
|
||||
| `--use-ast` | Use the legacy AST-based codegen (default is the IR codegen) |
|
||||
|
||||
### Check
|
||||
|
||||
|
|
|
|||
72
src/main.rs
72
src/main.rs
|
|
@ -33,6 +33,11 @@ enum Cli {
|
|||
#[arg(long)]
|
||||
dump_ir: bool,
|
||||
|
||||
/// Dump a human-readable memory map of variable allocations
|
||||
/// to stdout.
|
||||
#[arg(long)]
|
||||
memory_map: bool,
|
||||
|
||||
/// Use the legacy AST-based codegen. The default is the IR-based
|
||||
/// codegen, which runs the optimizer passes before emitting 6502.
|
||||
#[arg(long)]
|
||||
|
|
@ -55,6 +60,7 @@ fn main() {
|
|||
debug,
|
||||
asm_dump,
|
||||
dump_ir,
|
||||
memory_map,
|
||||
use_ast,
|
||||
} => {
|
||||
let output = output.unwrap_or_else(|| input.with_extension("nes"));
|
||||
|
|
@ -64,6 +70,7 @@ fn main() {
|
|||
debug,
|
||||
asm_dump,
|
||||
dump_ir,
|
||||
memory_map,
|
||||
use_ast,
|
||||
},
|
||||
) {
|
||||
|
|
@ -89,6 +96,65 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
/// Print a human-readable memory map of variable allocations.
|
||||
/// Entries are sorted by address and labelled with their scope
|
||||
/// (zero-page vs RAM).
|
||||
fn print_memory_map(analysis: &nescript::analyzer::AnalysisResult) {
|
||||
let mut allocs: Vec<_> = analysis.var_allocations.iter().collect();
|
||||
allocs.sort_by_key(|a| a.address);
|
||||
|
||||
println!("=== NEScript Memory Map ===");
|
||||
println!("Zero Page ($00-$FF):");
|
||||
println!(" $00-$0F [SYSTEM] reserved (frame flag, input, state, params, scratch)");
|
||||
for a in allocs.iter().filter(|a| a.address < 0x100) {
|
||||
if a.size == 1 {
|
||||
println!(" ${:04X} [USER] {} (u8)", a.address, a.name);
|
||||
} else {
|
||||
println!(
|
||||
" ${:04X}-${:04X} [USER] {} ({} bytes)",
|
||||
a.address,
|
||||
a.address + a.size - 1,
|
||||
a.name,
|
||||
a.size
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let ram_allocs: Vec<_> = allocs.iter().filter(|a| a.address >= 0x100).collect();
|
||||
if !ram_allocs.is_empty() {
|
||||
println!("\nRAM ($0200-$07FF):");
|
||||
println!(" $0200-$02FF [SYSTEM] OAM shadow buffer");
|
||||
for a in &ram_allocs {
|
||||
if a.size == 1 {
|
||||
println!(" ${:04X} [USER] {} (u8)", a.address, a.name);
|
||||
} else {
|
||||
println!(
|
||||
" ${:04X}-${:04X} [USER] {} ({} bytes)",
|
||||
a.address,
|
||||
a.address + a.size - 1,
|
||||
a.name,
|
||||
a.size
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Summary line.
|
||||
let zp_used: u16 = allocs
|
||||
.iter()
|
||||
.filter(|a| a.address < 0x80)
|
||||
.map(|a| a.size)
|
||||
.sum();
|
||||
let ram_used: u16 = allocs
|
||||
.iter()
|
||||
.filter(|a| a.address >= 0x300)
|
||||
.map(|a| a.size)
|
||||
.sum();
|
||||
println!();
|
||||
println!("Zero Page: {zp_used}/128 bytes used");
|
||||
println!("Main RAM: {ram_used}/1280 bytes used");
|
||||
}
|
||||
|
||||
fn dump_asm(instructions: &[nescript::asm::Instruction]) {
|
||||
use nescript::asm::{AddressingMode, Opcode};
|
||||
for inst in instructions {
|
||||
|
|
@ -112,6 +178,7 @@ struct CompileOptions {
|
|||
debug: bool,
|
||||
asm_dump: bool,
|
||||
dump_ir: bool,
|
||||
memory_map: bool,
|
||||
use_ast: bool,
|
||||
}
|
||||
|
||||
|
|
@ -119,6 +186,7 @@ fn compile(input: &PathBuf, opts: &CompileOptions) -> Result<Vec<u8>, ()> {
|
|||
let debug = opts.debug;
|
||||
let asm_dump = opts.asm_dump;
|
||||
let dump_ir = opts.dump_ir;
|
||||
let memory_map = opts.memory_map;
|
||||
let use_ast = opts.use_ast;
|
||||
let raw_source = std::fs::read_to_string(input).map_err(|e| {
|
||||
eprintln!("error: failed to read {}: {e}", input.display());
|
||||
|
|
@ -165,6 +233,10 @@ fn compile(input: &PathBuf, opts: &CompileOptions) -> Result<Vec<u8>, ()> {
|
|||
print!("{}", ir_program.pretty());
|
||||
}
|
||||
|
||||
if memory_map {
|
||||
print_memory_map(&analysis);
|
||||
}
|
||||
|
||||
// Resolve sprite assets (CHR data + tile indices) relative to the
|
||||
// source file's directory, so `@binary` / `@chr` paths work naturally.
|
||||
let source_dir = input.parent().unwrap_or_else(|| Path::new("."));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue