mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-16 07:28:52 +00:00
Update test
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
int main() {
|
int main() {
|
||||||
return _Alignof(const int);
|
return _Alignof(const int) == 4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,3 +4,7 @@ int bar(int x, int y, int z){
|
|||||||
if (x == y) { return y; }
|
if (x == y) { return y; }
|
||||||
else { return z; }
|
else { return z; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ int main()
|
|||||||
{
|
{
|
||||||
int y = 2;
|
int y = 2;
|
||||||
int x = (y += 2, 2, y + 3);
|
int x = (y += 2, 2, y + 3);
|
||||||
return x;
|
return x == 7;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ int main()
|
|||||||
{
|
{
|
||||||
int y = 1;
|
int y = 1;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
return (x == y) ? 2 : 5;
|
return ((x == y) ? 2 : 5) == 5;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,3 +5,7 @@ int (fibonacci)(int n) {
|
|||||||
|
|
||||||
return fibonacci(n - 2) + fibonacci(n - 1);
|
return fibonacci(n - 2) + fibonacci(n - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return fibonacci(9) == 34;
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,5 +16,5 @@ int fibonacci(int n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
return fibonacci(9);
|
return fibonacci(9) == 34;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,5 +18,5 @@ int fibonacci(int n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
return fibonacci(9);
|
return fibonacci(9) == 34;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,5 +18,5 @@ int fibonacci(int n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
return fibonacci(9);
|
return fibonacci(9) == 34;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ int fibonacci(int n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
return fibonacci(9);
|
return fibonacci(9) == 34;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ int foo(int x, int y, int z){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
return foo(0, 1, -1);
|
return foo(0, 1, -1) == -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ int main() {
|
|||||||
int k = 0;
|
int k = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ int foo(int, int k);
|
|||||||
int main() {
|
int main() {
|
||||||
int i = g;
|
int i = g;
|
||||||
|
|
||||||
return foo(i, i);
|
return foo(i, i) == 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
int foo(int i, int j) {
|
int foo(int i, int j) {
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ int (* (* foo3())())(int, int, int){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
return foo3()()(2, 2, 2);
|
return foo3()()(2, 2, 2) == 6;
|
||||||
}
|
}
|
||||||
|
|||||||
19
examples/for_continue_break.c
Normal file
19
examples/for_continue_break.c
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
int foo() {
|
||||||
|
int sum = 0;
|
||||||
|
|
||||||
|
for(int i = 0; ;) {
|
||||||
|
if(i == 5) break;
|
||||||
|
if(i == 3) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sum += i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return foo() == 7;
|
||||||
|
}
|
||||||
@@ -4,5 +4,5 @@ int foo(int x, int y, int z){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
return foo(0, 1, -1);
|
return foo(0, 1, -1) == 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ int main(){
|
|||||||
*&*foo(*p2) += 1;
|
*&*foo(*p2) += 1;
|
||||||
*foo(p3) += 1;
|
*foo(p3) += 1;
|
||||||
|
|
||||||
return a;
|
return a == 3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ void foo() {
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
foo();
|
foo();
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
int x = 1;
|
int x = 1;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ int main()
|
|||||||
for (i = 0; i < 11; ++i) {
|
for (i = 0; i < 11; ++i) {
|
||||||
sum += i;
|
sum += i;
|
||||||
}
|
}
|
||||||
return sum;
|
return sum == 55;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,3 +5,7 @@ int (fibonacci)(int n) {
|
|||||||
|
|
||||||
return fibonacci(n - 2) + fibonacci(n - 1);
|
return fibonacci(n - 2) + fibonacci(n - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
int main() {
|
int main() {
|
||||||
return sizeof(const int);
|
return sizeof(const int) == 4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,5 +16,5 @@ int main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return b;
|
return b == 2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,3 +3,7 @@ int fibonacci(int n) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
21
examples/while_continue_break.c
Normal file
21
examples/while_continue_break.c
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
int foo() {
|
||||||
|
int sum = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while(i < 10) {
|
||||||
|
if(i == 3) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sum += i;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if(i == 5) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return foo() == 7;
|
||||||
|
}
|
||||||
@@ -1058,7 +1058,7 @@ impl HasDtype for Instruction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
pub struct BlockId(pub usize);
|
pub struct BlockId(pub usize);
|
||||||
|
|
||||||
impl fmt::Display for BlockId {
|
impl fmt::Display for BlockId {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ pub enum InterpreterError {
|
|||||||
display = "{}:{}:{} / Undef value cannot be used as an operand",
|
display = "{}:{}:{} / Undef value cannot be used as an operand",
|
||||||
func_name, bid, iid
|
func_name, bid, iid
|
||||||
)]
|
)]
|
||||||
Undef {
|
Misc {
|
||||||
func_name: String,
|
func_name: String,
|
||||||
bid: BlockId,
|
bid: BlockId,
|
||||||
iid: usize,
|
iid: usize,
|
||||||
@@ -198,6 +198,9 @@ mod calculator {
|
|||||||
(ast::BinaryOperator::Less, Value::Int(lhs), Value::Int(rhs)) => {
|
(ast::BinaryOperator::Less, Value::Int(lhs), Value::Int(rhs)) => {
|
||||||
Ok(Value::Bool(lhs < rhs))
|
Ok(Value::Bool(lhs < rhs))
|
||||||
}
|
}
|
||||||
|
(ast::BinaryOperator::GreaterOrEqual, Value::Int(lhs), Value::Int(rhs)) => {
|
||||||
|
Ok(Value::Bool(lhs >= rhs))
|
||||||
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,6 +217,16 @@ mod calculator {
|
|||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn calculate_typecast(value: &Value, dtype: &crate::ir::Dtype) -> Result<Value, ()> {
|
||||||
|
match (value, dtype) {
|
||||||
|
(Value::Int(_), crate::ir::Dtype::Int { .. }) => Ok(value.clone()),
|
||||||
|
(Value::Bool(b), crate::ir::Dtype::Int { .. }) => {
|
||||||
|
Ok(Value::Int(if *b { 1 } else { 0 }))
|
||||||
|
}
|
||||||
|
_ => todo!("calculate_typecast ({:?}) {:?}", dtype, value),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: allocation fields will be added in the future
|
// TODO: allocation fields will be added in the future
|
||||||
@@ -250,7 +263,7 @@ impl<'i> State<'i> {
|
|||||||
// Create State
|
// Create State
|
||||||
let mut state = State {
|
let mut state = State {
|
||||||
global_map: GlobalMap::default(),
|
global_map: GlobalMap::default(),
|
||||||
stack_frame: StackFrame::new(func_def.bid_init.clone(), func_name, func_def),
|
stack_frame: StackFrame::new(func_def.bid_init, func_name, func_def),
|
||||||
stack: Vec::new(),
|
stack: Vec::new(),
|
||||||
memory: Vec::new(),
|
memory: Vec::new(),
|
||||||
ir,
|
ir,
|
||||||
@@ -351,7 +364,7 @@ impl<'i> State<'i> {
|
|||||||
.stack_frame
|
.stack_frame
|
||||||
.func_def
|
.func_def
|
||||||
.blocks
|
.blocks
|
||||||
.get(&self.stack_frame.pc.bid.clone())
|
.get(&self.stack_frame.pc.bid)
|
||||||
.expect("block matched with `bid` must be exist");
|
.expect("block matched with `bid` must be exist");
|
||||||
|
|
||||||
if block.instructions.len() == self.stack_frame.pc.iid {
|
if block.instructions.len() == self.stack_frame.pc.iid {
|
||||||
@@ -378,8 +391,7 @@ impl<'i> State<'i> {
|
|||||||
self.stack_frame = prev_stack_frame;
|
self.stack_frame = prev_stack_frame;
|
||||||
|
|
||||||
// create temporary register to write return value
|
// create temporary register to write return value
|
||||||
let register =
|
let register = RegisterId::temp(self.stack_frame.pc.bid, self.stack_frame.pc.iid);
|
||||||
RegisterId::temp(self.stack_frame.pc.bid.clone(), self.stack_frame.pc.iid);
|
|
||||||
self.register_write(register, value);
|
self.register_write(register, value);
|
||||||
self.stack_frame.pc.increment();
|
self.stack_frame.pc.increment();
|
||||||
}
|
}
|
||||||
@@ -392,7 +404,7 @@ impl<'i> State<'i> {
|
|||||||
) -> Result<Option<Value>, InterpreterError> {
|
) -> Result<Option<Value>, InterpreterError> {
|
||||||
match block_exit {
|
match block_exit {
|
||||||
BlockExit::Jump { bid } => {
|
BlockExit::Jump { bid } => {
|
||||||
self.stack_frame.pc = Pc::new(bid.clone());
|
self.stack_frame.pc = Pc::new(*bid);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
BlockExit::ConditionalJump {
|
BlockExit::ConditionalJump {
|
||||||
@@ -403,11 +415,7 @@ impl<'i> State<'i> {
|
|||||||
let value = self.get_value(condition.clone())?;
|
let value = self.get_value(condition.clone())?;
|
||||||
let value = value.get_bool().expect("`condition` must be `Value::Bool`");
|
let value = value.get_bool().expect("`condition` must be `Value::Bool`");
|
||||||
|
|
||||||
self.stack_frame.pc = Pc::new(if value {
|
self.stack_frame.pc = Pc::new(if value { *bid_then } else { *bid_else });
|
||||||
bid_then.clone()
|
|
||||||
} else {
|
|
||||||
bid_else.clone()
|
|
||||||
});
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
BlockExit::Switch {
|
BlockExit::Switch {
|
||||||
@@ -421,10 +429,10 @@ impl<'i> State<'i> {
|
|||||||
let bid_next = cases
|
let bid_next = cases
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(c, _)| value == self.constant_to_value(c.clone()))
|
.find(|(c, _)| value == self.constant_to_value(c.clone()))
|
||||||
.map(|(_, bid)| bid.clone())
|
.map(|(_, bid)| bid)
|
||||||
.unwrap_or_else(|| default.clone());
|
.unwrap_or_else(|| default);
|
||||||
|
|
||||||
self.stack_frame.pc = Pc::new(bid_next);
|
self.stack_frame.pc = Pc::new(*bid_next);
|
||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
@@ -443,9 +451,9 @@ impl<'i> State<'i> {
|
|||||||
let rhs = self.get_value(rhs.clone())?;
|
let rhs = self.get_value(rhs.clone())?;
|
||||||
|
|
||||||
calculator::calculate_binary_operator_expression(&op, lhs, rhs).map_err(|_| {
|
calculator::calculate_binary_operator_expression(&op, lhs, rhs).map_err(|_| {
|
||||||
InterpreterError::Undef {
|
InterpreterError::Misc {
|
||||||
func_name: self.stack_frame.func_name.clone(),
|
func_name: self.stack_frame.func_name.clone(),
|
||||||
bid: self.stack_frame.pc.bid.clone(),
|
bid: self.stack_frame.pc.bid,
|
||||||
iid: self.stack_frame.pc.iid,
|
iid: self.stack_frame.pc.iid,
|
||||||
}
|
}
|
||||||
})?
|
})?
|
||||||
@@ -454,9 +462,9 @@ impl<'i> State<'i> {
|
|||||||
let operand = self.get_value(operand.clone())?;
|
let operand = self.get_value(operand.clone())?;
|
||||||
|
|
||||||
calculator::calculate_unary_operator_expression(&op, operand).map_err(|_| {
|
calculator::calculate_unary_operator_expression(&op, operand).map_err(|_| {
|
||||||
InterpreterError::Undef {
|
InterpreterError::Misc {
|
||||||
func_name: self.stack_frame.func_name.clone(),
|
func_name: self.stack_frame.func_name.clone(),
|
||||||
bid: self.stack_frame.pc.bid.clone(),
|
bid: self.stack_frame.pc.bid,
|
||||||
iid: self.stack_frame.pc.iid,
|
iid: self.stack_frame.pc.iid,
|
||||||
}
|
}
|
||||||
})?
|
})?
|
||||||
@@ -502,7 +510,7 @@ impl<'i> State<'i> {
|
|||||||
|
|
||||||
let args = self.preprocess_args(func_signature, args)?;
|
let args = self.preprocess_args(func_signature, args)?;
|
||||||
|
|
||||||
let stack_frame = StackFrame::new(func_def.bid_init.clone(), callee_name, func_def);
|
let stack_frame = StackFrame::new(func_def.bid_init, callee_name, func_def);
|
||||||
let prev_stack_frame = mem::replace(&mut self.stack_frame, stack_frame);
|
let prev_stack_frame = mem::replace(&mut self.stack_frame, stack_frame);
|
||||||
self.stack.push(prev_stack_frame);
|
self.stack.push(prev_stack_frame);
|
||||||
|
|
||||||
@@ -512,10 +520,22 @@ impl<'i> State<'i> {
|
|||||||
|
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
_ => todo!("{:?} will be supported in the future", instruction),
|
Instruction::TypeCast {
|
||||||
|
value,
|
||||||
|
target_dtype,
|
||||||
|
} => {
|
||||||
|
let value = self.get_value(value.clone())?;
|
||||||
|
calculator::calculate_typecast(&value, target_dtype).map_err(|_| {
|
||||||
|
InterpreterError::Misc {
|
||||||
|
func_name: self.stack_frame.func_name.clone(),
|
||||||
|
bid: self.stack_frame.pc.bid,
|
||||||
|
iid: self.stack_frame.pc.iid,
|
||||||
|
}
|
||||||
|
})?
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let register = RegisterId::temp(self.stack_frame.pc.bid.clone(), self.stack_frame.pc.iid);
|
let register = RegisterId::temp(self.stack_frame.pc.bid, self.stack_frame.pc.iid);
|
||||||
self.register_write(register, result);
|
self.register_write(register, result);
|
||||||
self.stack_frame.pc.increment();
|
self.stack_frame.pc.increment();
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ impl WriteLine for (&BlockId, &Block) {
|
|||||||
writeln!(
|
writeln!(
|
||||||
write,
|
write,
|
||||||
"{}:{} = {}",
|
"{}:{} = {}",
|
||||||
RegisterId::temp(self.0.clone(), i),
|
RegisterId::temp(*self.0, i),
|
||||||
instr.dtype(),
|
instr.dtype(),
|
||||||
instr.write_string()
|
instr.write_string()
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use kecc::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn ast_printer_test() {
|
|
||||||
let mut parse = Parse::default();
|
|
||||||
let dir_path = Path::new("examples/");
|
|
||||||
let dir = dir_path.read_dir().expect("read_dir call failed");
|
|
||||||
for entry in dir {
|
|
||||||
let test_file = ok_or!(entry, continue);
|
|
||||||
let test_unit = parse.translate(&test_file.path().as_path()).expect(
|
|
||||||
&format!(
|
|
||||||
"parse failed {:?}",
|
|
||||||
test_file.path().into_os_string().to_str().unwrap()
|
|
||||||
)
|
|
||||||
.to_owned(),
|
|
||||||
);
|
|
||||||
write_c_test(&test_unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,6 +22,7 @@ REPLACE_DICT = {
|
|||||||
"int16_t": "int",
|
"int16_t": "int",
|
||||||
"int32_t": "int",
|
"int32_t": "int",
|
||||||
"uint": "unsigned int",
|
"uint": "unsigned int",
|
||||||
|
"static ": "",
|
||||||
}
|
}
|
||||||
CSMITH_DIR = "csmith-2.3.0"
|
CSMITH_DIR = "csmith-2.3.0"
|
||||||
|
|
||||||
@@ -44,7 +45,12 @@ def generate(tests_dir, bin_file, runtime, file_name):
|
|||||||
A developer may customize the options to meet one's needs for testing.
|
A developer may customize the options to meet one's needs for testing.
|
||||||
"""
|
"""
|
||||||
global CSMITH_DIR
|
global CSMITH_DIR
|
||||||
options = ["--no-builtins", "--no-safe-math", "--no-unions"]
|
options = [
|
||||||
|
"--no-argc", "--no-arrays", "--no-checksum",
|
||||||
|
"--no-jumps", "--no-longlong", "--no-int8",
|
||||||
|
"--no-uint8", "--no-safe-math", "--no-pointers",
|
||||||
|
"--no-structs", "--no-unions", "--no-builtins"
|
||||||
|
]
|
||||||
args = [bin_file] + options
|
args = [bin_file] + options
|
||||||
dst_path = os.path.join(runtime, file_name)
|
dst_path = os.path.join(runtime, file_name)
|
||||||
|
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
use kecc::run_ir::*;
|
|
||||||
use kecc::*;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
// TODO: cover all examples in the future
|
|
||||||
#[test]
|
|
||||||
fn ir_interpreter_test() {
|
|
||||||
// Test toy example
|
|
||||||
assert_eq!(run_example("examples/foo.c"), Ok(Value::Int(-1)));
|
|
||||||
|
|
||||||
// Test toy example with negate unary operator
|
|
||||||
assert_eq!(run_example("examples/negate.c"), Ok(Value::Int(1)));
|
|
||||||
|
|
||||||
// Test fibonacci function with for-loop
|
|
||||||
assert_eq!(run_example("examples/fib3.c"), Ok(Value::Int(34)));
|
|
||||||
|
|
||||||
// Test fibonacci function with while-loop
|
|
||||||
assert_eq!(run_example("examples/fib4.c"), Ok(Value::Int(34)));
|
|
||||||
|
|
||||||
// Test fibonacci function with do-while-loop
|
|
||||||
assert_eq!(run_example("examples/fib5.c"), Ok(Value::Int(34)));
|
|
||||||
|
|
||||||
// Test fibonacci function with recursive function call
|
|
||||||
assert_eq!(run_example("examples/fibonacci.c"), Ok(Value::Int(34)));
|
|
||||||
|
|
||||||
// Test example with global variable
|
|
||||||
assert_eq!(run_example("examples/foo3.c"), Ok(Value::Int(30)));
|
|
||||||
|
|
||||||
// Test example with comma expressions
|
|
||||||
assert_eq!(run_example("examples/comma.c"), Ok(Value::Int(7)));
|
|
||||||
|
|
||||||
// Test example with complex function call
|
|
||||||
assert_eq!(run_example("examples/foo4.c"), Ok(Value::Int(6)));
|
|
||||||
|
|
||||||
// Test example with pointer
|
|
||||||
assert_eq!(run_example("examples/pointer.c"), Ok(Value::Int(3)));
|
|
||||||
|
|
||||||
// Test example with sizeof
|
|
||||||
assert_eq!(run_example("examples/sizeof.c"), Ok(Value::Int(4)));
|
|
||||||
|
|
||||||
// Test example with alignof
|
|
||||||
assert_eq!(run_example("examples/alignof.c"), Ok(Value::Int(4)));
|
|
||||||
|
|
||||||
// Test example with simple for statement
|
|
||||||
assert_eq!(run_example("examples/simple_for.c"), Ok(Value::Int(55)));
|
|
||||||
|
|
||||||
// Test example with conditional expression
|
|
||||||
assert_eq!(run_example("examples/cond.c"), Ok(Value::Int(5)));
|
|
||||||
|
|
||||||
// Test example with switch statement
|
|
||||||
assert_eq!(run_example("examples/switch.c"), Ok(Value::Int(2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_example(example_path: &str) -> Result<Value, InterpreterError> {
|
|
||||||
let example_path = Path::new(example_path);
|
|
||||||
let unit = Parse::default()
|
|
||||||
.translate(&example_path)
|
|
||||||
.expect("parse failed");
|
|
||||||
let ir = Irgen::default()
|
|
||||||
.translate(&unit)
|
|
||||||
.expect("failed to generate ir");
|
|
||||||
|
|
||||||
// TODO: consider command line arguments in the future
|
|
||||||
// TODO: randomly generate argument values
|
|
||||||
let args = Vec::new();
|
|
||||||
|
|
||||||
run_ir(&ir, args)
|
|
||||||
}
|
|
||||||
47
tests/test_examples.rs
Normal file
47
tests/test_examples.rs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use lang_c::ast::*;
|
||||||
|
|
||||||
|
use kecc::run_ir::*;
|
||||||
|
use kecc::*;
|
||||||
|
|
||||||
|
fn test_dir<F>(path: &Path, f: F)
|
||||||
|
where
|
||||||
|
F: Fn(&TranslationUnit),
|
||||||
|
{
|
||||||
|
let mut parse = Parse::default();
|
||||||
|
let dir = path.read_dir().expect("read_dir call failed");
|
||||||
|
for entry in dir {
|
||||||
|
let entry = ok_or!(entry, continue);
|
||||||
|
let path = entry.path();
|
||||||
|
if path.is_dir() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("[testing {:?}]", path);
|
||||||
|
let test_unit = parse.translate(&path.as_path()).expect(
|
||||||
|
&format!("parse failed {:?}", path.into_os_string().to_str().unwrap()).to_owned(),
|
||||||
|
);
|
||||||
|
f(&test_unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_examples_write_c() {
|
||||||
|
test_dir(Path::new("examples/"), write_c_test);
|
||||||
|
test_dir(Path::new("examples/hw1"), write_c_test);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_examples_irgen() {
|
||||||
|
test_dir(Path::new("examples/"), |test_unit| {
|
||||||
|
let ir = Irgen::default()
|
||||||
|
.translate(test_unit)
|
||||||
|
.expect("failed to generate ir");
|
||||||
|
|
||||||
|
// TODO: insert randomly generated command line arguments
|
||||||
|
let args = Vec::new();
|
||||||
|
|
||||||
|
assert_eq!(run_ir(&ir, args), Ok(Value::Int(1)));
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user