Skip to content

Commit

Permalink
test(ir): add testcases
Browse files Browse the repository at this point in the history
  • Loading branch information
JuniMay committed Feb 18, 2024
1 parent f435b48 commit 2036c24
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 42 deletions.
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
# ORZCC
# OrzCC

Yet another compiler infrastructure.

## Getting Started

Just install rust toolchain and build/test/run using cargo.

## Testing

Install [cargo-tarpaulin](https://crates.io/crates/cargo-tarpaulin) to get test coverage.

```shell
cargo install cargo-tarpaulin
```

Note that because of the rustc version, you may need to install with `--locked` flag or nightly toolchain.

```shell
cargo install cargo-tarpaulin --locked
```

Then run the following command to get test coverage.

```shell
cargo tarpaulin
```
153 changes: 153 additions & 0 deletions src/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,156 @@ where
}
}
}

#[cfg(test)]
mod test {
use super::*;

#[derive(Debug, Clone)]
struct Node {
next: Option<usize>,
prev: Option<usize>,
}

impl BiLinkedNode<usize> for Node {
fn new() -> Self {
Self {
next: None,
prev: None,
}
}

fn next(&self) -> Option<usize> {
self.next
}

fn prev(&self) -> Option<usize> {
self.prev
}

fn set_next(&mut self, next: Option<usize>) {
self.next = next;
}

fn set_prev(&mut self, prev: Option<usize>) {
self.prev = prev;
}
}

#[test]
fn test_list_ops() {
let mut list = BiLinkedList::<usize, Node>::new();
assert_eq!(list.front(), None);

// 1
list.append(1).unwrap();
assert_eq!(list.front(), Some(1));
assert_eq!(list.node(1).unwrap().next(), None);
assert_eq!(list.node(1).unwrap().prev(), None);
assert!(list.contains_key(1));

// 1 -- 2
list.append(2).unwrap();
assert_eq!(list.front(), Some(1));
assert_eq!(list.node(1).unwrap().next(), Some(2));
assert_eq!(list.node(2).unwrap().prev(), Some(1));
assert!(list.contains_key(2));

// 1 -- 2 -- 3
list.append(3).unwrap();
assert_eq!(list.front(), Some(1));
assert_eq!(list.node(2).unwrap().next(), Some(3));
assert_eq!(list.node(3).unwrap().prev(), Some(2));
assert!(list.contains_key(3));

// 4 -- 1 -- 2 -- 3
list.insert_before(4, 1).unwrap();
assert_eq!(list.front(), Some(4));
assert_eq!(list.node(4).unwrap().next(), Some(1));
assert_eq!(list.node(1).unwrap().prev(), Some(4));
assert!(list.contains_key(4));

// 4 -- 1 -- 5 -- 2 -- 3
list.insert_before(5, 2).unwrap();
assert_eq!(list.front(), Some(4));
assert_eq!(list.node(1).unwrap().next(), Some(5));
assert_eq!(list.node(5).unwrap().prev(), Some(1));
assert!(list.contains_key(5));

// 4 -- 5 -- 2 -- 3
list.remove(1).unwrap();
assert_eq!(list.front(), Some(4));
assert_eq!(list.node(4).unwrap().next(), Some(5));
assert_eq!(list.node(5).unwrap().prev(), Some(4));
assert!(!list.contains_key(1));

// 5 -- 2 -- 3
list.remove(4).unwrap();
assert_eq!(list.front(), Some(5));
assert_eq!(list.node(2).unwrap().next(), Some(3));
assert_eq!(list.node(3).unwrap().prev(), Some(2));
assert_eq!(list.node(5).unwrap().prev(), None);
assert_eq!(list.node(2).unwrap().prev(), Some(5));
assert!(!list.contains_key(4));

// 5 -- 3
list.remove(2).unwrap();
assert_eq!(list.front(), Some(5));
assert_eq!(list.node(3).unwrap().next(), None);
assert_eq!(list.node(3).unwrap().prev(), Some(5));
assert!(!list.contains_key(2));

list.remove(5).unwrap();
assert_eq!(list.front(), Some(3));

list.remove(3).unwrap();
assert_eq!(list.front(), None);
assert!(!list.contains_key(3));
}

#[test]
fn test_list_iter() {
let mut list = BiLinkedList::<usize, Node>::new();
list.append(1).unwrap();
list.append(2).unwrap();
list.append(3).unwrap();
list.append(4).unwrap();
list.append(5).unwrap();

let mut iter = list.iter();
for i in 1..=5 {
let (key, _) = iter.next().unwrap();
assert_eq!(key, i);
if i == 5 {
assert!(iter.next().is_none());
}
}
}

#[test]
fn test_list_err() {
let mut list = BiLinkedList::<usize, Node>::new();
list.append(1).unwrap();
list.append(2).unwrap();
list.append(3).unwrap();
list.append(4).unwrap();
list.append(5).unwrap();

assert!(matches!(
list.append(1),
Err(BiLinkedListErr::KeyDuplicated(1))
));
assert!(matches!(
list.insert_before(1, 6),
Err(BiLinkedListErr::KeyDuplicated(1))
));
assert!(matches!(
list.insert_before(6, 7),
Err(BiLinkedListErr::NodeNotFound(7))
));
assert!(matches!(
list.remove(6),
Err(BiLinkedListErr::NodeNotFound(6))
));
}
}
43 changes: 4 additions & 39 deletions src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,46 +20,11 @@ const INDENT: &'static str = "\t";

#[cfg(test)]
mod tests {
use self::{
builder::{GlobalValueBuilder, LocalBlockBuilder, LocalValueBuilder},
entities::FunctionKind,
module::Module,
types::Type,
};

use super::*;
use crate::ir::module::Module;

#[test]
fn test_basic_builder_functionality() {
let mut module = Module::new("test".to_string());
let function = module
.builder()
.function(
"test_func".to_string(),
Type::mk_function(vec![], Type::mk_void()),
FunctionKind::Definition,
)
.unwrap();

let function_data = module.function_data_mut(function).unwrap();

let block = function_data.dfg_mut().builder().block(vec![]).unwrap();

let dfg = function_data.dfg_mut();

let alloc0 = dfg.builder().alloc(Type::mk_int(32)).unwrap();
let alloc1 = dfg.builder().alloc(Type::mk_float()).unwrap();
let alloc2 = dfg.builder().alloc(Type::mk_double()).unwrap();

let layout = function_data.layout_mut();

layout.append_block(block).ok();
layout.append_inst(alloc0.into(), block).ok();
layout.append_inst(alloc1.into(), block).ok();
layout.append_inst(alloc2.into(), block).ok();

assert_ne!(alloc0, alloc1);
assert_ne!(alloc0, alloc2);
assert_ne!(alloc1, alloc2);
fn test_properties() {
let module = Module::new("module_name".to_string());
assert_eq!(module.name(), "module_name");
}
}
71 changes: 69 additions & 2 deletions src/ir/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl Type {
pub fn size(&self, data_layout: Option<&DataLayout>) -> usize {
match self.kind() {
TypeKind::Void => 0,
TypeKind::Int(bits) => bits / 8,
TypeKind::Int(bits) => cmp::max(1, bits / 8),
TypeKind::Half => 2,
TypeKind::Float => 4,
TypeKind::Double => 8,
Expand Down Expand Up @@ -257,7 +257,15 @@ mod test {

#[test]
fn test_equality() {
assert_eq!(Type::mk_int(32), Type::mk_int(32));
assert_eq!(Type::mk_i32(), Type::mk_int(32));
assert_eq!(Type::mk_i1(), Type::mk_int(1));
assert_ne!(Type::mk_i32(), Type::mk_int(64));

assert!(Type::mk_i32().is_int());
assert!(Type::mk_float().is_float());
assert!(!Type::mk_i32().is_float());
assert!(Type::mk_ptr().is_ptr());

assert_eq!(
Type::mk_array(10, Type::mk_int(32)),
Type::mk_array(10, Type::mk_int(32))
Expand All @@ -272,6 +280,15 @@ mod test {
assert_eq!(Type::mk_float(), Type::mk_float());
assert_eq!(Type::mk_double(), Type::mk_double());
assert_eq!(Type::mk_ptr(), Type::mk_ptr());
assert_eq!(Type::mk_label(), Type::mk_label());
assert_eq!(
Type::mk_type("name".to_string()),
Type::mk_type("name".to_string())
);
assert_ne!(
Type::mk_type("name".to_string()),
Type::mk_type("name2".to_string())
);
assert_eq!(
Type::mk_function(vec![], Type::mk_void()),
Type::mk_function(vec![], Type::mk_void())
Expand All @@ -280,5 +297,55 @@ mod test {
Type::mk_function(vec![Type::mk_int(16)], Type::mk_void()),
Type::mk_function(vec![], Type::mk_int(32))
);
let ty1 = Type::mk_struct(vec![Type::mk_int(32), Type::mk_int(64)]);
let ty2 = Type::mk_struct(vec![Type::mk_int(32), Type::mk_int(64)]);
assert!(matches!(ty1.as_struct(), Some(_)));
assert_eq!(ty1, ty2);
}

#[test]
fn test_display() {
assert_eq!(format!("{}", Type::mk_int(32)), "i32");
let ty = Type::mk_array(10, Type::mk_int(32));
assert_eq!(format!("{}", ty), "[i32; 10]");
assert_eq!(format!("{}", Type::mk_void()), "void");
assert_eq!(format!("{}", Type::mk_half()), "half");
assert_eq!(format!("{}", Type::mk_float()), "float");
assert_eq!(format!("{}", Type::mk_double()), "double");
assert_eq!(format!("{}", Type::mk_ptr()), "ptr");
assert_eq!(format!("{}", Type::mk_label()), "label");
assert_eq!(format!("{}", Type::mk_type("name".to_string())), "#name");
let ty = Type::mk_function(vec![], Type::mk_void());
assert_eq!(format!("{}", ty), "() -> void");
let ty = Type::mk_function(vec![Type::mk_int(16)], Type::mk_void());
assert_eq!(format!("{}", ty), "(i16) -> void");
let ty = Type::mk_function(vec![Type::mk_int(16), Type::mk_int(32)], Type::mk_void());
assert_eq!(format!("{}", ty), "(i16, i32) -> void");
let ty = Type::mk_struct(vec![Type::mk_int(32), Type::mk_int(64)]);
assert_eq!(format!("{}", ty), "{ i32, i64 }");
}

#[test]
fn test_size() {
let dl = DataLayout { pointer_size: 8 };
assert_eq!(Type::mk_void().size(Some(&dl)), 0);
assert_eq!(Type::mk_label().size(Some(&dl)), 0);
assert_eq!(Type::mk_type("name".to_string()).size(Some(&dl)), 0);
assert_eq!(Type::mk_int(1).size(Some(&dl)), 1);
assert_eq!(Type::mk_int(32).size(Some(&dl)), 4);
assert_eq!(Type::mk_int(64).size(Some(&dl)), 8);
assert_eq!(Type::mk_half().size(Some(&dl)), 2);
assert_eq!(Type::mk_float().size(Some(&dl)), 4);
assert_eq!(Type::mk_double().size(Some(&dl)), 8);
assert_eq!(Type::mk_ptr().size(Some(&dl)), 8);
assert_eq!(Type::mk_array(10, Type::mk_int(32)).size(Some(&dl)), 40);
let ty = Type::mk_function(vec![], Type::mk_void());
assert_eq!(ty.size(Some(&dl)), 8);
let ty = Type::mk_function(vec![Type::mk_int(32)], Type::mk_void());
assert_eq!(ty.size(Some(&dl)), 8);
let ty = Type::mk_function(vec![Type::mk_int(32), Type::mk_int(64)], Type::mk_void());
assert_eq!(ty.size(Some(&dl)), 8);
let ty = Type::mk_struct(vec![Type::mk_int(32), Type::mk_int(64)]);
assert_eq!(ty.size(Some(&dl)), 12);
}
}

0 comments on commit 2036c24

Please sign in to comment.