new unit test

pull/21/head
Ondřej Hruška 4 years ago
parent 1d2ce0ad47
commit a867f43763
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 1
      csn_asm/src/instr/mod.rs
  2. 110
      csn_asm/src/lib.rs
  3. 2
      csn_asm/src/parse/parse_cond.rs
  4. 8
      csn_asm/src/parse/parse_instr.rs

@ -9,6 +9,7 @@ use std::collections::HashMap;
use crate::error::{AsmError, Error}; use crate::error::{AsmError, Error};
/// A higher-level instruction /// A higher-level instruction
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Instr { pub struct Instr {
pub op: Op, pub op: Op,
pub branches: Option<Vec<(Cond, Vec<Instr>)>>, pub branches: Option<Vec<(Cond, Vec<Instr>)>>,

@ -9,10 +9,11 @@ pub use parse::parse;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::parse; use crate::parse;
use crate::instr::{Op, Flatten}; use crate::instr::{Op, Flatten, Instr};
use crate::data::{Wr, DstDisp, Register, SrcDisp, Rd}; use crate::data::{Wr, DstDisp, Register, SrcDisp, Rd};
use crate::data::literal::{Value, Addr}; use crate::data::literal::{Value, Addr, Label};
use std::sync::atomic::AtomicU32; use std::sync::atomic::AtomicU32;
use crate::instr::Cond;
#[test] #[test]
fn test_parse_empty() { fn test_parse_empty() {
@ -140,14 +141,18 @@ mod tests {
], parsed); ], parsed);
} }
fn parse_single_instr(src : &str) -> anyhow::Result<Vec<Op>> { fn parse_single_instr(src : &str) -> anyhow::Result<Instr> {
Ok(parse::parse_instructions(vec![sexp::parse(src)?])?.remove(0))
}
fn parse_single_op(src : &str) -> anyhow::Result<Vec<Op>> {
let num = AtomicU32::new(0); let num = AtomicU32::new(0);
Ok(parse::parse_instructions(vec![sexp::parse(src)?])?.remove(0).flatten(&num)?) Ok(parse_single_instr(src)?.flatten(&num)?)
} }
#[test] #[test]
fn test_parse_single() { fn test_parse_single() {
let parsed = parse_single_instr("(mov r0 r1)").unwrap(); let parsed = parse_single_op("(mov r0 r1)").unwrap();
assert_eq!(vec![ assert_eq!(vec![
Op::Mov( Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(0))), Wr::new(DstDisp::Register(Register::Gen(0))),
@ -155,4 +160,99 @@ mod tests {
), ),
], parsed); ], parsed);
} }
#[test]
fn test_branches_instr() {
let parsed = parse_single_instr("
(cmp r0 r1 (eq? (mov r0 r0) (mov r1 r2)) (>? (mov r0 r0) (mov r1 r1)))
").unwrap();
assert_eq!(
Instr {
op: Op::Cmp(
Rd::new(SrcDisp::Register(Register::Gen(0))),
Rd::new(SrcDisp::Register(Register::Gen(1))),
),
branches: Some(vec![
(
Cond::Equal,
vec![
Instr {
op: Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(0))),
Rd::new(SrcDisp::Register(Register::Gen(0))),
),
branches: None
},
Instr {
op: Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(1))),
Rd::new(SrcDisp::Register(Register::Gen(2))),
),
branches: None
}
]
),
(
Cond::Greater,
vec![
Instr {
op: Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(0))),
Rd::new(SrcDisp::Register(Register::Gen(0))),
),
branches: None
},
Instr {
op: Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(1))),
Rd::new(SrcDisp::Register(Register::Gen(1))),
),
branches: None
}
]
)
])
}
, parsed);
}
#[test]
fn test_branches_op() {
let parsed = parse_single_op("
(cmp r0 r1
(eq?
(mov r0 r0)
(mov r1 r2))
(>?
(mov r0 r0)
(mov r1 r1)))
").unwrap();
assert_eq!(
vec![
Op::Cmp(
Rd::new(SrcDisp::Register(Register::Gen(0))),
Rd::new(SrcDisp::Register(Register::Gen(1))),
),
Op::JumpIf(Cond::NotEqual, Label::Numbered(0)),
Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(0))),
Rd::new(SrcDisp::Register(Register::Gen(0))),
),
Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(1))),
Rd::new(SrcDisp::Register(Register::Gen(2))),
),
Op::Label(Label::Numbered(0)),
Op::JumpIf(Cond::LessOrEqual, Label::Numbered(1)),
Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(0))),
Rd::new(SrcDisp::Register(Register::Gen(0))),
),
Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(1))),
Rd::new(SrcDisp::Register(Register::Gen(1))),
),
Op::Label(Label::Numbered(1)),
], parsed);
}
} }

@ -24,7 +24,7 @@ pub fn parse_cond(text: &str) -> Result<Cond, Error> {
"nz" | "<>0" | "!0" => Cond::NotZero, "nz" | "<>0" | "!0" => Cond::NotZero,
"lt" | "<" => Cond::Less, "lt" | "<" => Cond::Less,
"le" | "<=" | "≤" => Cond::LessOrEqual, "le" | "<=" | "≤" => Cond::LessOrEqual,
"gt" => Cond::Greater, "gt" | ">" => Cond::Greater,
"ge" | ">=" | "≥" => Cond::GreaterOrEqual, "ge" | ">=" | "≥" => Cond::GreaterOrEqual,
"pos" | "+" | ">0" => Cond::Positive, "pos" | "+" | ">0" => Cond::Positive,
"neg" | "-" | "<0" => Cond::Negative, "neg" | "-" | "<0" => Cond::Negative,

@ -1,9 +1,9 @@
use sexp::Sexp; use sexp::Sexp;
use crate::instr::{Instr, Op}; use crate::instr::{Instr};
use crate::error::Error; use crate::error::Error;
use crate::parse::parse_cond::{parse_cond_branch, parse_cond}; use crate::parse::parse_cond::{parse_cond_branch};
use crate::data::literal::{Label, RoutineName};
use crate::parse::parse_data::{parse_rd, parse_wr};
use crate::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::parse::sexp_expect::{expect_list, expect_string_atom};
use crate::patches::SexpIsA; use crate::patches::SexpIsA;
use super::parse_op::parse_op; use super::parse_op::parse_op;

Loading…
Cancel
Save