use tabled::Tabled;
use xo65::{scope::ScopeFlags, Xo65};
use crate::query::Xo65Query as _;
use crate::util::fmt_option;
pub fn dump(obj: &Xo65) {
println!("Scope:");
println!("{}", FmtScopeTable { obj });
println!();
}
#[derive(Debug)]
struct FmtScopeTable<'a, 'data> {
obj: &'a Xo65<'data>,
}
impl std::fmt::Display for FmtScopeTable<'_, '_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use tabled::{
settings::{object::Columns, Alignment, Style},
Table,
};
let fmt_str = |idx: u32| self.obj.fmt_string(idx).to_string();
let rows = self
.obj
.scope_table()
.iter()
.enumerate()
.map(|(idx, scope)| {
let name = fmt_str(scope.name());
let kind = format!("{:?}", scope.kind());
let parent = scope.parent().to_string(); let lex_lvl = scope.lexical_level();
let flags = scope.flags();
let flags = format!("{:#X} ({})", flags.get(), FmtFlagsDesc(flags));
let size = fmt_option(&scope.size()).to_string();
let label = fmt_option(&scope.label()).to_string();
let spans = scope.spans().len();
FmtScopeTableRow {
idx,
name,
kind,
parent,
lex_lvl,
flags,
size,
label,
spans,
}
});
Table::new(rows)
.with(Style::empty())
.modify(Columns::single(0), Alignment::right()) .modify(Columns::single(4), Alignment::right()) .modify(Columns::single(6), Alignment::right()) .modify(Columns::single(8), Alignment::right()) .fmt(f)
}
}
#[derive(Debug)]
struct FmtFlagsDesc(ScopeFlags);
impl std::fmt::Display for FmtFlagsDesc {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use itertools::Itertools as _;
let s = [
self.0.has_size().then_some("HAS_SIZE"),
self.0.has_label().then_some("HAS_LABEL"),
]
.into_iter()
.flatten()
.join(",");
s.fmt(f)
}
}
#[derive(Debug, Tabled)]
struct FmtScopeTableRow {
idx: usize,
name: String,
kind: String,
parent: String,
lex_lvl: u32,
flags: String,
size: String,
label: String,
spans: usize,
}