forked from MightyPork/crsn
add "swap" instr, document buffer ops
This commit is contained in:
@@ -71,12 +71,12 @@ pub fn parse_cond(text: &str, pos: &SourcePosition) -> Result<Cond, CrsnError> {
|
||||
"nneg" | "0+" | ">=0" | "≤0" => Cond::NonNegative,
|
||||
"c" => Cond::Carry,
|
||||
"nc" => Cond::NotCarry,
|
||||
"em" => Cond::Empty,
|
||||
"nem" => Cond::NotEmpty,
|
||||
"f" => Cond::Full,
|
||||
"nf" => Cond::NotFull,
|
||||
"valid" => Cond::Valid,
|
||||
"inval" => Cond::Invalid,
|
||||
"em" | "empty" => Cond::Empty,
|
||||
"nem" | "nempty" => Cond::NotEmpty,
|
||||
"f" | "full" => Cond::Full,
|
||||
"nf" | "nfull" => Cond::NotFull,
|
||||
"ok" | "val" | "valid" => Cond::Valid,
|
||||
"inval" | "invalid" | "nval" | "nok" => Cond::Invalid,
|
||||
"ov" => Cond::Overflow,
|
||||
"nov" => Cond::NotOverflow,
|
||||
_ => {
|
||||
|
||||
@@ -71,7 +71,9 @@ pub enum BuiltinOp {
|
||||
/// The object is released and the handle becomes invalid.
|
||||
Delete(RdObj),
|
||||
/// Copy value
|
||||
Move { dst: Wr, src: Rd },
|
||||
MoveValue { dst: Wr, src: Rd },
|
||||
/// Swap two registers
|
||||
SwapValues { a: Wr, b: Wr },
|
||||
/// Store runtime status to a register
|
||||
StoreFlags { dst: Wr },
|
||||
/// Load runtime status from a register
|
||||
|
||||
@@ -103,12 +103,18 @@ impl OpTrait for BuiltinOp {
|
||||
let pc = state.get_pc();
|
||||
program.validate_jump(pc, Addr((pc.0 as i64 + res.advance) as u64))?;
|
||||
}
|
||||
BuiltinOp::Move { dst, src } => {
|
||||
BuiltinOp::MoveValue { dst, src } => {
|
||||
state.clear_status();
|
||||
let val = state.read(*src)?;
|
||||
state.update_status(val);
|
||||
state.write(*dst, val)?;
|
||||
}
|
||||
BuiltinOp::SwapValues { a, b } => {
|
||||
let aa = state.read(a.as_rd())?;
|
||||
let bb = state.read(b.as_rd())?;
|
||||
state.write(*a, bb)?;
|
||||
state.write(*b, aa)?;
|
||||
}
|
||||
BuiltinOp::StoreFlags { dst } => {
|
||||
let packed = state.frame.status.store();
|
||||
state.write(*dst, packed)?;
|
||||
|
||||
@@ -177,12 +177,19 @@ pub(crate) fn parse_op<'a>(op_pos: &SourcePosition, keyword: &str, mut args: Tok
|
||||
}
|
||||
|
||||
"ld" => {
|
||||
BuiltinOp::Move {
|
||||
BuiltinOp::MoveValue {
|
||||
dst: args.next_wr()?,
|
||||
src: args.next_rd()?,
|
||||
}
|
||||
}
|
||||
|
||||
"swap" => {
|
||||
BuiltinOp::SwapValues {
|
||||
a: args.next_wr()?,
|
||||
b: args.next_wr()?,
|
||||
}
|
||||
}
|
||||
|
||||
"stf" => {
|
||||
BuiltinOp::StoreFlags {
|
||||
dst: args.next_wr()?,
|
||||
@@ -295,7 +302,8 @@ pub(crate) fn to_sexp(op: &BuiltinOp) -> Sexp {
|
||||
}
|
||||
}
|
||||
BuiltinOp::Delete(obj) => sexp::list(&[A("del"), A(obj)]),
|
||||
BuiltinOp::Move { dst, src } => sexp::list(&[A("ld"), A(dst), A(src)]),
|
||||
BuiltinOp::MoveValue { dst, src } => sexp::list(&[A("ld"), A(dst), A(src)]),
|
||||
BuiltinOp::SwapValues { a, b } => sexp::list(&[A("swp"), A(a), A(b)]),
|
||||
BuiltinOp::StoreFlags { dst } => sexp::list(&[A("stf"), A(dst)]),
|
||||
BuiltinOp::LoadFlags { src } => sexp::list(&[A("ldf"), A(src)])
|
||||
}
|
||||
@@ -364,6 +372,7 @@ mod test {
|
||||
("(fault)", "(fault)"),
|
||||
("(fault kur*a)", "(fault kur*a)"),
|
||||
("(fault \"do pr*ele\")", "(fault \"do pr*ele\")"),
|
||||
("(swap r0 r1)", "(swap r0 r1)"),
|
||||
("(ld r0 r0)", "(ld r0 r0)"),
|
||||
("(ld r0 156)", "(ld r0 156)"),
|
||||
("(ld _ -32767)", "(ld _ -32767)"),
|
||||
|
||||
Reference in New Issue
Block a user