Expand description
Represents an interval of values x..y
(much like Range<usize>
)
which supports various arithmetic operations.
Fields§
§start: usize
§end: usize
Implementations§
source§impl Interval
impl Interval
sourcepub fn is_constant(&self) -> bool
pub fn is_constant(&self) -> bool
Check whether this interval represents a constant value. For
example, the interval 1..1
represents the constant 1
.
sourcepub fn add(&self, val: usize) -> Self
pub fn add(&self, val: usize) -> Self
Add a constant to this range.
Examples found in repository?
src/dfa/stack.rs (line 98)
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
pub fn len(&self) -> Interval {
self.lower.add(self.upper.len())
}
/// Determine the minimum length of any stack represented by this
/// abstract stack.
pub fn min_len(&self) -> usize {
self.lower.start + self.upper.len()
}
/// Determine the maximum length of any stack represented by this
/// abstract stack.
pub fn max_len(&self) -> usize {
self.lower.end + self.upper.len()
}
/// Push an iterm onto this stack.
pub fn push(mut self, val: AbstractValue) -> Self {
// Should never be called on bottom
assert!(!self.is_bottom());
//
if val == AbstractValue::Unknown && self.upper.len() == 0 {
self.lower = self.lower.add(1);
} else {
// Pop target address off the stack.
self.upper.push(val);
}
// Done
self
}
/// Pop an item of this stack, producing an updated state.
pub fn pop(mut self) -> Self {
// Should never be called on bottom
assert!(!self.is_bottom());
// Pop target address off the stack.
if self.upper.is_empty() {
self.lower = self.lower.sub(1);
} else {
self.upper.pop();
}
// Done
self
}
/// Perk nth item on the stack (where `0` is top).
pub fn peek(&self, n: usize) -> AbstractValue {
// Should never be called on bottom
assert!(!self.is_bottom());
// Get the nth value!
if n < self.upper.len() {
// Determine stack index
let i = self.upper.len() - (1+n);
// Extract value
self.upper[i]
} else {
AbstractValue::Unknown
}
}
/// Set specific item on this stack.
pub fn set(mut self, n: usize, val: AbstractValue) -> Self {
// Should never be called on bottom
assert!(!self.is_bottom());
if n < self.upper.len() {
// Determine stack index
let i = self.upper.len() - (1+n);
// Set value
self.upper[i] = val;
// Done
self
} else {
// This case is complicated because we need to expand the
// upper portion to include the new value (where
// possible).
todo!("Implement me!");
}
}
/// Merge two abstract stacks together.
pub fn merge(self, other: &AbstractStack) -> Self {
let slen = self.upper.len();
let olen = other.upper.len();
// Determine common upper length
let n = cmp::min(slen,olen);
// Normalise lower segments
let lself = self.lower.add(slen - n);
let lother = other.lower.add(olen - n);
let mut merger = AbstractStack::new(lself.union(&lother),Vec::new());
// Push merged items from upper segment
for i in (0..n).rev() {
let ithself = self.peek(i);
let ithother = other.peek(i);
merger = merger.push(ithself.merge(ithother));
}
// Done
merger
}
sourcepub fn sub(&self, val: usize) -> Self
pub fn sub(&self, val: usize) -> Self
Subtract a constant from this range.
Examples found in repository?
src/dfa/stack.rs (line 130)
125 126 127 128 129 130 131 132 133 134 135 136
pub fn pop(mut self) -> Self {
// Should never be called on bottom
assert!(!self.is_bottom());
// Pop target address off the stack.
if self.upper.is_empty() {
self.lower = self.lower.sub(1);
} else {
self.upper.pop();
}
// Done
self
}
sourcepub fn union(&self, other: &Interval) -> Self
pub fn union(&self, other: &Interval) -> Self
Union this interval with another
Examples found in repository?
src/dfa/stack.rs (line 179)
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
pub fn merge(self, other: &AbstractStack) -> Self {
let slen = self.upper.len();
let olen = other.upper.len();
// Determine common upper length
let n = cmp::min(slen,olen);
// Normalise lower segments
let lself = self.lower.add(slen - n);
let lother = other.lower.add(olen - n);
let mut merger = AbstractStack::new(lself.union(&lother),Vec::new());
// Push merged items from upper segment
for i in (0..n).rev() {
let ithself = self.peek(i);
let ithother = other.peek(i);
merger = merger.push(ithself.merge(ithother));
}
// Done
merger
}
Trait Implementations§
source§impl PartialEq<Interval> for Interval
impl PartialEq<Interval> for Interval
impl Copy for Interval
impl Eq for Interval
impl StructuralEq for Interval
impl StructuralPartialEq for Interval
Auto Trait Implementations§
impl RefUnwindSafe for Interval
impl Send for Interval
impl Sync for Interval
impl Unpin for Interval
impl UnwindSafe for Interval
Blanket Implementations§
§impl<T> CloneAny for Twhere
T: Any + Clone,
impl<T> CloneAny for Twhere
T: Any + Clone,
fn clone_any(&self) -> Box<dyn CloneAny + 'static, Global>
fn clone_any_send(&self) -> Box<dyn CloneAny + Send + 'static, Global>where
T: Send,
fn clone_any_sync(&self) -> Box<dyn CloneAny + Sync + 'static, Global>where
T: Sync,
fn clone_any_send_sync(
&self
) -> Box<dyn CloneAny + Sync + Send + 'static, Global>where
T: Send + Sync,
source§impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
Compare self to
key
and return true
if they are equal.