From d64e9f622eedd54b0848da952c121d962b7812b3 Mon Sep 17 00:00:00 2001 From: Chunmyong Park Date: Thu, 2 Jul 2020 06:54:19 +0000 Subject: [PATCH] Update grader --- Cargo.lock | 1 + Cargo.toml | 1 + examples/c/cond_and_loop.c | 7 +- examples/c/fibonacci.c | 5 +- examples/c/foo3.c | 5 +- examples/c/simple.c | 6 +- examples/c/while_continue_break.c | 11 ++- examples/ir0/cond_and_loop.ir | 22 +++--- examples/ir0/fibonacci.ir | 13 +-- examples/ir0/foo3.ir | 7 +- examples/ir0/simple.ir | 7 +- examples/ir0/while_continue_break.ir | 22 ++++-- examples/ir1/cond_and_loop.ir | 24 +++--- examples/ir1/fibonacci.ir | 13 +-- examples/ir1/foo3.ir | 7 +- examples/ir1/simple.ir | 7 +- examples/ir1/while_continue_break.ir | 22 ++++-- examples/ir2/cond_and_loop.ir | 18 +++-- examples/ir2/fibonacci.ir | 13 +-- examples/ir2/foo3.ir | 7 +- examples/ir2/simple.ir | 7 +- examples/ir2/while_continue_break.ir | 22 ++++-- examples/ir3/cond_and_loop.ir | 9 ++- examples/ir3/fibonacci.ir | 7 +- examples/ir3/foo3.ir | 7 +- examples/ir3/simple.ir | 4 +- examples/ir3/while_continue_break.ir | 16 ++-- examples/ir4/cond_and_loop.ir | 9 ++- examples/ir4/fibonacci.ir | 7 +- examples/ir4/foo3.ir | 7 +- examples/ir4/simple.ir | 4 +- examples/ir4/while_continue_break.ir | 16 ++-- src/ir/mod.rs | 7 +- src/ir/parse.rs | 8 ++ src/tests.rs | 113 +++++++++++++++++++++++---- tests/reduce-criteria-template.sh | 2 +- 36 files changed, 314 insertions(+), 149 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 16bfb0d..c8ec49c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,6 +160,7 @@ dependencies = [ "lang-c 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "peg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index fffea63..25fcb83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,4 @@ ordered-float = "1.0" hexf = "0.1.0" wait-timeout = "0.2.0" peg = "0.6.2" +rand = "0.7" diff --git a/examples/c/cond_and_loop.c b/examples/c/cond_and_loop.c index a902561..57d247d 100644 --- a/examples/c/cond_and_loop.c +++ b/examples/c/cond_and_loop.c @@ -1,13 +1,16 @@ +int nonce; // For random input + int main() { int i; int p = 2; int q = 5; int r = (0 ? ((p > q) ? (p -= 2) : (p += 2)) : (p + q)); + int loop_num = nonce % 100; - for (i = 0; i < 11; ((i % 2) ? (i += 2) : ++i)) { + for (i = 0; i < loop_num; ((i % 2) ? (i += 2) : ++i)) { if (i % 2) { p += q; } else { p += r; } } - return p == 34; + return p; } diff --git a/examples/c/fibonacci.c b/examples/c/fibonacci.c index a65fe3a..537f73c 100644 --- a/examples/c/fibonacci.c +++ b/examples/c/fibonacci.c @@ -1,3 +1,5 @@ +int nonce; // For random input + int fibonacci(int n) { if (n < 2) { return n; @@ -7,5 +9,6 @@ int fibonacci(int n) { } int main() { - return fibonacci(9) == 34; + int number = nonce % 20; + return fibonacci(number); } diff --git a/examples/c/foo3.c b/examples/c/foo3.c index 1392714..f86010c 100644 --- a/examples/c/foo3.c +++ b/examples/c/foo3.c @@ -1,3 +1,4 @@ +int nonce; // For random input int g = 10; int foo(int, int k); @@ -5,9 +6,9 @@ int foo(int, int k); int main() { int i = g; - return foo(i, i) == 30; + return foo(i, i); } int foo(int i, int j) { - return i + j + g; + return i + j + nonce; } diff --git a/examples/c/simple.c b/examples/c/simple.c index 29fc1ed..a95da05 100644 --- a/examples/c/simple.c +++ b/examples/c/simple.c @@ -1,5 +1,7 @@ +int nonce; // For random input + int main() { - int x = 1; - return 1; + int x = nonce; + return x; } diff --git a/examples/c/while_continue_break.c b/examples/c/while_continue_break.c index 6e51fb3..940c008 100644 --- a/examples/c/while_continue_break.c +++ b/examples/c/while_continue_break.c @@ -1,21 +1,24 @@ +int nonce; // For random input + int foo() { int sum = 0; int i = 0; + int continue_num = nonce % 98; - while(i < 10) { - if(i == 3) { + while(i < 100) { + if(i == continue_num) { i++; continue; } sum += i; i++; - if(i == 5) break; + if(i == continue_num + 2) break; } return sum; } int main() { - return foo() == 7; + return foo(); } diff --git a/examples/ir0/cond_and_loop.ir b/examples/ir0/cond_and_loop.ir index d4b4ec5..60dc5b9 100644 --- a/examples/ir0/cond_and_loop.ir +++ b/examples/ir0/cond_and_loop.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @main () { init: @@ -9,7 +10,8 @@ init: %l3:i32:r %l4:i32:t0 %l5:i32:t1 - %l6:i32:t2 + %l6:i32:loop_num + %l7:i32:t2 block b0: %b0:i0:unit = store 2:i32 %l1:i32* @@ -33,6 +35,9 @@ block b2: block b3: %b3:i0:i32 = load %l5:i32* %b3:i1:unit = store %b3:i0:i32 %l3:i32* + %b3:i2:i32 = load @nonce:i32* + %b3:i3:i32 = mod %b3:i2:i32 100:i32 + %b3:i4:unit = store %b3:i3:i32 %l6:i32* j b7() block b4: @@ -60,8 +65,9 @@ block b7: block b8: %b8:i0:i32 = load %l0:i32* - %b8:i1:u1 = cmp lt %b8:i0:i32 11:i32 - br %b8:i1:u1, b9(), b11() + %b8:i1:i32 = load %l6:i32* + %b8:i2:u1 = cmp lt %b8:i0:i32 %b8:i1:i32 + br %b8:i2:u1, b9(), b11() block b9: %b9:i0:i32 = load %l0:i32* @@ -77,9 +83,7 @@ block b10: block b11: %b11:i0:i32 = load %l1:i32* - %b11:i1:u1 = cmp eq %b11:i0:i32 34:i32 - %b11:i2:i32 = typecast %b11:i1:u1 to i32 - ret %b11:i2:i32 + ret %b11:i0:i32 block b12: %b12:i0:i32 = load %l1:i32* @@ -102,18 +106,18 @@ block b15: %b15:i0:i32 = load %l0:i32* %b15:i1:i32 = add %b15:i0:i32 2:i32 %b15:i2:unit = store %b15:i1:i32 %l0:i32* - %b15:i3:unit = store %b15:i1:i32 %l6:i32* + %b15:i3:unit = store %b15:i1:i32 %l7:i32* j b17() block b16: %b16:i0:i32 = load %l0:i32* %b16:i1:i32 = add %b16:i0:i32 1:i32 %b16:i2:unit = store %b16:i1:i32 %l0:i32* - %b16:i3:unit = store %b16:i1:i32 %l6:i32* + %b16:i3:unit = store %b16:i1:i32 %l7:i32* j b17() block b17: - %b17:i0:i32 = load %l6:i32* + %b17:i0:i32 = load %l7:i32* j b8() block b18: diff --git a/examples/ir0/fibonacci.ir b/examples/ir0/fibonacci.ir index db43f06..61eca03 100644 --- a/examples/ir0/fibonacci.ir +++ b/examples/ir0/fibonacci.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @fibonacci (i32) { init: @@ -40,13 +41,15 @@ fun i32 @main () { init: bid: b0 allocations: - + %l0:i32:number block b0: - %b0:i0:i32 = call @fibonacci:[ret:i32 params:(i32)]*(9:i32) - %b0:i1:u1 = cmp eq %b0:i0:i32 34:i32 - %b0:i2:i32 = typecast %b0:i1:u1 to i32 - ret %b0:i2:i32 + %b0:i0:i32 = load @nonce:i32* + %b0:i1:i32 = mod %b0:i0:i32 20:i32 + %b0:i2:unit = store %b0:i1:i32 %l0:i32* + %b0:i3:i32 = load %l0:i32* + %b0:i4:i32 = call @fibonacci:[ret:i32 params:(i32)]*(%b0:i3:i32) + ret %b0:i4:i32 block b1: ret 0:i32 diff --git a/examples/ir0/foo3.ir b/examples/ir0/foo3.ir index f08e4f2..667fa2b 100644 --- a/examples/ir0/foo3.ir +++ b/examples/ir0/foo3.ir @@ -1,4 +1,5 @@ var i32 @g = 10 +var i32 @nonce = default fun i32 @foo (i32, i32) { init: @@ -15,7 +16,7 @@ block b0: %b0:i2:i32 = load %l0:i32* %b0:i3:i32 = load %l1:i32* %b0:i4:i32 = add %b0:i2:i32 %b0:i3:i32 - %b0:i5:i32 = load @g:i32* + %b0:i5:i32 = load @nonce:i32* %b0:i6:i32 = add %b0:i4:i32 %b0:i5:i32 ret %b0:i6:i32 @@ -35,9 +36,7 @@ block b0: %b0:i2:i32 = load %l0:i32* %b0:i3:i32 = load %l0:i32* %b0:i4:i32 = call @foo:[ret:i32 params:(i32, i32)]*(%b0:i2:i32, %b0:i3:i32) - %b0:i5:u1 = cmp eq %b0:i4:i32 30:i32 - %b0:i6:i32 = typecast %b0:i5:u1 to i32 - ret %b0:i6:i32 + ret %b0:i4:i32 block b1: ret 0:i32 diff --git a/examples/ir0/simple.ir b/examples/ir0/simple.ir index 7584bb8..d81c15e 100644 --- a/examples/ir0/simple.ir +++ b/examples/ir0/simple.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @main () { init: @@ -6,8 +7,10 @@ init: %l0:i32:x block b0: - %b0:i0:unit = store 1:i32 %l0:i32* - ret 1:i32 + %b0:i0:i32 = load @nonce:i32* + %b0:i1:unit = store %b0:i0:i32 %l0:i32* + %b0:i2:i32 = load %l0:i32* + ret %b0:i2:i32 block b1: ret 0:i32 diff --git a/examples/ir0/while_continue_break.ir b/examples/ir0/while_continue_break.ir index d52d43b..a737174 100644 --- a/examples/ir0/while_continue_break.ir +++ b/examples/ir0/while_continue_break.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @foo () { init: @@ -5,21 +6,26 @@ init: allocations: %l0:i32:sum %l1:i32:i + %l2:i32:continue_num block b0: %b0:i0:unit = store 0:i32 %l0:i32* %b0:i1:unit = store 0:i32 %l1:i32* + %b0:i2:i32 = load @nonce:i32* + %b0:i3:i32 = mod %b0:i2:i32 98:i32 + %b0:i4:unit = store %b0:i3:i32 %l2:i32* j b1() block b1: %b1:i0:i32 = load %l1:i32* - %b1:i1:u1 = cmp lt %b1:i0:i32 10:i32 + %b1:i1:u1 = cmp lt %b1:i0:i32 100:i32 br %b1:i1:u1, b2(), b3() block b2: %b2:i0:i32 = load %l1:i32* - %b2:i1:u1 = cmp eq %b2:i0:i32 3:i32 - br %b2:i1:u1, b4(), b5() + %b2:i1:i32 = load %l2:i32* + %b2:i2:u1 = cmp eq %b2:i0:i32 %b2:i1:i32 + br %b2:i2:u1, b4(), b5() block b3: %b3:i0:i32 = load %l0:i32* @@ -43,8 +49,10 @@ block b6: %b6:i5:i32 = add %b6:i4:i32 1:i32 %b6:i6:unit = store %b6:i5:i32 %l1:i32* %b6:i7:i32 = load %l1:i32* - %b6:i8:u1 = cmp eq %b6:i7:i32 5:i32 - br %b6:i8:u1, b8(), b9() + %b6:i8:i32 = load %l2:i32* + %b6:i9:i32 = add %b6:i8:i32 2:i32 + %b6:i10:u1 = cmp eq %b6:i7:i32 %b6:i9:i32 + br %b6:i10:u1, b8(), b9() block b7: j b6() @@ -73,9 +81,7 @@ init: block b0: %b0:i0:i32 = call @foo:[ret:i32 params:()]*() - %b0:i1:u1 = cmp eq %b0:i0:i32 7:i32 - %b0:i2:i32 = typecast %b0:i1:u1 to i32 - ret %b0:i2:i32 + ret %b0:i0:i32 block b1: ret 0:i32 diff --git a/examples/ir1/cond_and_loop.ir b/examples/ir1/cond_and_loop.ir index 8677235..6eb7081 100644 --- a/examples/ir1/cond_and_loop.ir +++ b/examples/ir1/cond_and_loop.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @main () { init: @@ -9,7 +10,8 @@ init: %l3:i32:r %l4:i32:t0 %l5:i32:t1 - %l6:i32:t2 + %l6:i32:loop_num + %l7:i32:t2 block b0: %b0:i0:unit = store 2:i32 %l1:i32* @@ -33,7 +35,10 @@ block b2: block b3: %b3:i0:i32 = load %l5:i32* %b3:i1:unit = store %b3:i0:i32 %l3:i32* - %b3:i2:unit = store 0:i32 %l0:i32* + %b3:i2:i32 = load @nonce:i32* + %b3:i3:i32 = mod %b3:i2:i32 100:i32 + %b3:i4:unit = store %b3:i3:i32 %l6:i32* + %b3:i5:unit = store 0:i32 %l0:i32* j b8() block b4: @@ -57,8 +62,9 @@ block b6: block b8: %b8:i0:i32 = load %l0:i32* - %b8:i1:u1 = cmp lt %b8:i0:i32 11:i32 - br %b8:i1:u1, b9(), b11() + %b8:i1:i32 = load %l6:i32* + %b8:i2:u1 = cmp lt %b8:i0:i32 %b8:i1:i32 + br %b8:i2:u1, b9(), b11() block b9: %b9:i0:i32 = load %l0:i32* @@ -68,9 +74,7 @@ block b9: block b11: %b11:i0:i32 = load %l1:i32* - %b11:i1:u1 = cmp eq %b11:i0:i32 34:i32 - %b11:i2:i32 = typecast %b11:i1:u1 to i32 - ret %b11:i2:i32 + ret %b11:i0:i32 block b12: %b12:i0:i32 = load %l1:i32* @@ -96,17 +100,17 @@ block b15: %b15:i0:i32 = load %l0:i32* %b15:i1:i32 = add %b15:i0:i32 2:i32 %b15:i2:unit = store %b15:i1:i32 %l0:i32* - %b15:i3:unit = store %b15:i1:i32 %l6:i32* + %b15:i3:unit = store %b15:i1:i32 %l7:i32* j b17() block b16: %b16:i0:i32 = load %l0:i32* %b16:i1:i32 = add %b16:i0:i32 1:i32 %b16:i2:unit = store %b16:i1:i32 %l0:i32* - %b16:i3:unit = store %b16:i1:i32 %l6:i32* + %b16:i3:unit = store %b16:i1:i32 %l7:i32* j b17() block b17: - %b17:i0:i32 = load %l6:i32* + %b17:i0:i32 = load %l7:i32* j b8() } diff --git a/examples/ir1/fibonacci.ir b/examples/ir1/fibonacci.ir index 95f56e9..fc78988 100644 --- a/examples/ir1/fibonacci.ir +++ b/examples/ir1/fibonacci.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @fibonacci (i32) { init: @@ -31,11 +32,13 @@ fun i32 @main () { init: bid: b0 allocations: - + %l0:i32:number block b0: - %b0:i0:i32 = call @fibonacci:[ret:i32 params:(i32)]*(9:i32) - %b0:i1:u1 = cmp eq %b0:i0:i32 34:i32 - %b0:i2:i32 = typecast %b0:i1:u1 to i32 - ret %b0:i2:i32 + %b0:i0:i32 = load @nonce:i32* + %b0:i1:i32 = mod %b0:i0:i32 20:i32 + %b0:i2:unit = store %b0:i1:i32 %l0:i32* + %b0:i3:i32 = load %l0:i32* + %b0:i4:i32 = call @fibonacci:[ret:i32 params:(i32)]*(%b0:i3:i32) + ret %b0:i4:i32 } diff --git a/examples/ir1/foo3.ir b/examples/ir1/foo3.ir index 5c974f8..3090014 100644 --- a/examples/ir1/foo3.ir +++ b/examples/ir1/foo3.ir @@ -1,4 +1,5 @@ var i32 @g = 10 +var i32 @nonce = default fun i32 @foo (i32, i32) { init: @@ -15,7 +16,7 @@ block b0: %b0:i2:i32 = load %l0:i32* %b0:i3:i32 = load %l1:i32* %b0:i4:i32 = add %b0:i2:i32 %b0:i3:i32 - %b0:i5:i32 = load @g:i32* + %b0:i5:i32 = load @nonce:i32* %b0:i6:i32 = add %b0:i4:i32 %b0:i5:i32 ret %b0:i6:i32 } @@ -32,7 +33,5 @@ block b0: %b0:i2:i32 = load %l0:i32* %b0:i3:i32 = load %l0:i32* %b0:i4:i32 = call @foo:[ret:i32 params:(i32, i32)]*(%b0:i2:i32, %b0:i3:i32) - %b0:i5:u1 = cmp eq %b0:i4:i32 30:i32 - %b0:i6:i32 = typecast %b0:i5:u1 to i32 - ret %b0:i6:i32 + ret %b0:i4:i32 } diff --git a/examples/ir1/simple.ir b/examples/ir1/simple.ir index 14b2891..f449776 100644 --- a/examples/ir1/simple.ir +++ b/examples/ir1/simple.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @main () { init: @@ -6,6 +7,8 @@ init: %l0:i32:x block b0: - %b0:i0:unit = store 1:i32 %l0:i32* - ret 1:i32 + %b0:i0:i32 = load @nonce:i32* + %b0:i1:unit = store %b0:i0:i32 %l0:i32* + %b0:i2:i32 = load %l0:i32* + ret %b0:i2:i32 } diff --git a/examples/ir1/while_continue_break.ir b/examples/ir1/while_continue_break.ir index 98161b4..4eaabd7 100644 --- a/examples/ir1/while_continue_break.ir +++ b/examples/ir1/while_continue_break.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @foo () { init: @@ -5,21 +6,26 @@ init: allocations: %l0:i32:sum %l1:i32:i + %l2:i32:continue_num block b0: %b0:i0:unit = store 0:i32 %l0:i32* %b0:i1:unit = store 0:i32 %l1:i32* + %b0:i2:i32 = load @nonce:i32* + %b0:i3:i32 = mod %b0:i2:i32 98:i32 + %b0:i4:unit = store %b0:i3:i32 %l2:i32* j b1() block b1: %b1:i0:i32 = load %l1:i32* - %b1:i1:u1 = cmp lt %b1:i0:i32 10:i32 + %b1:i1:u1 = cmp lt %b1:i0:i32 100:i32 br %b1:i1:u1, b2(), b3() block b2: %b2:i0:i32 = load %l1:i32* - %b2:i1:u1 = cmp eq %b2:i0:i32 3:i32 - br %b2:i1:u1, b4(), b5() + %b2:i1:i32 = load %l2:i32* + %b2:i2:u1 = cmp eq %b2:i0:i32 %b2:i1:i32 + br %b2:i2:u1, b4(), b5() block b3: %b3:i0:i32 = load %l0:i32* @@ -40,8 +46,10 @@ block b5: %b5:i5:i32 = add %b5:i4:i32 1:i32 %b5:i6:unit = store %b5:i5:i32 %l1:i32* %b5:i7:i32 = load %l1:i32* - %b5:i8:u1 = cmp eq %b5:i7:i32 5:i32 - br %b5:i8:u1, b3(), b1() + %b5:i8:i32 = load %l2:i32* + %b5:i9:i32 = add %b5:i8:i32 2:i32 + %b5:i10:u1 = cmp eq %b5:i7:i32 %b5:i9:i32 + br %b5:i10:u1, b3(), b1() } fun i32 @main () { @@ -52,7 +60,5 @@ init: block b0: %b0:i0:i32 = call @foo:[ret:i32 params:()]*() - %b0:i1:u1 = cmp eq %b0:i0:i32 7:i32 - %b0:i2:i32 = typecast %b0:i1:u1 to i32 - ret %b0:i2:i32 + ret %b0:i0:i32 } diff --git a/examples/ir2/cond_and_loop.ir b/examples/ir2/cond_and_loop.ir index 4736d7a..9b08ef2 100644 --- a/examples/ir2/cond_and_loop.ir +++ b/examples/ir2/cond_and_loop.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @main () { init: @@ -9,7 +10,8 @@ init: %l3:i32:r %l4:i32:t0 %l5:i32:t1 - %l6:i32:t2 + %l6:i32:loop_num + %l7:i32:t2 block b0: %b0:i0:unit = nop @@ -35,7 +37,10 @@ block b3: %b3:p1:i32:t1 %b3:i0:unit = nop %b3:i1:unit = nop - %b3:i2:unit = nop + %b3:i2:i32 = load @nonce:i32* + %b3:i3:i32 = mod %b3:i2:i32 100:i32 + %b3:i4:unit = nop + %b3:i5:unit = nop j b8(0:i32, %b3:p0:i32) block b4: @@ -63,8 +68,9 @@ block b8: %b8:p0:i32:i %b8:p1:i32:p %b8:i0:unit = nop - %b8:i1:u1 = cmp lt %b8:p0:i32 11:i32 - br %b8:i1:u1, b9(), b11() + %b8:i1:unit = nop + %b8:i2:u1 = cmp lt %b8:p0:i32 %b3:i3:i32 + br %b8:i2:u1, b9(), b11() block b9: %b9:i0:unit = nop @@ -74,9 +80,7 @@ block b9: block b11: %b11:i0:unit = nop - %b11:i1:u1 = cmp eq %b8:p1:i32 34:i32 - %b11:i2:i32 = typecast %b11:i1:u1 to i32 - ret %b11:i2:i32 + ret %b8:p1:i32 block b12: %b12:i0:unit = nop diff --git a/examples/ir2/fibonacci.ir b/examples/ir2/fibonacci.ir index 728399d..1d477cf 100644 --- a/examples/ir2/fibonacci.ir +++ b/examples/ir2/fibonacci.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @fibonacci (i32) { init: @@ -31,11 +32,13 @@ fun i32 @main () { init: bid: b0 allocations: - + %l0:i32:number block b0: - %b0:i0:i32 = call @fibonacci:[ret:i32 params:(i32)]*(9:i32) - %b0:i1:u1 = cmp eq %b0:i0:i32 34:i32 - %b0:i2:i32 = typecast %b0:i1:u1 to i32 - ret %b0:i2:i32 + %b0:i0:i32 = load @nonce:i32* + %b0:i1:i32 = mod %b0:i0:i32 20:i32 + %b0:i2:unit = nop + %b0:i3:unit = nop + %b0:i4:i32 = call @fibonacci:[ret:i32 params:(i32)]*(%b0:i1:i32) + ret %b0:i4:i32 } diff --git a/examples/ir2/foo3.ir b/examples/ir2/foo3.ir index a4cd96b..f57d193 100644 --- a/examples/ir2/foo3.ir +++ b/examples/ir2/foo3.ir @@ -1,4 +1,5 @@ var i32 @g = 10 +var i32 @nonce = default fun i32 @foo (i32, i32) { init: @@ -15,7 +16,7 @@ block b0: %b0:i2:unit = nop %b0:i3:unit = nop %b0:i4:i32 = add %b0:p0:i32 %b0:p1:i32 - %b0:i5:i32 = load @g:i32* + %b0:i5:i32 = load @nonce:i32* %b0:i6:i32 = add %b0:i4:i32 %b0:i5:i32 ret %b0:i6:i32 } @@ -32,7 +33,5 @@ block b0: %b0:i2:unit = nop %b0:i3:unit = nop %b0:i4:i32 = call @foo:[ret:i32 params:(i32, i32)]*(%b0:i0:i32, %b0:i0:i32) - %b0:i5:u1 = cmp eq %b0:i4:i32 30:i32 - %b0:i6:i32 = typecast %b0:i5:u1 to i32 - ret %b0:i6:i32 + ret %b0:i4:i32 } diff --git a/examples/ir2/simple.ir b/examples/ir2/simple.ir index f9242dc..ac91ca6 100644 --- a/examples/ir2/simple.ir +++ b/examples/ir2/simple.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @main () { init: @@ -6,6 +7,8 @@ init: %l0:i32:x block b0: - %b0:i0:unit = nop - ret 1:i32 + %b0:i0:i32 = load @nonce:i32* + %b0:i1:unit = nop + %b0:i2:unit = nop + ret %b0:i0:i32 } diff --git a/examples/ir2/while_continue_break.ir b/examples/ir2/while_continue_break.ir index 7f02810..8bf32c4 100644 --- a/examples/ir2/while_continue_break.ir +++ b/examples/ir2/while_continue_break.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @foo () { init: @@ -5,23 +6,28 @@ init: allocations: %l0:i32:sum %l1:i32:i + %l2:i32:continue_num block b0: %b0:i0:unit = nop %b0:i1:unit = nop + %b0:i2:i32 = load @nonce:i32* + %b0:i3:i32 = mod %b0:i2:i32 98:i32 + %b0:i4:unit = nop j b1(0:i32, 0:i32) block b1: %b1:p0:i32:sum %b1:p1:i32:i %b1:i0:unit = nop - %b1:i1:u1 = cmp lt %b1:p1:i32 10:i32 + %b1:i1:u1 = cmp lt %b1:p1:i32 100:i32 br %b1:i1:u1, b2(), b3(%b1:p0:i32) block b2: %b2:i0:unit = nop - %b2:i1:u1 = cmp eq %b1:p1:i32 3:i32 - br %b2:i1:u1, b4(), b5() + %b2:i1:unit = nop + %b2:i2:u1 = cmp eq %b1:p1:i32 %b0:i3:i32 + br %b2:i2:u1, b4(), b5() block b3: %b3:p0:i32:sum @@ -43,8 +49,10 @@ block b5: %b5:i5:i32 = add %b1:p1:i32 1:i32 %b5:i6:unit = nop %b5:i7:unit = nop - %b5:i8:u1 = cmp eq %b5:i5:i32 5:i32 - br %b5:i8:u1, b3(%b5:i2:i32), b1(%b5:i2:i32, %b5:i5:i32) + %b5:i8:unit = nop + %b5:i9:i32 = add %b0:i3:i32 2:i32 + %b5:i10:u1 = cmp eq %b5:i5:i32 %b5:i9:i32 + br %b5:i10:u1, b3(%b5:i2:i32), b1(%b5:i2:i32, %b5:i5:i32) } fun i32 @main () { @@ -55,7 +63,5 @@ init: block b0: %b0:i0:i32 = call @foo:[ret:i32 params:()]*() - %b0:i1:u1 = cmp eq %b0:i0:i32 7:i32 - %b0:i2:i32 = typecast %b0:i1:u1 to i32 - ret %b0:i2:i32 + ret %b0:i0:i32 } diff --git a/examples/ir3/cond_and_loop.ir b/examples/ir3/cond_and_loop.ir index 77a1f3d..03ca775 100644 --- a/examples/ir3/cond_and_loop.ir +++ b/examples/ir3/cond_and_loop.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @main () { init: @@ -20,6 +21,8 @@ block b2: block b3: %b3:p0:i32:p %b3:p1:i32:t1 + %b3:i0:i32 = load @nonce:i32* + %b3:i1:i32 = mod %b3:i0:i32 100:i32 j b8(0:i32, %b3:p0:i32) block b4: @@ -38,7 +41,7 @@ block b6: block b8: %b8:p0:i32:i %b8:p1:i32:p - %b8:i0:u1 = cmp lt %b8:p0:i32 11:i32 + %b8:i0:u1 = cmp lt %b8:p0:i32 %b3:i1:i32 br %b8:i0:u1, b9(), b11() block b9: @@ -47,9 +50,7 @@ block b9: br %b9:i1:u1, b12(), b13() block b11: - %b11:i0:u1 = cmp eq %b8:p1:i32 34:i32 - %b11:i1:i32 = typecast %b11:i0:u1 to i32 - ret %b11:i1:i32 + ret %b8:p1:i32 block b12: %b12:i0:i32 = add %b8:p1:i32 5:i32 diff --git a/examples/ir3/fibonacci.ir b/examples/ir3/fibonacci.ir index 04ee26d..49c3a68 100644 --- a/examples/ir3/fibonacci.ir +++ b/examples/ir3/fibonacci.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @fibonacci (i32) { init: @@ -29,8 +30,8 @@ init: block b0: - %b0:i0:i32 = call @fibonacci:[ret:i32 params:(i32)]*(9:i32) - %b0:i1:u1 = cmp eq %b0:i0:i32 34:i32 - %b0:i2:i32 = typecast %b0:i1:u1 to i32 + %b0:i0:i32 = load @nonce:i32* + %b0:i1:i32 = mod %b0:i0:i32 20:i32 + %b0:i2:i32 = call @fibonacci:[ret:i32 params:(i32)]*(%b0:i1:i32) ret %b0:i2:i32 } diff --git a/examples/ir3/foo3.ir b/examples/ir3/foo3.ir index b94e727..226097f 100644 --- a/examples/ir3/foo3.ir +++ b/examples/ir3/foo3.ir @@ -1,4 +1,5 @@ var i32 @g = 10 +var i32 @nonce = default fun i32 @foo (i32, i32) { init: @@ -10,7 +11,7 @@ block b0: %b0:p0:i32:i %b0:p1:i32:j %b0:i0:i32 = add %b0:p0:i32 %b0:p1:i32 - %b0:i1:i32 = load @g:i32* + %b0:i1:i32 = load @nonce:i32* %b0:i2:i32 = add %b0:i0:i32 %b0:i1:i32 ret %b0:i2:i32 } @@ -24,7 +25,5 @@ init: block b0: %b0:i0:i32 = load @g:i32* %b0:i1:i32 = call @foo:[ret:i32 params:(i32, i32)]*(%b0:i0:i32, %b0:i0:i32) - %b0:i2:u1 = cmp eq %b0:i1:i32 30:i32 - %b0:i3:i32 = typecast %b0:i2:u1 to i32 - ret %b0:i3:i32 + ret %b0:i1:i32 } diff --git a/examples/ir3/simple.ir b/examples/ir3/simple.ir index 9adaea1..1d4accf 100644 --- a/examples/ir3/simple.ir +++ b/examples/ir3/simple.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @main () { init: @@ -6,5 +7,6 @@ init: block b0: - ret 1:i32 + %b0:i0:i32 = load @nonce:i32* + ret %b0:i0:i32 } diff --git a/examples/ir3/while_continue_break.ir b/examples/ir3/while_continue_break.ir index 378789a..15156c9 100644 --- a/examples/ir3/while_continue_break.ir +++ b/examples/ir3/while_continue_break.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @foo () { init: @@ -6,16 +7,18 @@ init: block b0: + %b0:i0:i32 = load @nonce:i32* + %b0:i1:i32 = mod %b0:i0:i32 98:i32 j b1(0:i32, 0:i32) block b1: %b1:p0:i32:sum %b1:p1:i32:i - %b1:i0:u1 = cmp lt %b1:p1:i32 10:i32 + %b1:i0:u1 = cmp lt %b1:p1:i32 100:i32 br %b1:i0:u1, b2(), b3(%b1:p0:i32) block b2: - %b2:i0:u1 = cmp eq %b1:p1:i32 3:i32 + %b2:i0:u1 = cmp eq %b1:p1:i32 %b0:i1:i32 br %b2:i0:u1, b4(), b5() block b3: @@ -29,8 +32,9 @@ block b4: block b5: %b5:i0:i32 = add %b1:p0:i32 %b1:p1:i32 %b5:i1:i32 = add %b1:p1:i32 1:i32 - %b5:i2:u1 = cmp eq %b5:i1:i32 5:i32 - br %b5:i2:u1, b3(%b5:i0:i32), b1(%b5:i0:i32, %b5:i1:i32) + %b5:i2:i32 = add %b0:i1:i32 2:i32 + %b5:i3:u1 = cmp eq %b5:i1:i32 %b5:i2:i32 + br %b5:i3:u1, b3(%b5:i0:i32), b1(%b5:i0:i32, %b5:i1:i32) } fun i32 @main () { @@ -41,7 +45,5 @@ init: block b0: %b0:i0:i32 = call @foo:[ret:i32 params:()]*() - %b0:i1:u1 = cmp eq %b0:i0:i32 7:i32 - %b0:i2:i32 = typecast %b0:i1:u1 to i32 - ret %b0:i2:i32 + ret %b0:i0:i32 } diff --git a/examples/ir4/cond_and_loop.ir b/examples/ir4/cond_and_loop.ir index 24af09a..6815c89 100644 --- a/examples/ir4/cond_and_loop.ir +++ b/examples/ir4/cond_and_loop.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @main () { init: @@ -20,6 +21,8 @@ block b2: block b3: %b3:p0:i32:p %b3:p1:i32:t1 + %b3:i0:i32 = load @nonce:i32* + %b3:i1:i32 = mod %b3:i0:i32 100:i32 j b8(0:i32, %b3:p0:i32) block b4: @@ -38,7 +41,7 @@ block b6: block b8: %b8:p0:i32:i %b8:p1:i32:p - %b8:i0:u1 = cmp lt %b8:p0:i32 11:i32 + %b8:i0:u1 = cmp lt %b8:p0:i32 %b3:i1:i32 br %b8:i0:u1, b9(), b11() block b9: @@ -47,9 +50,7 @@ block b9: br %b9:i1:u1, b12(), b13() block b11: - %b11:i0:u1 = cmp eq %b8:p1:i32 34:i32 - %b11:i1:i32 = typecast %b11:i0:u1 to i32 - ret %b11:i1:i32 + ret %b8:p1:i32 block b12: %b12:i0:i32 = add %b8:p1:i32 5:i32 diff --git a/examples/ir4/fibonacci.ir b/examples/ir4/fibonacci.ir index 04ee26d..49c3a68 100644 --- a/examples/ir4/fibonacci.ir +++ b/examples/ir4/fibonacci.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @fibonacci (i32) { init: @@ -29,8 +30,8 @@ init: block b0: - %b0:i0:i32 = call @fibonacci:[ret:i32 params:(i32)]*(9:i32) - %b0:i1:u1 = cmp eq %b0:i0:i32 34:i32 - %b0:i2:i32 = typecast %b0:i1:u1 to i32 + %b0:i0:i32 = load @nonce:i32* + %b0:i1:i32 = mod %b0:i0:i32 20:i32 + %b0:i2:i32 = call @fibonacci:[ret:i32 params:(i32)]*(%b0:i1:i32) ret %b0:i2:i32 } diff --git a/examples/ir4/foo3.ir b/examples/ir4/foo3.ir index b94e727..226097f 100644 --- a/examples/ir4/foo3.ir +++ b/examples/ir4/foo3.ir @@ -1,4 +1,5 @@ var i32 @g = 10 +var i32 @nonce = default fun i32 @foo (i32, i32) { init: @@ -10,7 +11,7 @@ block b0: %b0:p0:i32:i %b0:p1:i32:j %b0:i0:i32 = add %b0:p0:i32 %b0:p1:i32 - %b0:i1:i32 = load @g:i32* + %b0:i1:i32 = load @nonce:i32* %b0:i2:i32 = add %b0:i0:i32 %b0:i1:i32 ret %b0:i2:i32 } @@ -24,7 +25,5 @@ init: block b0: %b0:i0:i32 = load @g:i32* %b0:i1:i32 = call @foo:[ret:i32 params:(i32, i32)]*(%b0:i0:i32, %b0:i0:i32) - %b0:i2:u1 = cmp eq %b0:i1:i32 30:i32 - %b0:i3:i32 = typecast %b0:i2:u1 to i32 - ret %b0:i3:i32 + ret %b0:i1:i32 } diff --git a/examples/ir4/simple.ir b/examples/ir4/simple.ir index 9adaea1..1d4accf 100644 --- a/examples/ir4/simple.ir +++ b/examples/ir4/simple.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @main () { init: @@ -6,5 +7,6 @@ init: block b0: - ret 1:i32 + %b0:i0:i32 = load @nonce:i32* + ret %b0:i0:i32 } diff --git a/examples/ir4/while_continue_break.ir b/examples/ir4/while_continue_break.ir index 378789a..15156c9 100644 --- a/examples/ir4/while_continue_break.ir +++ b/examples/ir4/while_continue_break.ir @@ -1,3 +1,4 @@ +var i32 @nonce = default fun i32 @foo () { init: @@ -6,16 +7,18 @@ init: block b0: + %b0:i0:i32 = load @nonce:i32* + %b0:i1:i32 = mod %b0:i0:i32 98:i32 j b1(0:i32, 0:i32) block b1: %b1:p0:i32:sum %b1:p1:i32:i - %b1:i0:u1 = cmp lt %b1:p1:i32 10:i32 + %b1:i0:u1 = cmp lt %b1:p1:i32 100:i32 br %b1:i0:u1, b2(), b3(%b1:p0:i32) block b2: - %b2:i0:u1 = cmp eq %b1:p1:i32 3:i32 + %b2:i0:u1 = cmp eq %b1:p1:i32 %b0:i1:i32 br %b2:i0:u1, b4(), b5() block b3: @@ -29,8 +32,9 @@ block b4: block b5: %b5:i0:i32 = add %b1:p0:i32 %b1:p1:i32 %b5:i1:i32 = add %b1:p1:i32 1:i32 - %b5:i2:u1 = cmp eq %b5:i1:i32 5:i32 - br %b5:i2:u1, b3(%b5:i0:i32), b1(%b5:i0:i32, %b5:i1:i32) + %b5:i2:i32 = add %b0:i1:i32 2:i32 + %b5:i3:u1 = cmp eq %b5:i1:i32 %b5:i2:i32 + br %b5:i3:u1, b3(%b5:i0:i32), b1(%b5:i0:i32, %b5:i1:i32) } fun i32 @main () { @@ -41,7 +45,5 @@ init: block b0: %b0:i0:i32 = call @foo:[ret:i32 params:()]*() - %b0:i1:u1 = cmp eq %b0:i0:i32 7:i32 - %b0:i2:i32 = typecast %b0:i1:u1 to i32 - ret %b0:i2:i32 + ret %b0:i0:i32 } diff --git a/src/ir/mod.rs b/src/ir/mod.rs index d6842d5..0325cc5 100644 --- a/src/ir/mod.rs +++ b/src/ir/mod.rs @@ -527,7 +527,12 @@ impl TryFrom<&ast::Constant> for Constant { ast::IntegerBase::Octal => Self::OCTAL, ast::IntegerBase::Hexadecimal => Self::HEXADECIMAL, }; - let value = u128::from_str_radix(integer.number.deref(), pat).unwrap(); + + let value = if integer.suffix.unsigned { + u128::from_str_radix(integer.number.deref(), pat).unwrap() + } else { + i128::from_str_radix(integer.number.deref(), pat).unwrap() as u128 + }; let is_signed = !integer.suffix.unsigned && { // Even if `suffix` represents `signed`, integer literal cannot be translated diff --git a/src/ir/parse.rs b/src/ir/parse.rs index d99145e..b150418 100644 --- a/src/ir/parse.rs +++ b/src/ir/parse.rs @@ -580,6 +580,14 @@ peg::parser! { suffix, } } + / + "0" suffix:ast_integer_suffix() { + ast::Integer { + base: ast::IntegerBase::Decimal, + number: Box::from("0"), + suffix, + } + } / "" { todo!() diff --git a/src/tests.rs b/src/tests.rs index 9ae2b7c..84cb608 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,3 +1,5 @@ +use lang_c::*; +use rand::Rng; use std::fs::{self, File}; use std::io::{stderr, Read, Write}; use std::path::Path; @@ -7,6 +9,67 @@ use wait_timeout::ChildExt; use crate::*; +const NONCE_DTYPE: &str = "int"; +const NONCE_NAME: &str = "nonce"; + +fn modify_c(path: &Path, rand_num: i32) -> String { + let mut src = File::open(path).expect("`path` must exist"); + let mut data = String::new(); + src.read_to_string(&mut data) + .expect("`src` must be converted to string"); + drop(src); + + let from = format!("{} {}", NONCE_DTYPE, NONCE_NAME); + let to = format!("{} = {}", from, rand_num); + data.replace(&from, &to) +} + +fn ast_initializer(number: i32) -> ast::Initializer { + let expr = ast::Expression::Constant(Box::new(span::Node::new( + ast::Constant::Integer(ast::Integer { + base: ast::IntegerBase::Decimal, + number: Box::from(&number.to_string() as &str), + suffix: ast::IntegerSuffix { + size: ast::IntegerSize::Int, + unsigned: false, + imaginary: false, + }, + }), + span::Span::none(), + ))); + + ast::Initializer::Expression(Box::new(span::Node::new(expr, span::Span::none()))) +} + +fn modify_ir(unit: &mut ir::TranslationUnit, rand_num: i32) { + for (name, decl) in &mut unit.decls { + if name == NONCE_NAME { + let (dtype, initializer) = decl.get_variable().expect("`decl` must be variable"); + assert!(initializer.is_none()); + + let initializer = ast_initializer(rand_num); + let new_decl = ir::Declaration::Variable { + dtype: dtype.clone(), + initializer: Some(initializer), + }; + + *decl = new_decl; + } + } +} + +fn modify_asm(unit: &mut asm::Asm, rand_num: i32) { + for variable in &mut unit.unit.variables { + let body = &mut variable.body; + if body.label == asm::Label(NONCE_NAME.to_string()) { + let directive = + asm::Directive::try_from_data_size(asm::DataSize::Word, rand_num as u64); + + body.directives = vec![directive]; + } + } +} + // Rust sets an exit code of 101 when the process panicked. // So, we decide KECC sets an exit code of 102 after 101 when the test skipped. pub const SKIP_TEST: i32 = 102; @@ -39,13 +102,27 @@ pub fn test_irgen(path: &Path) { .translate(&path) .unwrap_or_else(|_| panic!("parse failed {}", path.display())); - // Test parse - c::Parse::default() - .translate(&path) - .expect("failed to parse the given program"); + let mut ir = Irgen::default() + .translate(&unit) + .unwrap_or_else(|irgen_error| panic!("{}", irgen_error)); - let file_path = path.display().to_string(); - let bin_path = path.with_extension("irgen").as_path().display().to_string(); + // Apply random value to global variable `dyn` + let rand_num = rand::thread_rng().gen(); + let new_c = modify_c(path, rand_num); + modify_ir(&mut ir, rand_num); + + // compile recolved c example + let temp_dir = tempdir().expect("temp dir creation failed"); + let temp_file_path = temp_dir.path().join("temp.c"); + let mut temp_file = File::create(&temp_file_path).unwrap(); + temp_file.write_all(new_c.as_bytes()).unwrap(); + + let file_path = temp_file_path.display().to_string(); + let bin_path = temp_file_path + .with_extension("irgen") + .as_path() + .display() + .to_string(); // Compile c file: If fails, test is vacuously success if !Command::new("gcc") @@ -100,10 +177,10 @@ pub fn test_irgen(path: &Path) { } let status = some_or_exit!(status.code(), SKIP_TEST); + drop(temp_file); + temp_dir.close().expect("temp dir deletion failed"); - let ir = Irgen::default() - .translate(&unit) - .unwrap_or_else(|irgen_error| panic!("{}", irgen_error)); + // Interpret resolved ir let args = Vec::new(); let result = ir::interp(&ir, args).unwrap_or_else(|interp_error| panic!("{}", interp_error)); // We only allow main function whose return type is `int` @@ -217,22 +294,28 @@ pub fn test_opt, P2: AsRef, O: Optimize&1 | grep -q '(left == right)' +cargo run --manifest-path $PROJECT_DIR/Cargo.toml --release --bin fuzz -- $FUZZ_ARG test_reduced.c 2>&1 | grep -q 'assertion failed'