From a867f43763978bc18ace76c75d43e52a371b84da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Mon, 21 Sep 2020 23:22:13 +0200 Subject: [PATCH] new unit test --- csn_asm/src/instr/mod.rs | 1 + csn_asm/src/lib.rs | 110 +++++++++++++++++++++++++++++-- csn_asm/src/parse/parse_cond.rs | 2 +- csn_asm/src/parse/parse_instr.rs | 8 +-- 4 files changed, 111 insertions(+), 10 deletions(-) diff --git a/csn_asm/src/instr/mod.rs b/csn_asm/src/instr/mod.rs index c172ac2..2fe0e87 100644 --- a/csn_asm/src/instr/mod.rs +++ b/csn_asm/src/instr/mod.rs @@ -9,6 +9,7 @@ use std::collections::HashMap; use crate::error::{AsmError, Error}; /// A higher-level instruction +#[derive(Debug, Clone, Eq, PartialEq)] pub struct Instr { pub op: Op, pub branches: Option)>>, diff --git a/csn_asm/src/lib.rs b/csn_asm/src/lib.rs index e97f902..2a69d10 100644 --- a/csn_asm/src/lib.rs +++ b/csn_asm/src/lib.rs @@ -9,10 +9,11 @@ pub use parse::parse; #[cfg(test)] mod tests { 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::literal::{Value, Addr}; + use crate::data::literal::{Value, Addr, Label}; use std::sync::atomic::AtomicU32; + use crate::instr::Cond; #[test] fn test_parse_empty() { @@ -140,14 +141,18 @@ mod tests { ], parsed); } - fn parse_single_instr(src : &str) -> anyhow::Result> { + fn parse_single_instr(src : &str) -> anyhow::Result { + Ok(parse::parse_instructions(vec![sexp::parse(src)?])?.remove(0)) + } + + fn parse_single_op(src : &str) -> anyhow::Result> { 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] 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![ Op::Mov( Wr::new(DstDisp::Register(Register::Gen(0))), @@ -155,4 +160,99 @@ mod tests { ), ], 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); + } } diff --git a/csn_asm/src/parse/parse_cond.rs b/csn_asm/src/parse/parse_cond.rs index 1d9c637..5ff7714 100644 --- a/csn_asm/src/parse/parse_cond.rs +++ b/csn_asm/src/parse/parse_cond.rs @@ -24,7 +24,7 @@ pub fn parse_cond(text: &str) -> Result { "nz" | "<>0" | "!0" => Cond::NotZero, "lt" | "<" => Cond::Less, "le" | "<=" | "≤" => Cond::LessOrEqual, - "gt" => Cond::Greater, + "gt" | ">" => Cond::Greater, "ge" | ">=" | "≥" => Cond::GreaterOrEqual, "pos" | "+" | ">0" => Cond::Positive, "neg" | "-" | "<0" => Cond::Negative, diff --git a/csn_asm/src/parse/parse_instr.rs b/csn_asm/src/parse/parse_instr.rs index 5a41b09..fa3b5c3 100644 --- a/csn_asm/src/parse/parse_instr.rs +++ b/csn_asm/src/parse/parse_instr.rs @@ -1,9 +1,9 @@ use sexp::Sexp; -use crate::instr::{Instr, Op}; +use crate::instr::{Instr}; use crate::error::Error; -use crate::parse::parse_cond::{parse_cond_branch, parse_cond}; -use crate::data::literal::{Label, RoutineName}; -use crate::parse::parse_data::{parse_rd, parse_wr}; +use crate::parse::parse_cond::{parse_cond_branch}; + + use crate::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::patches::SexpIsA; use super::parse_op::parse_op;