From 9cd18398f1e1722cc73fb5201db6ececb579f949 Mon Sep 17 00:00:00 2001 From: Shane Date: Mon, 1 Jul 2024 13:35:09 -0400 Subject: [PATCH] map between filtered and real indicies --- stack-debugger/src/main.rs | 251 +++++++++++++++++++++---------------- 1 file changed, 146 insertions(+), 105 deletions(-) diff --git a/stack-debugger/src/main.rs b/stack-debugger/src/main.rs index c2ab4889..c9534b54 100644 --- a/stack-debugger/src/main.rs +++ b/stack-debugger/src/main.rs @@ -1,6 +1,7 @@ use core::{fmt, num::NonZeroUsize}; use std::{ cmp::Ordering, + collections::BTreeMap, ops::Add, path::PathBuf, sync::{mpsc, Arc}, @@ -12,8 +13,12 @@ use eframe::egui::{self, text::LayoutJob, Color32, RichText}; use notify::{ Config, Event, EventKind, RecommendedWatcher, RecursiveMode, Watcher, }; -use stack_core::{journal::JournalScope, prelude::*}; +use stack_core::{ + journal::{JournalOp, JournalScope}, + prelude::*, +}; use stack_debugger::*; +use thinset::SparseMap; #[derive(Debug, Clone, PartialEq, Eq, Default, clap::Parser)] #[command(author, version, about, long_about = None)] @@ -86,10 +91,12 @@ pub fn main() { stack: Vec::new(), scopes: Vec::new(), - error: None, - prints: Vec::new(), index: 0, last_index: 0, + indicies: Vec::new(), + + error: None, + prints: Vec::new(), journal_string: Vec::new(), }; @@ -147,13 +154,21 @@ pub struct DebuggerApp { stack: Vec, scopes: Vec, - error: Option, - prints: Vec, index: usize, last_index: usize, + indicies: Vec, + + error: Option, + prints: Vec, journal_string: Vec, } +fn is_scope_op(op: &JournalOp) -> bool { + matches!(op, JournalOp::ScopedFnStart(..)) + || matches!(op, JournalOp::ScopelessFnStart) + || matches!(op, JournalOp::FnEnd(..)) +} + impl DebuggerApp { fn reload(&mut self) { // TODO: Clear screen when we reload @@ -187,7 +202,26 @@ impl DebuggerApp { self.context.journal_mut().as_mut().unwrap().commit(); - self.index = self.stack_ops_len().saturating_sub(1); + self.indicies.clear(); + let mut ki = 0; + self + .context + .journal() + .as_ref() + .unwrap() + .entries() + .iter() + .enumerate() + .for_each(|(i, entry)| { + let has_scope_op = entry.ops.iter().any(is_scope_op); + + if !(has_scope_op && entry.ops.len() == 1) { + self.indicies.insert(ki, i); + ki += 1; + } + }); + + self.index = self.indicies.len().saturating_sub(1); self.last_index = self.index; self.prints.extend(self.print_rx.try_iter().map(|evt| { if let IOHookEvent::GoTo(index) = evt { @@ -220,31 +254,37 @@ impl DebuggerApp { } fn step_over(&mut self) { - let index = self.index; if let Some(entry) = self .context .journal() .as_ref() .unwrap() .entries() - .get(index) + .get(self.index) { let scope_level = entry.scope_level; - let next_index = self - .context - .journal() - .as_ref() - .unwrap() - .entries() - .iter() - .enumerate() - .skip(index + 1) - .find(|(_, entry)| entry.scope_level == scope_level) - .map(|(i, _)| i); + let next_index = + self.indicies.iter().enumerate().find_map(|(i, real_i)| { + let entry = self + .context + .journal() + .as_ref() + .unwrap() + .entries() + .get(*real_i); + + if let Some(entry) = entry { + if entry.scope_level == scope_level { + Some(i) + } else { + None + } + } else { + None + } + }); - if let Some(next_index) = next_index { - self.index = next_index; - } + self.index = next_index.unwrap_or(self.index); } } @@ -269,12 +309,15 @@ impl DebuggerApp { .enumerate() .rev() .skip(self.stack_ops_len() - index) - .find(|(_, entry)| entry.scope_level == scope_level) - .map(|(i, _)| i); + .find_map(|(i, entry)| { + if entry.scope_level == scope_level { + Some(i) + } else { + None + } + }); - if let Some(next_index) = next_index { - self.index = next_index; - } + self.index = next_index.unwrap_or(self.index); } } } @@ -368,13 +411,11 @@ impl eframe::App for DebuggerApp { } if ui.button(">").clicked() { - self.index = self - .index - .add(1) - .min(self.stack_ops_len().saturating_sub(1)); + self.index = + self.index.add(1).min(self.indicies.len().saturating_sub(1)); } if ui.button("|>").clicked() { - self.index = self.stack_ops_len().saturating_sub(1); + self.index = self.indicies.len().saturating_sub(1); } }); @@ -389,7 +430,7 @@ impl eframe::App for DebuggerApp { }) }); - let max = self.stack_ops_len().saturating_sub(1); + let max = self.indicies.len().saturating_sub(1); ui.horizontal(|ui| { ui.spacing_mut().slider_width = ui.available_width() - 80.0; ui.add( @@ -400,7 +441,8 @@ impl eframe::App for DebuggerApp { }); let entries = self.context.journal().as_ref().unwrap().entries(); - let entry = entries.get(self.index); + let entry = + entries.get(self.indicies.get(self.index).copied().unwrap_or_default()); let mut layout_job = LayoutJob::default(); append_to_job( @@ -436,16 +478,18 @@ impl eframe::App for DebuggerApp { RichText::new("Location: ").strong().color(Color32::WHITE), &mut layout_job, ); - if let Some(entry) = entry { - if let Some(first) = entry.ops.first() { - if let Some(expr) = first.expr() { - if let Some(info) = expr.info.clone() { - if let Some(location) = info.source.location(info.span.start) { - append_to_job( - RichText::new(format!("{}:{}", info.source.name(), location)), - &mut layout_job, - ); - } + + let first_op = + entry.and_then(|entry| entry.ops.iter().find(|op| !is_scope_op(op))); + + if let Some(first) = first_op { + if let Some(expr) = first.expr() { + if let Some(info) = expr.info.clone() { + if let Some(location) = info.source.location(info.span.start) { + append_to_job( + RichText::new(format!("{}:{}", info.source.name(), location)), + &mut layout_job, + ); } } } @@ -453,69 +497,66 @@ impl eframe::App for DebuggerApp { ui.label(layout_job); let mut layout_job = LayoutJob::default(); - if let Some(entry) = entry { - if let Some(first) = entry.ops.first() { - if let Some(expr) = first.expr() { - if let Some(info) = expr.info.clone() { - if let Some((start_loc, end_loc)) = info - .source - .location(info.span.start) - .zip(info.source.location(info.span.end)) - { - const SURROUNDING_LINES: usize = 7; - - let start = - start_loc.line.get().saturating_sub(SURROUNDING_LINES); - let end = - start_loc.line.get().saturating_add(SURROUNDING_LINES); - - ui.add_space(5.0); - ui.label(RichText::new(info.source.name()).monospace()); - ui.add_space(5.0); - - for line in start..end { - if let Some(line_str) = NonZeroUsize::new(line) - .and_then(|line| info.source.line(line)) - { - let mut text = - RichText::new(format!("{}: ", line)).monospace(); - - if line == start_loc.line.get() { - text = text.color(Color32::YELLOW); - } - - append_to_job(text, &mut layout_job); + if let Some(first) = first_op { + if let Some(expr) = first.expr() { + if let Some(info) = expr.info.clone() { + if let Some((start_loc, end_loc)) = info + .source + .location(info.span.start) + .zip(info.source.location(info.span.end)) + { + const SURROUNDING_LINES: usize = 7; + + let start = + start_loc.line.get().saturating_sub(SURROUNDING_LINES); + let end = start_loc.line.get().saturating_add(SURROUNDING_LINES); + + ui.add_space(5.0); + ui.label(RichText::new(info.source.name()).monospace()); + ui.add_space(5.0); + + for line in start..end { + if let Some(line_str) = NonZeroUsize::new(line) + .and_then(|line| info.source.line(line)) + { + let mut text = + RichText::new(format!("{}: ", line)).monospace(); + + if line == start_loc.line.get() { + text = text.color(Color32::YELLOW); + } - line_str.char_indices().for_each(|(i, c)| { - let mut text = RichText::new(c).monospace(); - // TODO: properly support multiline exprs - // - // TODO: if the line span is greater than the surrounding lines, - // remove top surrounding lines until it fits - // - // TODO: lex and parse so we can use paint_expr - if line >= start_loc.line.into() - && line <= end_loc.line.into() + append_to_job(text, &mut layout_job); + + line_str.char_indices().for_each(|(i, c)| { + let mut text = RichText::new(c).monospace(); + // TODO: properly support multiline exprs + // + // TODO: if the line span is greater than the surrounding lines, + // remove top surrounding lines until it fits + // + // TODO: lex and parse so we can use paint_expr + if line >= start_loc.line.into() + && line <= end_loc.line.into() + { + if (i + 1) >= start_loc.column.into() + && (i + 1) < end_loc.column.into() { - if (i + 1) >= start_loc.column.into() - && (i + 1) < end_loc.column.into() - { - text = text - .color(Color32::BLACK) - .background_color(Color32::YELLOW); - } else { - text = text.color(Color32::YELLOW); - } + text = text + .color(Color32::BLACK) + .background_color(Color32::YELLOW); + } else { + text = text.color(Color32::YELLOW); } + } - append_to_job(text, &mut layout_job); - }); - } + append_to_job(text, &mut layout_job); + }); } - - ui.label(layout_job); - ui.add_space(5.0); } + + ui.label(layout_job); + ui.add_space(5.0); } } } @@ -551,16 +592,16 @@ impl eframe::App for DebuggerApp { self.context.journal().as_ref().unwrap().construct_from_to( &mut self.stack, &mut self.scopes, - self.last_index, - self.index, + self.indicies.get(self.last_index).copied().unwrap(), + self.indicies.get(self.index).copied().unwrap(), ) } Ordering::Less => { self.context.journal().as_ref().unwrap().construct_to_from( &mut self.stack, &mut self.scopes, - self.index, - self.last_index, + self.indicies.get(self.index).copied().unwrap(), + self.indicies.get(self.last_index).copied().unwrap(), ) }