forked from MightyPork/crsn
buffer module, replacing stacks. TODO: docs, fix parsing of "numbers tuple" in mkbfv (consumed by the conditional branch parser)
This commit is contained in:
@@ -45,6 +45,14 @@ pub enum Cond {
|
||||
Carry,
|
||||
/// Carry not set
|
||||
NotCarry,
|
||||
// Full
|
||||
Full,
|
||||
/// Not full
|
||||
NotFull,
|
||||
// Empty
|
||||
Empty,
|
||||
/// Not empty
|
||||
NotEmpty,
|
||||
}
|
||||
|
||||
pub fn parse_cond(text: &str, pos: &SourcePosition) -> Result<Cond, CrsnError> {
|
||||
@@ -59,14 +67,18 @@ pub fn parse_cond(text: &str, pos: &SourcePosition) -> Result<Cond, CrsnError> {
|
||||
"ge" | ">=" | "≥" => Cond::GreaterOrEqual,
|
||||
"pos" | "+" | ">0" => Cond::Positive,
|
||||
"neg" | "-" | "<0" => Cond::Negative,
|
||||
"npos" | "!+" | "0-" | "<=0" | "≥0" => Cond::NonPositive,
|
||||
"nneg" | "!-" | "0+" | ">=0" | "≤0" => Cond::NonNegative,
|
||||
"npos" | "0-" | "<=0" | "≥0" => Cond::NonPositive,
|
||||
"nneg" | "0+" | ">=0" | "≤0" => Cond::NonNegative,
|
||||
"c" => Cond::Carry,
|
||||
"nc" | "!c" => Cond::NotCarry,
|
||||
"nc" => Cond::NotCarry,
|
||||
"em" => Cond::Empty,
|
||||
"nem" => Cond::NotEmpty,
|
||||
"f" => Cond::Full,
|
||||
"nf" => Cond::NotFull,
|
||||
"valid" => Cond::Valid,
|
||||
"inval" => Cond::Invalid,
|
||||
"ov" | "^" => Cond::Overflow,
|
||||
"nov" | "!ov" | "!^" => Cond::NotOverflow,
|
||||
"ov" => Cond::Overflow,
|
||||
"nov" => Cond::NotOverflow,
|
||||
_ => {
|
||||
return Err(CrsnError::Parse(format!("Unknown cond: {}", text).into(), pos.clone()));
|
||||
}
|
||||
@@ -80,6 +92,10 @@ impl Display for Cond {
|
||||
Cond::NotEqual => "ne",
|
||||
Cond::Zero => "z",
|
||||
Cond::NotZero => "nz",
|
||||
Cond::Empty => "emp",
|
||||
Cond::NotEmpty => "nemp",
|
||||
Cond::Full => "full",
|
||||
Cond::NotFull => "nfull",
|
||||
Cond::Lower => "lt",
|
||||
Cond::LowerOrEqual => "le",
|
||||
Cond::Greater => "gt",
|
||||
@@ -108,6 +124,12 @@ impl Not for Cond {
|
||||
Cond::Overflow => Cond::NotOverflow,
|
||||
Cond::Carry => Cond::NotCarry,
|
||||
|
||||
Cond::Empty => Cond::NotEmpty,
|
||||
Cond::NotEmpty => Cond::Empty,
|
||||
|
||||
Cond::Full => Cond::NotFull,
|
||||
Cond::NotFull => Cond::Full,
|
||||
|
||||
Cond::Positive => Cond::NonPositive,
|
||||
Cond::Negative => Cond::NonNegative,
|
||||
Cond::NonPositive => Cond::Positive,
|
||||
|
||||
@@ -90,7 +90,7 @@ impl<'a> TokenParser<'a> {
|
||||
parse_rd(next, self.pcx)
|
||||
}
|
||||
|
||||
/// Get the next entry as read location
|
||||
/// Get the next entry as an object location
|
||||
pub fn next_rdobj(&mut self) -> Result<RdObj, CrsnError> {
|
||||
match parse_rd(self.next_or_err()?, self.pcx)? {
|
||||
Rd(RdData::RegObject(reg), Mask::FULL) => {
|
||||
|
||||
@@ -123,7 +123,7 @@ impl OpTrait for BuiltinOp {
|
||||
BuiltinOp::Delete(obj) => {
|
||||
let x = state.read(Rd::new(RdData::Register(obj.reg())))?;
|
||||
|
||||
trace!("Drop object: {:#x}", x);
|
||||
trace!("Del object: {:#x}", x);
|
||||
let mut dropped = false;
|
||||
for ex in info.program.extensions.iter() {
|
||||
if ex.drop_obj(info, state, x)?.is_some() {
|
||||
@@ -131,7 +131,7 @@ impl OpTrait for BuiltinOp {
|
||||
}
|
||||
}
|
||||
if !dropped {
|
||||
warn!("Object {:#x} to drop does not exist!", x);
|
||||
warn!("Object {:#x} to del does not exist!", x);
|
||||
state.set_flag(Cond::Invalid, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,10 @@ pub struct StatusFlags {
|
||||
pub invalid: bool,
|
||||
/// Arithmetic carry
|
||||
pub carry: bool,
|
||||
/// Buffer full
|
||||
pub full: bool,
|
||||
/// Buffer empty
|
||||
pub empty: bool,
|
||||
}
|
||||
|
||||
impl StatusFlags {
|
||||
@@ -43,6 +47,8 @@ impl StatusFlags {
|
||||
if self.overflow { val |= 0x40; }
|
||||
if self.invalid { val |= 0x80; }
|
||||
if self.carry { val |= 0x100; }
|
||||
if self.full { val |= 0x200; }
|
||||
if self.empty { val |= 0x400; }
|
||||
val
|
||||
}
|
||||
|
||||
@@ -56,6 +62,8 @@ impl StatusFlags {
|
||||
if val & 0x40 != 0 { self.overflow = true; }
|
||||
if val & 0x80 != 0 { self.invalid = true; }
|
||||
if val & 0x100 != 0 { self.carry = true; }
|
||||
if val & 0x200 != 0 { self.full = true; }
|
||||
if val & 0x400 != 0 { self.empty = true; }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@@ -85,7 +93,11 @@ impl StatusFlags {
|
||||
Cond::Invalid => self.invalid,
|
||||
Cond::Valid => !self.invalid,
|
||||
Cond::Carry => self.carry,
|
||||
Cond::NotCarry => !self.carry
|
||||
Cond::NotCarry => !self.carry,
|
||||
Cond::Full => self.full,
|
||||
Cond::NotFull => !self.full,
|
||||
Cond::Empty => self.empty,
|
||||
Cond::NotEmpty => !self.empty,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +133,12 @@ impl StatusFlags {
|
||||
Cond::Carry => {
|
||||
self.carry = true;
|
||||
}
|
||||
Cond::Empty => {
|
||||
self.empty = true;
|
||||
}
|
||||
Cond::Full => {
|
||||
self.full = true;
|
||||
}
|
||||
other => {
|
||||
error!("Cannot set cond by {:?}", other);
|
||||
// ...and do nothing. Don't panic, we don't want to crash the runtime!
|
||||
@@ -133,32 +151,38 @@ impl Display for StatusFlags {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("[")?;
|
||||
if self.equal {
|
||||
f.write_str(" E")?;
|
||||
f.write_str(" =")?;
|
||||
}
|
||||
if self.zero {
|
||||
f.write_str(" Z")?;
|
||||
f.write_str(" 0")?;
|
||||
}
|
||||
if self.lower {
|
||||
f.write_str(" L")?;
|
||||
f.write_str(" Lt")?;
|
||||
}
|
||||
if self.greater {
|
||||
f.write_str(" G")?;
|
||||
f.write_str(" Gt")?;
|
||||
}
|
||||
if self.positive {
|
||||
f.write_str(" P")?;
|
||||
f.write_str(" +")?;
|
||||
}
|
||||
if self.negative {
|
||||
f.write_str(" N")?;
|
||||
f.write_str(" -")?;
|
||||
}
|
||||
if self.overflow {
|
||||
f.write_str(" V")?;
|
||||
f.write_str(" Ov")?;
|
||||
}
|
||||
if self.invalid {
|
||||
f.write_str(" X")?;
|
||||
f.write_str(" Inv")?;
|
||||
}
|
||||
if self.carry {
|
||||
f.write_str(" C")?;
|
||||
}
|
||||
if self.full {
|
||||
f.write_str(" Full")?;
|
||||
}
|
||||
if self.empty {
|
||||
f.write_str(" Emp")?;
|
||||
}
|
||||
f.write_str(" ]")?;
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user