aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-01-15 01:14:50 -0800
committeriximeow <me@iximeow.net>2020-01-15 01:14:50 -0800
commit894cba0dde913d86472430eae8b7ba0353711b4e (patch)
tree3c0f4eea33a8c0c1db60a1d843cd72702a7be633
parentf0869a1e2fbbdc50f6b020f088da020463e177da (diff)
no_std!!
this makes yaxpeax-arch no_std. generally nothing has changed w.r.t downstream crates, but a lot to do with colorization has been moved tweaked to make it no_std-friendly (specifically, allowing `termion` to be an optional dependency) this also makes address parsing optional, in the hopes that decode-only use cases don't need to involve as much machinery when building.
-rw-r--r--Cargo.toml14
-rw-r--r--src/address/mod.rs163
-rw-r--r--src/color.rs386
-rw-r--r--src/display.rs151
-rw-r--r--src/lib.rs498
5 files changed, 666 insertions, 546 deletions
diff --git a/Cargo.toml b/Cargo.toml
index efe935c..f2430f6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,16 +10,20 @@ repository = "https://git.iximeow.net/yaxpeax-arch/"
version = "0.0.1"
[dependencies]
-"num-traits" = "0.2"
-"termion" = "1.4.0"
-"serde" = "1.0"
+"num-traits" = { version = "0.2", default-features = false }
+"termion" = { version = "1.4.0", optional = true }
+"serde" = { version = "1.0", optional = true }
[profile.release]
lto = true
[features]
-default = []
+default = ["use-serde", "colors", "address-parse"]
# enables the (optional) use of Serde for bounds on
# Arch and Arch::Address
-use-serde = []
+use-serde = ["serde"]
+
+colors = ["termion"]
+
+address-parse = []
diff --git a/src/address/mod.rs b/src/address/mod.rs
new file mode 100644
index 0000000..7146d01
--- /dev/null
+++ b/src/address/mod.rs
@@ -0,0 +1,163 @@
+use core::hash::Hash;
+
+use core::fmt::{self, Debug, Display, Formatter};
+
+use core::ops::{Add, Sub, AddAssign, SubAssign};
+
+use num_traits::identities;
+use num_traits::{Bounded, WrappingAdd, WrappingSub, CheckedAdd, CheckedSub};
+
+#[cfg(feature="use-serde")]
+use serde::{Deserialize, Serialize};
+
+pub trait AddressBase where Self:
+ Debug + Display + AddressDisplay +
+ Copy + Clone + Sized + Hash +
+ Ord + Eq + PartialEq + Bounded +
+ Add<Output=Self> + Sub<Output=Self> +
+ AddAssign + SubAssign +
+ WrappingAdd + WrappingSub +
+ CheckedAdd + CheckedSub +
+ Hash +
+ identities::One + identities::Zero {
+ fn to_linear(&self) -> usize;
+}
+
+#[cfg(all(feature="use-serde", feature="address-parse"))]
+pub trait Address where Self:
+ AddressBase +
+ Serialize + for<'de> Deserialize<'de> +
+ AddrParse {
+}
+
+#[cfg(all(feature="use-serde", not(feature="address-parse")))]
+pub trait Address where Self:
+ AddressBase +
+ Serialize + for<'de> Deserialize<'de> {
+}
+
+#[cfg(all(not(feature="use-serde"), feature="address-parse"))]
+pub trait Address where Self:
+ AddressBase + AddrParse {
+}
+
+#[cfg(all(not(feature="use-serde"), not(feature="address-parse")))]
+pub trait Address where Self: AddressBase { }
+
+impl AddressBase for u16 {
+ fn to_linear(&self) -> usize { *self as usize }
+}
+
+impl Address for u16 {}
+
+impl AddressBase for u32 {
+ fn to_linear(&self) -> usize { *self as usize }
+}
+
+impl Address for u32 {}
+
+impl AddressBase for u64 {
+ fn to_linear(&self) -> usize { *self as usize }
+}
+
+impl Address for u64 {}
+
+impl AddressBase for usize {
+ fn to_linear(&self) -> usize { *self }
+}
+
+impl Address for usize {}
+
+pub trait AddressDisplay {
+ fn show(&self, f: &mut Formatter) -> fmt::Result;
+}
+
+impl AddressDisplay for usize {
+ fn show(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{:#x}", self)
+ }
+}
+
+impl AddressDisplay for u64 {
+ fn show(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{:#x}", self)
+ }
+}
+
+impl AddressDisplay for u32 {
+ fn show(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{:#x}", self)
+ }
+}
+
+impl AddressDisplay for u16 {
+ fn show(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{:#x}", self)
+ }
+}
+
+/*
+ * TODO: this should be FromStr.
+ * that would require newtyping address primitives, though
+ *
+ * this is not out of the question, BUT is way more work than
+ * i want to put in right now
+ *
+ * this is one of those "clean it up later" situations
+ */
+#[cfg(feature="address-parse")]
+use core::str::FromStr;
+
+#[cfg(feature="address-parse")]
+pub trait AddrParse: Sized {
+ type Err;
+ fn parse_from(s: &str) -> Result<Self, Self::Err>;
+}
+
+#[cfg(feature="address-parse")]
+impl AddrParse for usize {
+ type Err = core::num::ParseIntError;
+ fn parse_from(s: &str) -> Result<Self, Self::Err> {
+ if s.starts_with("0x") {
+ usize::from_str_radix(&s[2..], 16)
+ } else {
+ usize::from_str(s)
+ }
+ }
+}
+
+#[cfg(feature="address-parse")]
+impl AddrParse for u64 {
+ type Err = core::num::ParseIntError;
+ fn parse_from(s: &str) -> Result<Self, Self::Err> {
+ if s.starts_with("0x") {
+ u64::from_str_radix(&s[2..], 16)
+ } else {
+ u64::from_str(s)
+ }
+ }
+}
+
+#[cfg(feature="address-parse")]
+impl AddrParse for u32 {
+ type Err = core::num::ParseIntError;
+ fn parse_from(s: &str) -> Result<Self, Self::Err> {
+ if s.starts_with("0x") {
+ u32::from_str_radix(&s[2..], 16)
+ } else {
+ u32::from_str(s)
+ }
+ }
+}
+
+#[cfg(feature="address-parse")]
+impl AddrParse for u16 {
+ type Err = core::num::ParseIntError;
+ fn parse_from(s: &str) -> Result<Self, Self::Err> {
+ if s.starts_with("0x") {
+ u16::from_str_radix(&s[2..], 16)
+ } else {
+ u16::from_str(s)
+ }
+ }
+}
diff --git a/src/color.rs b/src/color.rs
new file mode 100644
index 0000000..4bcbd15
--- /dev/null
+++ b/src/color.rs
@@ -0,0 +1,386 @@
+use core::fmt::{self, Display, Formatter};
+
+pub enum Colored<T: Display, Colorer: Display> {
+ Color(T, Colorer, Colorer),
+ Just(T)
+}
+
+impl <T: Display, Colorer: Display> Display for Colored<T, Colorer> {
+ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
+ match self {
+ Colored::Color(t, before, after) => {
+ write!(fmt, "{}{}{}", before, t, after)
+ },
+ Colored::Just(t) => {
+ write!(fmt, "{}", t)
+ }
+ }
+ }
+}
+
+pub trait YaxColors<Color: Display> {
+ fn arithmetic_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn stack_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn nop_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn stop_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn control_flow_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn data_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn comparison_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn invalid_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn platform_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn misc_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+
+ fn register<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn program_counter<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn number<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn zero<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn one<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn minus_one<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn address<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn symbol<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn function<T: Display>(&self, t: T) -> Colored<T, Color>;
+}
+
+pub struct NoColors;
+
+impl YaxColors<&'static str> for NoColors {
+ fn arithmetic_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn stack_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn nop_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn stop_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn control_flow_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn data_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn comparison_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn invalid_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn platform_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn misc_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn register<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn program_counter<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn number<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn zero<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn one<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn minus_one<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn address<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn symbol<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn function<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+}
+
+pub trait Colorize<T: fmt::Write, Color: Display, Y: YaxColors<Color> + ?Sized> {
+ fn colorize(&self, colors: &Y, out: &mut T) -> fmt::Result;
+}
+
+#[cfg(feature="colors")]
+pub use termion_color::ColorSettings;
+
+#[cfg(feature="colors")]
+mod termion_color {
+ use core::fmt::Display;
+
+ use termion::color;
+ use serde::Serialize;
+
+ use crate::color::{Colored, YaxColors};
+
+ #[cfg(feature="use-serde")]
+ impl Serialize for ColorSettings {
+ fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+ use serde::ser::SerializeStruct;
+ let s = serializer.serialize_struct("ColorSettings", 0)?;
+ s.end()
+ }
+ }
+
+ pub struct ColorSettings {
+ arithmetic: color::Fg<&'static dyn color::Color>,
+ stack: color::Fg<&'static dyn color::Color>,
+ nop: color::Fg<&'static dyn color::Color>,
+ stop: color::Fg<&'static dyn color::Color>,
+ control: color::Fg<&'static dyn color::Color>,
+ data: color::Fg<&'static dyn color::Color>,
+ comparison: color::Fg<&'static dyn color::Color>,
+ invalid: color::Fg<&'static dyn color::Color>,
+ platform: color::Fg<&'static dyn color::Color>,
+ misc: color::Fg<&'static dyn color::Color>,
+
+ register: color::Fg<&'static dyn color::Color>,
+ program_counter: color::Fg<&'static dyn color::Color>,
+
+ number: color::Fg<&'static dyn color::Color>,
+ zero: color::Fg<&'static dyn color::Color>,
+ one: color::Fg<&'static dyn color::Color>,
+ minus_one: color::Fg<&'static dyn color::Color>,
+
+ function: color::Fg<&'static dyn color::Color>,
+ symbol: color::Fg<&'static dyn color::Color>,
+ address: color::Fg<&'static dyn color::Color>,
+ }
+
+ #[cfg(feature="colorize")]
+ impl Default for ColorSettings {
+ fn default() -> ColorSettings {
+ ColorSettings {
+ arithmetic: color::Fg(&color::LightYellow),
+ stack: color::Fg(&color::Magenta),
+ nop: color::Fg(&color::Blue),
+ stop: color::Fg(&color::LightRed),
+ control: color::Fg(&color::Green),
+ data: color::Fg(&color::LightMagenta),
+ comparison: color::Fg(&color::Yellow),
+ invalid: color::Fg(&color::Red),
+ platform: color::Fg(&color::Cyan),
+ misc: color::Fg(&color::LightCyan),
+
+ register: color::Fg(&color::Cyan),
+ program_counter: color::Fg(&color::Red),
+
+ number: color::Fg(&color::White),
+ zero: color::Fg(&color::White),
+ one: color::Fg(&color::White),
+ minus_one: color::Fg(&color::White),
+
+ function: color::Fg(&color::LightGreen),
+ symbol: color::Fg(&color::LightGreen),
+ address: color::Fg(&color::Green),
+ }
+ }
+ }
+
+ impl YaxColors<color::Fg<&'static dyn color::Color>> for ColorSettings {
+ fn arithmetic_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.arithmetic, color::Fg(&color::Reset))
+ }
+ fn stack_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.stack, color::Fg(&color::Reset))
+ }
+ fn nop_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.nop, color::Fg(&color::Reset))
+ }
+ fn stop_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.stop, color::Fg(&color::Reset))
+ }
+ fn control_flow_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.control, color::Fg(&color::Reset))
+ }
+ fn data_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.data, color::Fg(&color::Reset))
+ }
+ fn comparison_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.comparison, color::Fg(&color::Reset))
+ }
+ fn invalid_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.invalid, color::Fg(&color::Reset))
+ }
+ fn misc_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.misc, color::Fg(&color::Reset))
+ }
+ fn platform_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.platform, color::Fg(&color::Reset))
+ }
+
+ fn register<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.register, color::Fg(&color::Reset))
+ }
+ fn program_counter<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.program_counter, color::Fg(&color::Reset))
+ }
+ fn number<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.number, color::Fg(&color::Reset))
+ }
+ fn zero<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.zero, color::Fg(&color::Reset))
+ }
+ fn one<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.one, color::Fg(&color::Reset))
+ }
+ fn minus_one<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.minus_one, color::Fg(&color::Reset))
+ }
+ fn address<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.address, color::Fg(&color::Reset))
+ }
+ fn symbol<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.symbol, color::Fg(&color::Reset))
+ }
+ fn function<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.function, color::Fg(&color::Reset))
+ }
+ }
+
+ impl <'a> YaxColors<color::Fg<&'static dyn color::Color>>for Option<&'a ColorSettings> {
+ fn arithmetic_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.arithmetic_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn stack_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.stack_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn nop_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.nop_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn stop_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.stop_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn control_flow_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.control_flow_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn data_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.data_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn comparison_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.comparison_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn invalid_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.invalid_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn misc_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.misc_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn platform_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.platform_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+
+ fn register<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.register(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn program_counter<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.program_counter(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn number<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.number(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn zero<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.zero(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn one<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.one(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn minus_one<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.minus_one(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn address<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.address(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn symbol<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.symbol(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn function<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.function(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ }
+}
+
+/*
+ * can this be a derivable trait or something?
+ */
+/*
+impl <T: Colorize> Display for T {
+ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
+ self.colorize(None, fmt)
+ }
+}
+*/
+
+/*
+ * and make this auto-derive from a ShowContextual impl?
+ */
+/*
+impl <T, U> Colorize for T where T: ShowContextual<Ctx=U> {
+ fn colorize(&self, colors: Option<&ColorSettings>, fmt: &mut Formatter) -> fmt::Result {
+ self.contextualize(colors, None, fmt)
+ }
+}
+*/
diff --git a/src/display.rs b/src/display.rs
index 5ba9cd1..50d63d5 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -1,3 +1,9 @@
+use crate::YaxColors;
+
+use core::fmt;
+use core::num::Wrapping;
+use core::ops::Neg;
+
pub enum NumberStyleHint {
Signed,
HexSigned,
@@ -11,105 +17,120 @@ pub enum NumberStyleHint {
HexUnsignedWithSign
}
-pub fn format_number_i32(i: i32, hint: NumberStyleHint) -> String {
+pub fn format_number_i32<W: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>>(colors: &Y, f: &mut W, i: i32, hint: NumberStyleHint) -> fmt::Result {
match hint {
NumberStyleHint::Signed => {
- format!("{}", i)
+ write!(f, "{}", colors.number(i))
},
NumberStyleHint::HexSigned => {
- if i == std::i32::MIN {
- format!("-0x7fffffff")
- } else if i < 0 {
- format!("-{:#x}", -i)
- } else {
- format!("{:#x}", i)
- }
+ write!(f, "{}", colors.number(signed_i32_hex(i)))
},
NumberStyleHint::Unsigned => {
- format!("{}", i as u32)
+ write!(f, "{}", colors.number(i as u32))
},
NumberStyleHint::HexUnsigned => {
- format!("{:#x}", i as u32)
+ write!(f, "{}", colors.number(u32_hex(i as u32)))
},
NumberStyleHint::SignedWithSignSplit => {
- if i == std::i32::MIN {
- format!("- 2147483647")
+ if i == core::i32::MIN {
+ write!(f, "- {}", colors.number("2147483647"))
} else if i < 0 {
- format!("- {}", -i)
+ write!(f, "- {}", colors.number(-Wrapping(i)))
} else {
- format!("+ {}", i)
+ write!(f, "+ {}", colors.number(i))
}
}
NumberStyleHint::HexSignedWithSignSplit => {
- if i == std::i32::MIN {
- format!("- 0x7fffffff")
+ if i == core::i32::MIN {
+ write!(f, "- {}", colors.number("0x7fffffff"))
} else if i < 0 {
- format!("- {:#x}", -i)
+ write!(f, "- {}", colors.number(u32_hex((-Wrapping(i)).0 as u32)))
} else {
- format!("+ {:#x}", i)
+ write!(f, "+ {}", colors.number(u32_hex(i as u32)))
}
},
NumberStyleHint::HexSignedWithSign => {
- if i == std::i32::MIN {
- format!("-0x7fffffff")
- } else if i < 0 {
- format!("-{:#x}", -i)
- } else {
- format!("+{:#x}", i)
- }
+ write!(f, "{}", signed_i32_hex(i))
},
NumberStyleHint::SignedWithSign => {
- format!("{:+}", i)
+ write!(f, "{:+}", i)
}
NumberStyleHint::HexUnsignedWithSign => {
- format!("{:+#x}", i as u32)
+ write!(f, "{:+#x}", i as u32)
},
NumberStyleHint::UnsignedWithSign => {
- format!("{:+}", i as u32)
+ write!(f, "{:+}", i as u32)
}
}
}
-pub fn signed_i8_hex(imm: i8) -> String {
- let (sign, imm) = if imm == std::i8::MIN {
- (false, imm)
- } else if imm < 0 {
- (true, -imm)
- } else {
- (false, imm)
- };
- format!("{}{:#x}", if sign { "-" } else { "" } , imm)
+pub struct SignedHexDisplay<T: core::fmt::LowerHex + Neg> {
+ value: T,
+ negative: bool
+}
+
+impl<T: fmt::LowerHex + Neg + Copy> fmt::Display for SignedHexDisplay<T> where Wrapping<T>: Neg, <Wrapping<T> as Neg>::Output: fmt::LowerHex {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if self.negative {
+ write!(f, "-{:#x}", -Wrapping(self.value))
+ } else {
+ write!(f, "{:#x}", self.value)
+ }
+ }
+}
+
+pub fn u8_hex(value: u8) -> SignedHexDisplay<i8> {
+ SignedHexDisplay {
+ value: value as i8,
+ negative: false,
+ }
+}
+
+pub fn signed_i8_hex(imm: i8) -> SignedHexDisplay<i8> {
+ SignedHexDisplay {
+ value: imm,
+ negative: imm < 0,
+ }
+}
+
+pub fn u16_hex(value: u16) -> SignedHexDisplay<i16> {
+ SignedHexDisplay {
+ value: value as i16,
+ negative: false,
+ }
}
-pub fn signed_i16_hex(imm: i16) -> String {
- let (sign, imm) = if imm == std::i16::MIN {
- (false, imm)
- } else if imm < 0 {
- (true, -imm)
- } else {
- (false, imm)
- };
- format!("{}{:#x}", if sign { "-" } else { "" } , imm)
+pub fn signed_i16_hex(imm: i16) -> SignedHexDisplay<i16> {
+ SignedHexDisplay {
+ value: imm,
+ negative: imm < 0,
+ }
}
-pub fn signed_i32_hex(imm: i32) -> String {
- let (sign, imm) = if imm == std::i32::MIN {
- (false, imm)
- } else if imm < 0 {
- (true, -imm)
- } else {
- (false, imm)
- };
- format!("{}{:#x}", if sign { "-" } else { "" } , imm)
+pub fn u32_hex(value: u32) -> SignedHexDisplay<i32> {
+ SignedHexDisplay {
+ value: value as i32,
+ negative: false,
+ }
}
-pub fn signed_i64_hex(imm: i64) -> String {
- let (sign, imm) = if imm == std::i64::MIN {
- (false, imm)
- } else if imm < 0 {
- (true, -imm)
- } else {
- (false, imm)
- };
- format!("{}{:#x}", if sign { "-" } else { "" } , imm)
+pub fn signed_i32_hex(imm: i32) -> SignedHexDisplay<i32> {
+ SignedHexDisplay {
+ value: imm,
+ negative: imm < 0,
+ }
+}
+
+pub fn u64_hex(value: u64) -> SignedHexDisplay<i64> {
+ SignedHexDisplay {
+ value: value as i64,
+ negative: false,
+ }
+}
+
+pub fn signed_i64_hex(imm: i64) -> SignedHexDisplay<i64> {
+ SignedHexDisplay {
+ value: imm,
+ negative: imm < 0,
+ }
}
diff --git a/src/lib.rs b/src/lib.rs
index c5b0610..f503741 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,163 +1,31 @@
-extern crate num_traits;
-extern crate termion;
-#[cfg(feature="use-serde")]
-extern crate serde;
-
-use std::str::FromStr;
-use std::hash::Hash;
+#![no_std]
-use std::fmt::{Debug, Display, Formatter};
+#[cfg(feature = "std")]
+#[macro_use]
+extern crate std;
-use std::ops::{Add, Sub, AddAssign, SubAssign};
-
-use num_traits::identities;
-use num_traits::{Bounded, WrappingAdd, WrappingSub, CheckedAdd, CheckedSub};
-
-use termion::color;
+use core::fmt::{self, Debug, Display};
+use core::hash::Hash;
+extern crate num_traits;
#[cfg(feature="use-serde")]
-use serde::{Serialize, Deserialize};
-
-pub mod display;
- // This is pretty wonk..
-pub trait AddressDisplay {
- fn stringy(&self) -> String;
-}
-
-/*
- * TODO: this should be FromStr.
- * that would require newtyping address primitives, though
- *
- * this is not out of the question, BUT is way more work than
- * i want to put in right now
- *
- * this is one of those "clean it up later" situations
- */
-pub trait AddrParse: Sized {
- type Err;
- fn parse_from(s: &str) -> Result<Self, Self::Err>;
-}
+extern crate serde;
+#[cfg(feature="colors")]
+extern crate termion;
#[cfg(feature="use-serde")]
-pub trait Address where Self:
- Serialize + for<'de> Deserialize<'de> +
- Debug + Display + AddressDisplay +
- Copy + Clone + Sized + Hash +
- Ord + Eq + PartialEq + Bounded +
- Add<Output=Self> + Sub<Output=Self> +
- AddAssign + SubAssign +
- WrappingAdd + WrappingSub +
- CheckedAdd + CheckedSub +
- AddrParse +
- Hash +
- identities::One + identities::Zero {
- fn to_linear(&self) -> usize;
-
-}
-#[cfg(not(feature="use-serde"))]
-pub trait Address where Self:
- Debug + Display + AddressDisplay +
- Copy + Clone + Sized + Hash +
- Ord + Eq + PartialEq + Bounded +
- Add<Output=Self> + Sub<Output=Self> +
- AddAssign + SubAssign +
- WrappingAdd + WrappingSub +
- CheckedAdd + CheckedSub +
- AddrParse +
- Hash +
- identities::One + identities::Zero {
- fn to_linear(&self) -> usize;
-
-}
-/*
-impl <T> Address for T where T: Sized + Ord + Add<Output=Self> + From<u16> + Into<usize> {
- fn to_linear(&self) -> usize { *self.into() }
-}
-*/
-
-impl AddrParse for usize {
- type Err = std::num::ParseIntError;
- fn parse_from(s: &str) -> Result<Self, Self::Err> {
- if s.starts_with("0x") {
- usize::from_str_radix(&s[2..], 16)
- } else {
- usize::from_str(s)
- }
- }
-}
-
-impl AddressDisplay for usize {
- fn stringy(&self) -> String {
- format!("{:#x}", self)
- }
-}
-
-impl AddrParse for u64 {
- type Err = std::num::ParseIntError;
- fn parse_from(s: &str) -> Result<Self, Self::Err> {
- if s.starts_with("0x") {
- u64::from_str_radix(&s[2..], 16)
- } else {
- u64::from_str(s)
- }
- }
-}
-
-impl AddressDisplay for u64 {
- fn stringy(&self) -> String {
- format!("{:#x}", self)
- }
-}
-
-impl AddrParse for u32 {
- type Err = std::num::ParseIntError;
- fn parse_from(s: &str) -> Result<Self, Self::Err> {
- if s.starts_with("0x") {
- u32::from_str_radix(&s[2..], 16)
- } else {
- u32::from_str(s)
- }
- }
-}
-
-impl AddressDisplay for u32 {
- fn stringy(&self) -> String {
- format!("{:#x}", self)
- }
-}
-
-impl AddrParse for u16 {
- type Err = std::num::ParseIntError;
- fn parse_from(s: &str) -> Result<Self, Self::Err> {
- if s.starts_with("0x") {
- u16::from_str_radix(&s[2..], 16)
- } else {
- u16::from_str(s)
- }
- }
-}
-
-impl AddressDisplay for u16 {
- fn stringy(&self) -> String {
- format!("{:#x}", self)
- }
-}
+use serde::{Serialize, Deserialize};
-impl Address for u16 {
- fn to_linear(&self) -> usize { *self as usize }
-}
+mod address;
+pub use address::{Address, AddressBase};
-impl Address for u32 {
- fn to_linear(&self) -> usize { *self as usize }
-}
+mod color;
+pub use color::{Colorize, NoColors, YaxColors};
-impl Address for u64 {
- fn to_linear(&self) -> usize { *self as usize }
-}
+#[cfg(feature="colors")]
+pub use color::ColorSettings;
-impl Address for usize {
- fn to_linear(&self) -> usize { *self }
-}
+pub mod display;
pub trait DecodeError {
fn data_exhausted(&self) -> bool;
@@ -204,335 +72,13 @@ pub trait Instruction {
fn well_defined(&self) -> bool;
}
-#[cfg(feature="use-serde")]
-impl Serialize for ColorSettings {
- fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
- use serde::ser::SerializeStruct;
- let s = serializer.serialize_struct("ColorSettings", 0)?;
- s.end()
- }
-}
-
-#[allow(dead_code)]
-pub struct ColorSettings {
- arithmetic: color::Fg<&'static dyn color::Color>,
- stack: color::Fg<&'static dyn color::Color>,
- nop: color::Fg<&'static dyn color::Color>,
- stop: color::Fg<&'static dyn color::Color>,
- control: color::Fg<&'static dyn color::Color>,
- data: color::Fg<&'static dyn color::Color>,
- comparison: color::Fg<&'static dyn color::Color>,
- invalid: color::Fg<&'static dyn color::Color>,
- platform: color::Fg<&'static dyn color::Color>,
- misc: color::Fg<&'static dyn color::Color>,
-
- register: color::Fg<&'static dyn color::Color>,
- program_counter: color::Fg<&'static dyn color::Color>,
-
- number: color::Fg<&'static dyn color::Color>,
- zero: color::Fg<&'static dyn color::Color>,
- one: color::Fg<&'static dyn color::Color>,
- minus_one: color::Fg<&'static dyn color::Color>,
-
- function: color::Fg<&'static dyn color::Color>,
- symbol: color::Fg<&'static dyn color::Color>,
- address: color::Fg<&'static dyn color::Color>
-}
-
-impl Default for ColorSettings {
- fn default() -> ColorSettings {
- ColorSettings {
- /*
- arithmetic: color::Fg(&color::LightYellow),
- stack: color::Fg(&color::Magenta),
- nop: color::Fg(&color::Blue),
- stop: color::Fg(&color::LightRed),
- control: color::Fg(&color::Green),
- data: color::Fg(&color::LightMagenta),
- comparison: color::Fg(&color::Yellow),
- invalid: color::Fg(&color::Red),
- platform: color::Fg(&color::Cyan),
- misc: color::Fg(&color::LightCyan),
- */
- arithmetic: color::Fg(&color::Yellow),
- stack: color::Fg(&color::Magenta),
- nop: color::Fg(&color::Blue),
- stop: color::Fg(&color::Red),
- control: color::Fg(&color::Red),
- data: color::Fg(&color::Yellow),
- comparison: color::Fg(&color::Yellow),
- invalid: color::Fg(&color::Red),
- platform: color::Fg(&color::LightBlue),
- misc: color::Fg(&color::LightCyan),
-
- register: color::Fg(&color::Cyan),
- program_counter: color::Fg(&color::Red),
-
- number: color::Fg(&color::White),
- zero: color::Fg(&color::White),
- one: color::Fg(&color::White),
- minus_one: color::Fg(&color::White),
-
- function: color::Fg(&color::LightGreen),
- symbol: color::Fg(&color::LightGreen),
- address: color::Fg(&color::Green)
- }
- }
-}
-
-pub trait YaxColors {
- fn arithmetic_op<T: Display>(&self, t: T) -> Colored<T>;
- fn stack_op<T: Display>(&self, t: T) -> Colored<T>;
- fn nop_op<T: Display>(&self, t: T) -> Colored<T>;
- fn stop_op<T: Display>(&self, t: T) -> Colored<T>;
- fn control_flow_op<T: Display>(&self, t: T) -> Colored<T>;
- fn data_op<T: Display>(&self, t: T) -> Colored<T>;
- fn comparison_op<T: Display>(&self, t: T) -> Colored<T>;
- fn invalid_op<T: Display>(&self, t: T) -> Colored<T>;
- fn platform_op<T: Display>(&self, t: T) -> Colored<T>;
- fn misc_op<T: Display>(&self, t: T) -> Colored<T>;
-
- fn register<T: Display>(&self, t: T) -> Colored<T>;
- fn program_counter<T: Display>(&self, t: T) -> Colored<T>;
- fn number<T: Display>(&self, t: T) -> Colored<T>;
- fn zero<T: Display>(&self, t: T) -> Colored<T>;
- fn one<T: Display>(&self, t: T) -> Colored<T>;
- fn minus_one<T: Display>(&self, t: T) -> Colored<T>;
- fn address<T: Display>(&self, t: T) -> Colored<T>;
- fn symbol<T: Display>(&self, t: T) -> Colored<T>;
- fn function<T: Display>(&self, t: T) -> Colored<T>;
-}
-
-impl YaxColors for ColorSettings {
- fn arithmetic_op<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.arithmetic)
- }
- fn stack_op<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.stack)
- }
- fn nop_op<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.nop)
- }
- fn stop_op<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.stop)
- }
- fn control_flow_op<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.control)
- }
- fn data_op<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.data)
- }
- fn comparison_op<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.comparison)
- }
- fn invalid_op<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.invalid)
- }
- fn misc_op<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.misc)
- }
- fn platform_op<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.platform)
- }
-
- fn register<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.register)
- }
- fn program_counter<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.program_counter)
- }
- fn number<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.number)
- }
- fn zero<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.zero)
- }
- fn one<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.one)
- }
- fn minus_one<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.minus_one)
- }
- fn address<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.address)
- }
- fn symbol<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.symbol)
- }
- fn function<T: Display>(&self, t: T) -> Colored<T> {
- Colored::Color(t, self.function)
- }
-}
-
-impl <'a> YaxColors for Option<&'a ColorSettings> {
- fn arithmetic_op<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.arithmetic_op(t) }
- None => { Colored::Just(t) }
- }
- }
- fn stack_op<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.stack_op(t) }
- None => { Colored::Just(t) }
- }
- }
- fn nop_op<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.nop_op(t) }
- None => { Colored::Just(t) }
- }
- }
- fn stop_op<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.stop_op(t) }
- None => { Colored::Just(t) }
- }
- }
- fn control_flow_op<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.control_flow_op(t) }
- None => { Colored::Just(t) }
- }
- }
- fn data_op<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.data_op(t) }
- None => { Colored::Just(t) }
- }
- }
- fn comparison_op<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.comparison_op(t) }
- None => { Colored::Just(t) }
- }
- }
- fn invalid_op<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.invalid_op(t) }
- None => { Colored::Just(t) }
- }
- }
- fn misc_op<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.misc_op(t) }
- None => { Colored::Just(t) }
- }
- }
- fn platform_op<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.platform_op(t) }
- None => { Colored::Just(t) }
- }
- }
-
- fn register<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.register(t) }
- None => { Colored::Just(t) }
- }
- }
- fn program_counter<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.program_counter(t) }
- None => { Colored::Just(t) }
- }
- }
- fn number<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.number(t) }
- None => { Colored::Just(t) }
- }
- }
- fn zero<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.zero(t) }
- None => { Colored::Just(t) }
- }
- }
- fn one<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.one(t) }
- None => { Colored::Just(t) }
- }
- }
- fn minus_one<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.minus_one(t) }
- None => { Colored::Just(t) }
- }
- }
- fn address<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.address(t) }
- None => { Colored::Just(t) }
- }
- }
- fn symbol<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.symbol(t) }
- None => { Colored::Just(t) }
- }
- }
- fn function<T: Display>(&self, t: T) -> Colored<T> {
- match self {
- Some(colors) => { colors.function(t) }
- None => { Colored::Just(t) }
- }
- }
-}
-
-pub enum Colored<T: Display> {
- Color(T, color::Fg<&'static dyn color::Color>),
- Just(T)
-}
-
-impl <T: Display> Display for Colored<T> {
- fn fmt(&self, fmt: &mut Formatter) -> std::fmt::Result {
- match self {
- Colored::Color(t, color) => {
- write!(fmt, "{}{}{}", color, t, color::Fg(color::Reset))
- },
- Colored::Just(t) => {
- write!(fmt, "{}", t)
- }
- }
- }
-}
-
-/*
- * can this be a derivable trait or something?
- */
-/*
-impl <T: Colorize> Display for T {
- fn fmt(&self, fmt: &mut Formatter) -> std::fmt::Result {
- self.colorize(None, fmt)
- }
-}
-*/
-
-pub trait Colorize<T: std::fmt::Write> {
- fn colorize(&self, colors: Option<&ColorSettings>, out: &mut T) -> std::fmt::Result;
-}
-
-/*
- * and make this auto-derive from a ShowContextual impl?
- */
-/*
-impl <T, U> Colorize for T where T: ShowContextual<Ctx=U> {
- fn colorize(&self, colors: Option<&ColorSettings>, fmt: &mut Formatter) -> std::fmt::Result {
- self.contextualize(colors, None, fmt)
- }
-}
-*/
-
-pub trait ShowContextual<Addr, Ctx: ?Sized, T: std::fmt::Write> {
- fn contextualize(&self, colors: Option<&ColorSettings>, address: Addr, context: Option<&Ctx>, out: &mut T) -> std::fmt::Result;
+pub trait ShowContextual<Addr, Ctx: ?Sized, Color: Display, T: fmt::Write, Y: YaxColors<Color>> {
+ fn contextualize(&self, colors: &Y, address: Addr, context: Option<&Ctx>, out: &mut T) -> fmt::Result;
}
/*
-impl <C: ?Sized, T: std::fmt::Write, U: Colorize<T>> ShowContextual<C, T> for U {
- fn contextualize(&self, colors: Option<&ColorSettings>, context: Option<&C>, out: &mut T) -> std::fmt::Result {
+impl <C: ?Sized, T: fmt::Write, U: Colorize<T>> ShowContextual<C, T> for U {
+ fn contextualize(&self, colors: Option<&ColorSettings>, context: Option<&C>, out: &mut T) -> fmt::Result {
self.colorize(colors, out)
}
}