A fn to return a map of line addresses to enable step debugging

This commit is contained in:
2023-01-26 14:40:40 -06:00
parent 11f0760b01
commit dddff7b54a
3 changed files with 40 additions and 1 deletions
-1
View File
@@ -1,7 +1,6 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
use clap::lazy_static::lazy_static;
use clap::Parser; use clap::Parser;
use regex::Regex; use regex::Regex;
use serde_json::json; use serde_json::json;
+1
View File
@@ -10,4 +10,5 @@ mod vasm_parser;
mod vasm_preprocessor; mod vasm_preprocessor;
pub use vasm_assembler::assemble_snippet; pub use vasm_assembler::assemble_snippet;
pub use vasm_assembler::snippet_source_map;
pub use vasm_assembler::assemble_file; pub use vasm_assembler::assemble_file;
+39
View File
@@ -182,6 +182,45 @@ pub fn assemble_snippet<T: IntoIterator<Item = String>>(
assemble_line_results(line_results).map(|(bytes, _)| { bytes }) assemble_line_results(line_results).map(|(bytes, _)| { bytes })
} }
/// Turn an iterable of strs into a map from instruction address to line number. This
/// supports macros but not `#include`, just like `assemble_snippet`. Zero-length lines
/// won't appear in the map. This is intended to be used for highlighting lines while
/// stepping through a snippet. Lines in the snippet are indexed from 1 and comment and
/// blank lines are handled correctly.
/// ```
/// use std::collections::BTreeMap;
/// assert_eq!(
/// vasm_core::snippet_source_map(".org 0x400 \n push 5 \n add 7".lines().map(String::from)),
/// Ok(BTreeMap::from([(1024, 2), (1026, 3)]))
/// )
/// ```
pub fn snippet_source_map<T: IntoIterator<Item = String>>(lines: T) -> Result<BTreeMap<i32, usize>, AssembleError> {
let line_results = linesource_for_snippet(lines);
let lines = line_results.iter().map(|line| line.clone().unwrap());
let lines: Vec<Line> = lines.into_iter().collect();
let scope = solve_equs(&lines)?;
let line_lengths = measure_instructions(&lines, &scope);
let (line_addresses, _scope) = place_labels(&lines, scope, &line_lengths)?;
let mut line_for_addr = BTreeMap::new();
for (i, line) in lines.iter().enumerate() {
line_for_addr.insert(line_addresses[&i], line.location.line_num);
}
Ok(line_for_addr)
}
fn linesource_for_snippet<T: IntoIterator<Item=String>>(lines: T) -> Vec<Result<Line, AssembleError>> {
let line_results: Vec<Result<Line, AssembleError>> =
LineSource::new("<none>", lines, |_file| {
Err(AssembleError::IncludeError(
Location::default(),
"Including is not supported in assembling snippets".to_string(),
))
})
.collect();
line_results
}
/// Assemble a file from the filesystem, opening other files as it includes them. /// Assemble a file from the filesystem, opening other files as it includes them.
pub fn assemble_file(filename: &str) -> Result<(Vec<u8>, Scope), AssembleError> { pub fn assemble_file(filename: &str) -> Result<(Vec<u8>, Scope), AssembleError> {
let lines = lines_from_file(filename)?; let lines = lines_from_file(filename)?;