add rcmp instr, add rot13 example

pull/21/head
Ondřej Hruška 4 years ago
parent e48d734615
commit 3a8895b790
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 6
      README.md
  2. 1
      crsn_arith/src/defs.rs
  3. 11
      crsn_arith/src/exec.rs
  4. 8
      crsn_arith/src/parse.rs
  5. 16
      examples/stdio_rot13.csn

@ -341,9 +341,13 @@ Many instructions have two forms:
; Test properties of a value - zero, positive, negative ; Test properties of a value - zero, positive, negative
(tst SRC) (tst SRC)
; Compare two values ; Compare two values. Sets EQ, LT, GT, and Z, POS and NEG if the values equal
(cmp Rd Rd) (cmp Rd Rd)
; Check if a value is in a range (inclusive).
; Sets the EQ, LT and GT flags. Also sets Z, POS and NEG based on the value.
(rcmp Rd:val Rd:start Rd:end)
; Add A+B ; Add A+B
(add Wr Rd Rd) (add Wr Rd Rd)
(add RW Rd) (add RW Rd)

@ -5,6 +5,7 @@ use crsn::asm::data::{Rd, Wr};
pub enum ArithOp { pub enum ArithOp {
Test { a: Rd }, Test { a: Rd },
Compare { a: Rd, b: Rd }, Compare { a: Rd, b: Rd },
RangeTest { val: Rd, a: Rd, b: Rd },
Add { dst: Wr, a: Rd, b: Rd }, Add { dst: Wr, a: Rd, b: Rd },
Sub { dst: Wr, a: Rd, b: Rd }, Sub { dst: Wr, a: Rd, b: Rd },

@ -34,6 +34,16 @@ impl OpTrait for ArithOp {
state.update_status(x); state.update_status(x);
} }
} }
ArithOp::RangeTest { val, a, b } => {
state.clear_status();
let val = state.read(*val)?;
let a = state.read(*a)?;
let b = state.read(*b)?;
state.set_flag(Cond::Equal, val >= a && val <= b);
state.set_flag(Cond::Lower, val < a);
state.set_flag(Cond::Greater, val > b);
state.update_status(val);
}
ArithOp::Add { dst, a, b } => { ArithOp::Add { dst, a, b } => {
state.clear_status(); state.clear_status();
let x = state.read(*a)?; let x = state.read(*a)?;
@ -201,6 +211,7 @@ impl OpTrait for ArithOp {
ArithOp::Add { dst, a, b } => to_sexp_2_or_3("add", dst, a, b), ArithOp::Add { dst, a, b } => to_sexp_2_or_3("add", dst, a, b),
ArithOp::Test { a } => sexp::list(&[A("test"), A(a)]), ArithOp::Test { a } => sexp::list(&[A("test"), A(a)]),
ArithOp::Compare { a, b } => sexp::list(&[A("cmp"), A(a), A(b)]), ArithOp::Compare { a, b } => sexp::list(&[A("cmp"), A(a), A(b)]),
ArithOp::RangeTest { val, a: start, b: end } => sexp::list(&[A("rcmp"), A(val), A(start), A(end)]),
ArithOp::Sub { dst, a, b } => to_sexp_2_or_3("sub", dst, a, b), ArithOp::Sub { dst, a, b } => to_sexp_2_or_3("sub", dst, a, b),
ArithOp::Mul { dst, a, b } => to_sexp_2_or_3("mul", dst, a, b), ArithOp::Mul { dst, a, b } => to_sexp_2_or_3("mul", dst, a, b),
ArithOp::Div { dst, rem, a, div } => { ArithOp::Div { dst, rem, a, div } => {

@ -16,6 +16,14 @@ pub(crate) fn parse<'a>(pos: &SourcePosition, keyword: &str, mut args: TokenPars
} }
} }
"rcmp" => {
ArithOp::RangeTest {
val: args.next_rd()?,
a: args.next_rd()?,
b: args.next_rd()?,
}
}
"tst" => { "tst" => {
let arg = args.next_rd()?; let arg = args.next_rd()?;
ArithOp::Test { a: arg } ArithOp::Test { a: arg }

@ -0,0 +1,16 @@
(
(:again)
(ld r0 @stdin (inval? (halt)))
(rcmp r0 'A' 'Z'
(eq? (ld r1 'A'))
(ne? (rcmp r0 'a' 'z'
(eq? (ld r1 'a'))
(ne? (j :print)))))
(sub r0 r1)
(add r0 13)
(mod r0 26)
(add r0 r1)
(:print)
(ld @stdout r0)
(j :again)
)
Loading…
Cancel
Save