CSE 5343 programming projects - simple test cases
In addition to these simple test cases, it is your responsibility to write many test cases yourself, and test your implementation with them
Project 1
Test case: int f() { int x_2; x_2 = 0x34; }
Expected output (ignoring extra spaces/newlines from pretty printing): int f() { int x_2; (x_2=52); }
Test case: double f() { double y; y = 1.2 + 3.4e5; return y; }
Expected output: double f() { double y; (y=(1.2+340000.0)); return y; }
Test case: double f() { double y; y = 1.2; y += 3.4 + 5.6 * 7.8; }
Expected output: double f() { double y; (y=1.2); (y+=(3.4+(5.6*7.8))); }
Test case: int f() { double x; x = 3?14;}
Expected output: scanner error
Project 2
Test case: test program lpc.c - see project description for more details
Test case: int f() { int x; int y; int z; z = x < 5 + y < 6; }
Expected output: int f() { int x; int y; int z; (z=((x<(5+y))<6)); }
Test case: int f() { int x; while (x<10) x = x + 1; }
Expected output: int f() { int x; while ((x<10)) (x=(x+1)); }
Test case: int f() { int x; x = x - - x; }
Expected output: parser error
Project 3
Test case: test program lpc.c. Expected output: a gcc-compilable C program that contains 61 temporary variables of type int and 207 temporary variables of type double
Test case: int f() { double x; int y; double x; x = 1.2; y = 3; return y; } should fail semantic checking (exit code 2)
Test case: int f() { int a[5][0][10]; a[0][0][0] = 1; return 2; } should fail semantic checking (exit code 2)
Test case: int f() { int x; double y; double z; x = 1; y = 2.3; z = x + y; return 4;} should pass semantic checking (exit code 0). Expected output, but the declaration of _t1 could be anywhere in the declaration list: int f() { int x; double y; double z; double _t1; (x=1); (y=2.3); (z=(x+y)); return 4; }
Test case: int f() { int a[5][10][20]; a[1][2] = 3; return a[0][1][2]; } should fail semantic checking (exit code 2)
Test case: int f() { double x; int a[10][20]; return a[2][x+1]; } should fail semantic checking (exit code 2)
Test case: int f() { int a; int b; int c; int d; d = a+b+c; return d+1; } should pass semantic checking (exit code 0). Expected output, but the declarations of _t1 , _t2, and _t3 could be anywhere in the declaration list: int f() { int a; int b; int c; int d; int _t2; int _t1; int _t3; (d=((a+b)+c)); return (d+1); }
Test case: int f() { int a[5][10][20]; a[1][2][3] = 3; return a[0][1][2]; } should pass semantic checking (exit code 0). Expected output, but the declarations of _t1 and _t2 could be anywhere in the declaration list: int f() { int a[5][10][20]; int _t2; int _t1; (a[1][2][3]=3); return a[0][1][2]; }
Project 4
Note: program lpc.c cannot be a test case for this project, since it contains statements other than expression statements and return statements.
Test case: int f1() { int x; int y; int z; return x+y*z; }
Expected output: int f1() { int x; int y; int z; int _t2; int _t1; _t1 = y * z; _t2 = x + _t1; return _t2; } but any permutation of the declarations is OK
Test case: int f2() { int a[10][20]; int x; int y; int z; x = 1; y = 2; z = 3; a[y-x][y+x] = z + 2*y; return 1; }
Expected output: int f2() { int a[10][20]; int x; int y; int z; int _t5; int _t2; int _t1; int _t4; int _t3; x = 1; y = 2; z = 3; _t4 = 2 * y; _t5 = z + _t4; _t1 = y - x; _t2 = y + x; a[_t1][_t2] = _t5; return 1; } but any permutation of the declarations is OK
Test case: int f3() { int x; int y; int z; int w; w = z = (x = 1) + (y = x+2); return w; }
Expected output: int f3() { int x; int y; int z; int w; int _t2; int _t1; x = 1; _t1 = x + 2; y = _t1; _t2 = 1 + _t1; z = _t2; w = _t2; return w; } but any permutation of the declarations is OK
Test case: int f4() { int x; int y; int z; x = 1; y = 2; z = 3; return x-y*z; }
Expected output: int f4() { int x; int y; int z; int _t2; int _t1; x = 1; y = 2; z = 3; _t1 = y * z; _t2 = x - _t1; return _t2; }
Save the output to a file: ./simplec f4.c > f4.3addr.c and then compile gcc -o f4 main.c f4.3addr.c where main.c contains
#include <stdio.h> int f4(void); int main(void) { int res = f4(); printf("%d",res); }
Then execute ./f4 and observe the correct result -5 being printed
Test case: int f5() { int x; int y; int z; int w; x = 11; w = z = (x += 1) + (y = x+2); return x + y + z + w; }
Replace f4 with f5 in main.c. Run ./simplec f5.c > f5.3addr.c and then compile gcc -o f5 main.c f5.3addr.c
Then execute ./f5 and observe the correct result 78 being printed
Test case: int f6() { int a[2][3]; int x; x = 1; a[x][x+1] = x+2; return a[1][2]; }
Replace f5 with f6 in main.c. Run ./simplec f6.c > f6.3addr.c and then compile gcc -o f6 main.c f6.3addr.c
Then execute ./f6 and observe the correct result 3 being printed
Project 5
Test case: test program lpc.c. Expected output: a gcc-compilable C program. Save the output to a file: ./simplec lpc.c > lpc.3addr.c and then compile gcc -o lpc3addr main-lpc.c lpc.3addr.c where main-lpc.c contains #include <stdio.h> double lpc(void); int main(void) { double res = lpc(); printf("%lf",res); }
Expected run-time behavior: ./lpc3addr should produce 106.882296
Test case: int f1() { int x; int y; x = 1; if (x > 2) return 3; else { y = 4; return y; } }
Save the output to a file: ./simplec f1.c > f1.3addr.c and then compile gcc -o f1 main.c f1.3addr.c where main.c contains
#include <stdio.h> int f1(void); int main(void) { int res = f1(); printf("%d",res); }
Then execute ./f1 and observe the correct result 4 being printed
Test case: int f2() { int n; int i; int res; n = 10; i = 1; res = 1; while (i <= n) { res *= i; i += 1; } return res; }
Compile and run similarly to the previous test case. Observe the correct value of 3628800 being printed
Test case: int f3() { int n; int i; int res; n = 10; i = 1; res = 1; while (i <= n) { if (i % 2 == 0) res *= i; i += 1; } return res; }
Compile and run similarly to the previous test case. Observe the correct value of 3840 being printed
Project 6
Test case: int f() { int x; int y; int _t1; int _t2; x = 1; y = 2; _t1 = x < y; if (!t1) goto _l2; _t2 = x; goto _l1; _l2: _t2 = y; _l1: return _t2; }
CFG NODES: 6
CFG EDGES: 6
BACK EDGES: 0
NODES IN LOOPS: 0
Test case: int f() { return 1; }
CFG NODES: 3
CFG EDGES: 2
BACK EDGES: 0
NODES IN LOOPS: 0
Test case: int f() { int x; int _t2; int _t1; _l1: _t1 = 1 < 2; if (!_t1) goto _l2; _l3: _t2 = 2 < 3; if (!_t2) goto _l4; x = 8; goto _l3; _l4: goto _l1; _l2: return x; }
CFG NODES: 7
CFG EDGES: 8
BACK EDGES: 2
NODES IN LOOPS: 4
Test case: int f() { int x; int _t2; int _t1; _l1: _l21: _l31: _t1 = x < 10; if (!_t1) goto _l2; _t2 = x + 1; x = _t2; goto _l1; _l2: _l22: _l32: _l42: return x; }
CFG NODES: 5
CFG EDGES: 5
BACK EDGES: 1
NODES IN LOOPS: 2
Test case: int f() { int x; int _t2; int _t1; _t1 = x < 10; if (!_t1) goto _l1; x = 1; goto _l2; _l1: x = 2; _l2: return x; }
CFG NODES: 6
CFG EDGES: 6
BACK EDGES: 0
NODES IN LOOPS: 0