buffer module, replacing stacks. TODO: docs, fix parsing of "numbers tuple" in mkbfv (consumed by the conditional branch parser)

This commit is contained in:
2020-10-10 01:26:40 +02:00
parent 1f2dbaa81d
commit ee59096821
18 changed files with 578 additions and 232 deletions
+27 -5
View File
@@ -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,
+1 -1
View File
@@ -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) => {
+2 -2
View File
@@ -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);
}
}
+33 -9
View File
@@ -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(())