From 80da2af821385b2fc89091e9ac37a047349da4bd Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Wed, 5 Feb 2025 12:58:02 +1300 Subject: Implement source unit compilation, symbol resolution, error reporting This library can now carry out all stages of assembly from collecting source fragments to resolving symbols to pruning unused libraries to generating a single compiled source file. Pretty-printing of state has also been implemented in this library. The source tree hierarchy, symbol resolution errors, and file read errors can all be printed in a tidy format. --- src/source_hierarchy.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/source_hierarchy.rs (limited to 'src/source_hierarchy.rs') diff --git a/src/source_hierarchy.rs b/src/source_hierarchy.rs new file mode 100644 index 0000000..9478c56 --- /dev/null +++ b/src/source_hierarchy.rs @@ -0,0 +1,58 @@ +use crate::*; + +use ansi::*; + + +pub struct SourceHierarchy<'a> { + pub resolver: &'a Resolver, +} + +impl<'a> SourceHierarchy<'a> { + pub fn report(&self) { + eprintln!("."); + let len = self.resolver.root_unit_ids.len(); + for (i, id) in self.resolver.root_unit_ids.iter().enumerate() { + let end = i + 1 == len; + self.report_leaf(*id, Vec::new(), end); + } + } + + fn report_leaf(&self, id: usize, mut levels: Vec, end: bool) { + // A level entry is true if all entries in that level have been printed. + for level in &levels { + match level { + false => eprint!("│ "), + true => eprint!(" "), + } + } + // The end value is true if all siblings of this entry have been printed. + match end { + false => eprint!("├── "), + true => eprint!("└── "), + } + if let Some(unit) = self.resolver.source_units.get(id) { + let path_str = &unit.source_unit.main.path.as_os_str().to_string_lossy(); + if let Some(name_str) = unit.source_unit.name() { + eprint!("{name_str}{BLUE}"); + if unit.source_unit.head.is_some() { eprint!(" +head") } + if unit.source_unit.tail.is_some() { eprint!(" +tail") } + let mut unresolved = 0; + for symbol in &self.resolver.unresolved { + if symbol.source_id == id { unresolved += 1; } + } + if unresolved > 0 { eprint!("{RED} ({unresolved})"); } + eprintln!("{NORMAL} {DIM}({path_str}){NORMAL}"); + } else { + eprintln!("{path_str}"); + } + levels.push(end); + let len = unit.child_ids.len(); + for (i, id) in unit.child_ids.iter().enumerate() { + let end = i + 1 == len; + self.report_leaf(*id, levels.clone(), end); + } + } else { + eprintln!(""); + } + } +} -- cgit v1.2.3-70-g09d2