Fixed {Data, Func}Table::get_*.

`Directive` now implements `InstTargetFmt`.
This commit is contained in:
2021-01-13 23:09:25 +00:00
parent 930696eaec
commit bbfe541a6d
7 changed files with 40 additions and 16 deletions

View File

@@ -52,6 +52,12 @@ impl Data {
self.pos + self.size()
}
/// Checks if this data contains `pos`
#[must_use]
pub fn contains(&self, pos: Pos) -> bool {
(self.pos..self.end_pos()).contains(&pos)
}
/// Returns the size, in bytes, of this data
#[must_use]
pub fn size(&self) -> usize {

View File

@@ -60,14 +60,13 @@ impl DataTable {
#[must_use]
pub fn get_containing(&self, pos: Pos) -> Option<&Data> {
// Find the first data that includes `pos`.
self.range(..=pos).find(|data| pos < data.end_pos())
self.range(..=pos).filter(|data| data.contains(pos)).min_by_key(|data| data.size())
}
/// Retrieves the smallest data location at `pos`
#[must_use]
pub fn get_starting_at(&self, pos: Pos) -> Option<&Data> {
// Get the first data with position `pos`
self.range(pos..=pos).next()
self.get_containing(pos).filter(|data| data.pos == pos)
}
/// Returns a range of data

View File

@@ -45,6 +45,14 @@ pub struct Func {
pub end_pos: Pos,
}
impl Func {
/// Checks if this function contains `pos`
#[must_use]
pub fn contains(&self, pos: Pos) -> bool {
(self.start_pos..self.end_pos).contains(&pos)
}
}
impl Borrow<Pos> for Func {
fn borrow(&self) -> &Pos {
&self.start_pos
@@ -60,12 +68,6 @@ impl PartialEq for Func {
impl Eq for Func {}
/// Only the start position is hashed, just as in the [`PartialEq`] impl.
impl std::hash::Hash for Func {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.start_pos.hash(state);
}
}
/// Only the start position matters for the order
impl PartialOrd for Func {

View File

@@ -49,16 +49,17 @@ impl FuncTable {
DiscardingSortedMergeIter::new(self.0.into_iter(), other.0.into_iter()).collect()
}
/// Retrieves a function that contains `pos`
/// Retrieves the function containing `pos`
#[must_use]
pub fn get_containing(&self, pos: Pos) -> Option<&Func> {
self.range(..=pos).next_back().filter(|func| pos < func.end_pos)
// Find the first data that includes `pos`.
self.range(..=pos).find(|func| func.contains(pos))
}
/// Retrieves a function that starting at `pos`
/// Retrieves the function at `pos`
#[must_use]
pub fn get_starting_at(&self, pos: Pos) -> Option<&Func> {
self.range(pos..=pos).next()
self.get_containing(pos).filter(|func| func.start_pos == pos)
}
/// Returns a range of functions

View File

@@ -136,7 +136,7 @@ impl<'a> InstFmt for Inst<'a> {
match self {
Self::Basic(inst) => inst.fmt(pos, f),
Self::Pseudo(inst) => inst.fmt(pos, f),
Self::Directive(directive) => directive.fmt(pos, f),
Self::Directive(directive) => <Directive as InstFmt>::fmt(directive, pos, f),
}
}
}

View File

@@ -1,7 +1,7 @@
//! Directives
// Imports
use super::{InstFmt, InstSize};
use super::{InstFmt, InstSize, InstTargetFmt};
use crate::exe::{DataType, Pos};
use ascii::{AsciiChar, AsciiStr};
use dcb_util::NextFromBytes;
@@ -157,6 +157,19 @@ impl<'a> InstFmt for Directive<'a> {
}
}
impl<'a> InstTargetFmt for Directive<'a> {
fn fmt(&self, _pos: Pos, target: impl std::fmt::Display, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Dw(_) => write!(f, "dw {target}"),
Self::Dh(_) => write!(f, "dh {target}"),
Self::Db(_) => write!(f, "db {target}"),
Self::Ascii(_) => write!(f, ".ascii {target}"),
}
}
}
/// Reads an ascii string from a byte slice until null, aligned to a word
#[allow(clippy::as_conversions, clippy::cast_possible_truncation)] // Our length will always fit into a `u32`.
fn read_ascii_until_null(bytes: &[u8]) -> Option<&AsciiStr> {