mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-14 22:38:46 +00:00
Various quality-of-life improvements (ideas from @33577 )
* Very basic `hello_main.c` * Big starting hint to `write_c` * Better error messages on failed test * TODO: also improve it for asmgen, but not sure how to do it in a good way
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
int sum(int len, int *p) {
|
int sum(int len, int* p) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
result += p[i];
|
result += p[i];
|
||||||
@@ -10,7 +10,7 @@ int sum(int len, int *p) {
|
|||||||
int main() {
|
int main() {
|
||||||
int a[5];
|
int a[5];
|
||||||
int len = 5;
|
int len = 5;
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
a[i] = i;
|
a[i] = i;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
int* foo(int a[10]){
|
int* foo(int a[10]) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int a[10];
|
int a[10];
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
(foo(a))[i] = i;
|
(foo(a))[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return a[5] == 5;
|
return a[5] == 5;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
int main() {
|
int main() {
|
||||||
int a[10];
|
int a[10];
|
||||||
int *p = a;
|
int* p = a;
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
*(p++) = i;
|
*(p++) = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return a[5] == 5;
|
return a[5] == 5;
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ int main() {
|
|||||||
int a[5] = {init, 2, 3, 4, -5};
|
int a[5] = {init, 2, 3, 4, -5};
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
|
|
||||||
for(int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
sum += a[i];
|
sum += a[i];
|
||||||
sum += g_a[i];
|
sum += g_a[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
int bar(int x, int y, int z){
|
int bar(int x, int y, int z) {
|
||||||
int arith_mean = (x + y + z) / 3;
|
int arith_mean = (x + y + z) / 3;
|
||||||
int ugly_mean = (((x + y) / 2) * 2 + z) / 3;
|
int ugly_mean = (((x + y) / 2) * 2 + z) / 3;
|
||||||
if (x == y) { return y; }
|
if (x == y) {
|
||||||
else { return z; }
|
return y;
|
||||||
|
} else {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ int main() {
|
|||||||
unsigned char a = -1;
|
unsigned char a = -1;
|
||||||
unsigned char b = -128;
|
unsigned char b = -128;
|
||||||
unsigned char c = 127;
|
unsigned char c = 127;
|
||||||
unsigned char d = b | a; // -1 (255)
|
unsigned char d = b | a; // -1 (255)
|
||||||
unsigned char e = b & a; // -128 (128)
|
unsigned char e = b & a; // -128 (128)
|
||||||
unsigned char f = b & c; // 0 (0)
|
unsigned char f = b & c; // 0 (0)
|
||||||
unsigned char g = b | c; // -1 (255)
|
unsigned char g = b | c; // -1 (255)
|
||||||
unsigned char h = -1 ^ -1; // 0 (0)
|
unsigned char h = -1 ^ -1; // 0 (0)
|
||||||
unsigned char i = -1 ^ 0; // -1 (255)
|
unsigned char i = -1 ^ 0; // -1 (255)
|
||||||
|
|
||||||
return d == 255 && e == 128 && f == 0 && g == 255 && h == 0 && i == 255;
|
return d == 255 && e == 128 && f == 0 && g == 255 && h == 0 && i == 255;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
int int_greater_than(int i, unsigned int j) {
|
int int_greater_than(int i, unsigned int j) {
|
||||||
if (i > j) return 1;
|
if (i > j)
|
||||||
else return 0;
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int char_greater_than(char i, unsigned char j) {
|
int char_greater_than(char i, unsigned char j) {
|
||||||
if (i > j) return 1;
|
if (i > j)
|
||||||
else return 0;
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
int y = 2;
|
int y = 2;
|
||||||
int x = (y += 2, 2, y + 3);
|
int x = (y += 2, 2, y + 3);
|
||||||
return x == 7;
|
return x == 7;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
int nonce = 1; // For random input
|
int nonce = 1; // For random input
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int a = ~nonce;
|
int a = ~nonce;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
int y = 1;
|
int y = 1;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
return ((x == y) ? 2 : 5) == 5;
|
return ((x == y) ? 2 : 5) == 5;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
int nonce = 1; // For random input
|
int nonce = 1; // For random input
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int i;
|
int i;
|
||||||
@@ -8,8 +8,11 @@ int main() {
|
|||||||
int loop_num = nonce % 100;
|
int loop_num = nonce % 100;
|
||||||
|
|
||||||
for (i = 0; i < loop_num; ((i % 2) ? (i += 2) : ++i)) {
|
for (i = 0; i < loop_num; ((i % 2) ? (i += 2) : ++i)) {
|
||||||
if (i % 2) { p += q; }
|
if (i % 2) {
|
||||||
else { p += r; }
|
p += q;
|
||||||
|
} else {
|
||||||
|
p += r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
int (fibonacci)(int n) {
|
int fibonacci(int n) {
|
||||||
if (n < 2) {
|
if (n < 2) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
int nonce = 1; // For random input
|
int nonce = 1; // For random input
|
||||||
|
|
||||||
int fibonacci(int n) {
|
int fibonacci(int n) {
|
||||||
if (n < 2) {
|
if (n < 2) {
|
||||||
|
|||||||
@@ -14,22 +14,22 @@ double average(int len, int a[10]) {
|
|||||||
int sum = 0;
|
int sum = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
sum += a[i];
|
sum += a[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (double) sum / len;
|
return (double)sum / len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int a[10];
|
int a[10];
|
||||||
int len = 10;
|
int len = 10;
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
a[i] = i;
|
a[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
float avg = average(len, a);
|
float avg = average(len, a);
|
||||||
|
|
||||||
return is_close(avg, 4.5, 1e-09, 0.1);
|
return is_close(avg, 4.5, 1e-09, 0.1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
int foo(int x, int y, int z){
|
int foo(int x, int y, int z) {
|
||||||
if (x == y) { return y; }
|
if (x == y) {
|
||||||
else { return z; }
|
return y;
|
||||||
|
} else {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ int main() {
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
int nonce = 1; // For random input
|
int nonce = 1; // For random input
|
||||||
int g = 10;
|
int g = 10;
|
||||||
|
|
||||||
int foo(int, int k);
|
int foo(int, int k);
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int i = g;
|
int i = g;
|
||||||
|
|
||||||
return foo(i, i);
|
return foo(i, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
int foo(int i, int j, int k) {
|
int foo(int i, int j, int k) {
|
||||||
return i + j + k;
|
return i + j + k;
|
||||||
}
|
}
|
||||||
|
|
||||||
int (* foo2())(int, int, int){
|
int (*foo2())(int, int, int) {
|
||||||
return foo;
|
return foo;
|
||||||
}
|
}
|
||||||
|
|
||||||
int (* (* foo3())())(int, int, int){
|
int (*(*foo3())())(int, int, int) {
|
||||||
return foo2;
|
return foo2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
return foo3()()(2, 2, 2) == 6;
|
return foo3()()(2, 2, 2) == 6;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
int foo() {
|
int foo() {
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
|
|
||||||
for(int i = 0; ;) {
|
for (int i = 0;;) {
|
||||||
if(i == 5) break;
|
if (i == 5)
|
||||||
if(i == 3) {
|
break;
|
||||||
|
if (i == 3) {
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ int gcd(int a, int b) {
|
|||||||
a = (a > 0) ? a : -a;
|
a = (a > 0) ? a : -a;
|
||||||
b = (b > 0) ? b : -b;
|
b = (b > 0) ? b : -b;
|
||||||
|
|
||||||
while(a != b) {
|
while (a != b) {
|
||||||
if(a > b) { a -= b; }
|
if (a > b) {
|
||||||
else { b -= a; }
|
a -= b;
|
||||||
|
} else {
|
||||||
|
b -= a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
|
|||||||
3
examples/c/hello_main.c
Normal file
3
examples/c/hello_main.c
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
int main() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
int main() {
|
int main() {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
do {
|
do {
|
||||||
result = i;
|
result = i;
|
||||||
i++;
|
i++;
|
||||||
} while (i < 4);
|
} while (i < 4);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
int foo(int x, int y, int z){
|
int foo(int x, int y, int z) {
|
||||||
if (!(x == y)) { return y; }
|
if (!(x == y)) {
|
||||||
else { return z; }
|
return y;
|
||||||
|
} else {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
int* foo(int *a){
|
int* foo(int* a) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(){
|
int main() {
|
||||||
int a = 1;
|
int a = 1;
|
||||||
int *p = &a;
|
int* p = &a;
|
||||||
int **p2 = &*&p;
|
int** p2 = &*&p;
|
||||||
int *p3 = *&p;
|
int* p3 = *&p;
|
||||||
|
|
||||||
*&*foo(*p2) += 1;
|
*&*foo(*p2) += 1;
|
||||||
*foo(p3) += 1;
|
*foo(p3) += 1;
|
||||||
|
|
||||||
return a == 3;
|
return a == 3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
int nonce = 1; // For random input
|
int nonce = 1; // For random input
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
int x = nonce;
|
int x = nonce;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for (i = 0; i < 11; ++i) {
|
for (i = 0; i < 11; ++i) {
|
||||||
sum += i;
|
sum += i;
|
||||||
}
|
}
|
||||||
return sum == 55;
|
return sum == 55;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
int (fibonacci)(int n) {
|
int fibonacci(int n) {
|
||||||
if (n < 2) {
|
if (n < 2) {
|
||||||
n += 2;
|
n += 2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
int a = 3;
|
int a = 3;
|
||||||
int b = sizeof(!(a++));
|
int b = sizeof(!(a++));
|
||||||
return a + b;
|
return a + b;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
char a;
|
char a;
|
||||||
struct {
|
struct {
|
||||||
int b[4][5];
|
int b[4][5];
|
||||||
};
|
};
|
||||||
double c;
|
double c;
|
||||||
} Temp;
|
} Temp;
|
||||||
|
|
||||||
void init(int row, int col, int arr[4][5]) {
|
void init(int row, int col, int arr[4][5]) {
|
||||||
@@ -21,6 +21,6 @@ int main() {
|
|||||||
|
|
||||||
Temp temp2;
|
Temp temp2;
|
||||||
temp2 = temp;
|
temp2 = temp;
|
||||||
|
|
||||||
return temp2.b[2][3] == 6;
|
return temp2.b[2][3] == 6;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
char a;
|
char a;
|
||||||
struct {
|
struct {
|
||||||
int b[4];
|
int b[4];
|
||||||
};
|
};
|
||||||
long c;
|
long c;
|
||||||
} Temp;
|
} Temp;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
const Temp temp = {1, {{2, 3, 4, 5}}, 6};
|
const Temp temp = {1, {{2, 3, 4, 5}}, 6};
|
||||||
|
|
||||||
Temp temp2;
|
Temp temp2;
|
||||||
temp2 = temp;
|
temp2 = temp;
|
||||||
|
|
||||||
int sum = temp2.a + temp2.b[2] + temp2.c;
|
int sum = temp2.a + temp2.b[2] + temp2.c;
|
||||||
|
|
||||||
return sum == 11;
|
return sum == 11;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,16 @@
|
|||||||
int nonce = 1; // For random input
|
int nonce = 1; // For random input
|
||||||
|
|
||||||
struct Foo
|
struct Foo {
|
||||||
{
|
|
||||||
int x;
|
int x;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Foo f()
|
struct Foo f() {
|
||||||
{
|
|
||||||
struct Foo x;
|
struct Foo x;
|
||||||
x.x = nonce;
|
x.x = nonce;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
int x = f().x;
|
int x = f().x;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
int main() {
|
int main() {
|
||||||
int a = 1;
|
int a = 1;
|
||||||
int b = 2;
|
int b = 2;
|
||||||
do {
|
do {
|
||||||
int t = a;
|
int t = a;
|
||||||
a = b;
|
a = b;
|
||||||
b = t;
|
b = t;
|
||||||
} while (b == 1);
|
} while (b == 1);
|
||||||
return a * 10 + b;
|
return a * 10 + b;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
int main() {
|
int main() {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
while (i < 10) {
|
while (i < 10) {
|
||||||
i++;
|
i++;
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case (1): {
|
case (1): {
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
c++;
|
||||||
}
|
}
|
||||||
c++;
|
return c;
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,33 @@
|
|||||||
struct color { int number; char name; };
|
struct color {
|
||||||
|
int number;
|
||||||
|
char name;
|
||||||
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
temp += sizeof(unsigned char);
|
temp += sizeof(unsigned char);
|
||||||
temp += _Alignof(unsigned char);
|
temp += _Alignof(unsigned char);
|
||||||
|
|
||||||
struct color c = {1, 2};
|
struct color c = {1, 2};
|
||||||
temp += c.name;
|
temp += c.name;
|
||||||
struct color *cp = &c;
|
struct color* cp = &c;
|
||||||
temp += cp->name;
|
temp += cp->name;
|
||||||
|
|
||||||
for(int i = 0, j = 0; i < 10; ++i) {
|
for (int i = 0, j = 0; i < 10; ++i) {
|
||||||
if ( i == 2 && j == 0) break;
|
if (i == 2 && j == 0)
|
||||||
temp += i;
|
break;
|
||||||
}
|
temp += i;
|
||||||
|
|
||||||
switch(temp) {
|
|
||||||
case 1: {
|
|
||||||
temp = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return temp;
|
switch (temp) {
|
||||||
|
case 1: {
|
||||||
|
temp = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
char temp = 0x00L;
|
char temp = 0x00L;
|
||||||
|
|
||||||
int main(){
|
int main() {
|
||||||
return (temp = 0xEF36L) >= (2L);
|
return (temp = 0xEF36L) >= (2L);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
int nonce = 1; // For random input
|
int nonce = 1; // For random input
|
||||||
|
|
||||||
int foo() {
|
int foo() {
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int continue_num = nonce % 98;
|
int continue_num = nonce % 98;
|
||||||
|
|
||||||
while(i < 100) {
|
while (i < 100) {
|
||||||
if(i == continue_num) {
|
if (i == continue_num) {
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sum += i;
|
sum += i;
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if(i == continue_num + 2) break;
|
if (i == continue_num + 2)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
|
|||||||
13
examples/ir0/hello_main.ir
Normal file
13
examples/ir0/hello_main.ir
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
fun i32 @main () {
|
||||||
|
init:
|
||||||
|
bid: b0
|
||||||
|
allocations:
|
||||||
|
|
||||||
|
|
||||||
|
block b0:
|
||||||
|
ret 1:i32
|
||||||
|
|
||||||
|
block b1:
|
||||||
|
ret 1:i32
|
||||||
|
}
|
||||||
10
examples/ir1/hello_main.ir
Normal file
10
examples/ir1/hello_main.ir
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
fun i32 @main () {
|
||||||
|
init:
|
||||||
|
bid: b0
|
||||||
|
allocations:
|
||||||
|
|
||||||
|
|
||||||
|
block b0:
|
||||||
|
ret 0:i32
|
||||||
|
}
|
||||||
10
examples/ir2/hello_main.ir
Normal file
10
examples/ir2/hello_main.ir
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
fun i32 @main () {
|
||||||
|
init:
|
||||||
|
bid: b0
|
||||||
|
allocations:
|
||||||
|
|
||||||
|
|
||||||
|
block b0:
|
||||||
|
ret 1:i32
|
||||||
|
}
|
||||||
10
examples/ir3/hello_main.ir
Normal file
10
examples/ir3/hello_main.ir
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
fun i32 @main () {
|
||||||
|
init:
|
||||||
|
bid: b0
|
||||||
|
allocations:
|
||||||
|
|
||||||
|
|
||||||
|
block b0:
|
||||||
|
ret 1:i32
|
||||||
|
}
|
||||||
10
examples/ir4/hello_main.ir
Normal file
10
examples/ir4/hello_main.ir
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
fun i32 @main () {
|
||||||
|
init:
|
||||||
|
bid: b0
|
||||||
|
allocations:
|
||||||
|
|
||||||
|
|
||||||
|
block b0:
|
||||||
|
ret 1:i32
|
||||||
|
}
|
||||||
10
examples/opt/hello_main.ir
Normal file
10
examples/opt/hello_main.ir
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
fun i32 @main () {
|
||||||
|
init:
|
||||||
|
bid: b0
|
||||||
|
allocations:
|
||||||
|
|
||||||
|
|
||||||
|
block b0:
|
||||||
|
ret 1:i32
|
||||||
|
}
|
||||||
@@ -522,13 +522,3 @@ impl IsEquiv for AlignOf {
|
|||||||
self.0.is_equiv(&other.0)
|
self.0.is_equiv(&other.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn assert_ast_equiv(lhs: &TranslationUnit, rhs: &TranslationUnit) {
|
|
||||||
if !lhs.is_equiv(rhs) {
|
|
||||||
panic!(
|
|
||||||
r#"assertion failed: `(left.is_equiv(right))`
|
|
||||||
left: `{lhs:?}`,
|
|
||||||
right: `{rhs:?}`"#
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,5 +2,4 @@ mod ast_equiv;
|
|||||||
mod parse;
|
mod parse;
|
||||||
mod write_c;
|
mod write_c;
|
||||||
|
|
||||||
pub(crate) use ast_equiv::assert_ast_equiv;
|
|
||||||
pub use parse::Parse;
|
pub use parse::Parse;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ impl<T: WriteString> WriteString for Node<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WriteLine for TranslationUnit {
|
impl WriteLine for TranslationUnit {
|
||||||
|
/// VERY BIG HINT: You should start by understanding the [`writeln!`](https://doc.rust-lang.org/std/macro.writeln.html) macro.
|
||||||
fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> {
|
fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ pub struct Block {
|
|||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum Instruction {
|
pub enum Instruction {
|
||||||
Nop,
|
Nop,
|
||||||
|
// TODO: Explain what this is, why this is needed.
|
||||||
Value {
|
Value {
|
||||||
value: Operand,
|
value: Operand,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -67,4 +67,4 @@ pub use opt::{
|
|||||||
};
|
};
|
||||||
pub use tests::*;
|
pub use tests::*;
|
||||||
pub use utils::*;
|
pub use utils::*;
|
||||||
pub(crate) use write_base::write;
|
pub use write_base::write;
|
||||||
|
|||||||
28
src/tests.rs
28
src/tests.rs
@@ -71,12 +71,11 @@ fn modify_asm(unit: &mut asm::Asm, rand_num: i32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rust sets an exit code of 101 when the process panicked.
|
// 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.
|
// Set exit code of 102 after 101 to denote that the test skipped.
|
||||||
const SKIP_TEST: i32 = 102;
|
const SKIP_TEST: i32 = 102;
|
||||||
|
|
||||||
/// Tests write_c.
|
/// Tests write_c.
|
||||||
pub fn test_write_c(path: &Path) {
|
pub fn test_write_c(path: &Path) {
|
||||||
// Check if the file has .c extension
|
|
||||||
assert_eq!(path.extension(), Some(std::ffi::OsStr::new("c")));
|
assert_eq!(path.extension(), Some(std::ffi::OsStr::new("c")));
|
||||||
let unit = Parse
|
let unit = Parse
|
||||||
.translate(&path)
|
.translate(&path)
|
||||||
@@ -91,9 +90,17 @@ pub fn test_write_c(path: &Path) {
|
|||||||
let new_unit = Parse
|
let new_unit = Parse
|
||||||
.translate(&temp_file_path.as_path())
|
.translate(&temp_file_path.as_path())
|
||||||
.expect("parse failed while parsing the output from implemented printer");
|
.expect("parse failed while parsing the output from implemented printer");
|
||||||
drop(temp_file);
|
|
||||||
c::assert_ast_equiv(&unit, &new_unit);
|
if !unit.is_equiv(&new_unit) {
|
||||||
temp_dir.close().expect("temp dir deletion failed");
|
let mut buf = String::new();
|
||||||
|
// FIXME: For some reason we cannot reuse `temp_file`.
|
||||||
|
let _ = File::open(&temp_file_path)
|
||||||
|
.unwrap()
|
||||||
|
.read_to_string(&mut buf)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
panic!("[write-c] Failed to correctly write {path:?}.\n\n[incorrect result]\n\n{buf}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests irgen.
|
/// Tests irgen.
|
||||||
@@ -171,12 +178,10 @@ pub fn test_irgen(path: &Path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let status = some_or_exit!(status.code(), SKIP_TEST);
|
let status = some_or_exit!(status.code(), SKIP_TEST);
|
||||||
drop(temp_file);
|
|
||||||
temp_dir.close().expect("temp dir deletion failed");
|
|
||||||
|
|
||||||
// Interpret resolved ir
|
// Interpret resolved ir
|
||||||
let args = Vec::new();
|
let args = Vec::new();
|
||||||
let result = ir::interp(&ir, args).unwrap_or_else(|interp_error| panic!("{}", interp_error));
|
let result = ir::interp(&ir, args).unwrap_or_else(|interp_error| panic!("{interp_error}"));
|
||||||
// We only allow a main function whose return type is `int`
|
// We only allow a main function whose return type is `int`
|
||||||
let (value, width, is_signed) = result.get_int().expect("non-integer value occurs");
|
let (value, width, is_signed) = result.get_int().expect("non-integer value occurs");
|
||||||
assert_eq!(width, 32);
|
assert_eq!(width, 32);
|
||||||
@@ -187,7 +192,12 @@ pub fn test_irgen(path: &Path) {
|
|||||||
// typecasted to `unsigned char`. However, during `creduce` to reduce the code, typecasting may
|
// typecasted to `unsigned char`. However, during `creduce` to reduce the code, typecasting may
|
||||||
// be nullified. So, we truncate the result value to byte size one more time here.
|
// be nullified. So, we truncate the result value to byte size one more time here.
|
||||||
println!("clang (expected): {}, kecc: {}", status as u8, value as u8);
|
println!("clang (expected): {}, kecc: {}", status as u8, value as u8);
|
||||||
assert_eq!(status as u8, value as u8);
|
if status as u8 != value as u8 {
|
||||||
|
stderr().lock().write_fmt(format_args!(
|
||||||
|
"[irgen] Failed to correctly generate {path:?}.\n\n [incorrect ir]"
|
||||||
|
));
|
||||||
|
write(&ir, &mut stderr()).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests irparse.
|
/// Tests irparse.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ pub(crate) fn write_indent(indent: usize, write: &mut dyn Write) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A trait for writing a type to a `Write` stream with a new line.
|
/// A trait for writing a type to a `Write` stream with a new line.
|
||||||
pub(crate) trait WriteLine {
|
pub trait WriteLine {
|
||||||
/// Write `self` to `write`, starting at `indent` number of double spaces, with a newline at the
|
/// Write `self` to `write`, starting at `indent` number of double spaces, with a newline at the
|
||||||
/// end.
|
/// end.
|
||||||
fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()>;
|
fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()>;
|
||||||
@@ -44,6 +44,6 @@ impl<T: WriteString> WriteString for Option<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write `t` to `write`.
|
/// Write `t` to `write`.
|
||||||
pub(crate) fn write<T: WriteLine>(t: &T, write: &mut dyn Write) -> Result<()> {
|
pub fn write<T: WriteLine>(t: &T, write: &mut dyn Write) -> Result<()> {
|
||||||
t.write_line(0, write)
|
t.write_line(0, write)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ where
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("[testing {path:?}]");
|
|
||||||
f(&path);
|
f(&path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,6 +43,8 @@ fn test_opt_between_dirs<O: Optimize<ir::TranslationUnit>>(from: &Path, to: &Pat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const HELLO_MAIN: &str = "hello_main";
|
||||||
|
|
||||||
const IRGEN_SMALL_TEST_IGNORE_LIST: [&str; 12] = [
|
const IRGEN_SMALL_TEST_IGNORE_LIST: [&str; 12] = [
|
||||||
"examples/c/array.c",
|
"examples/c/array.c",
|
||||||
"examples/c/array2.c",
|
"examples/c/array2.c",
|
||||||
@@ -84,14 +85,24 @@ const ASMGEN_SMALL_TEST_IGNORE_LIST: [&str; 12] = [
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_examples_write_c() {
|
fn test_examples_write_c() {
|
||||||
test_dir(Path::new("examples/c"), OsStr::new("c"), test_write_c);
|
println!("[testing write_c for \"examples/c/{HELLO_MAIN}.c\"]");
|
||||||
|
test_write_c(Path::new(&format!("examples/c/{HELLO_MAIN}.c")));
|
||||||
|
test_dir(Path::new("examples/c"), OsStr::new("c"), |path| {
|
||||||
|
if !path.to_str().unwrap().contains(HELLO_MAIN) {
|
||||||
|
println!("[testing write_c for {path:?}]");
|
||||||
|
test_write_c(path)
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_examples_irgen_small() {
|
fn test_examples_irgen_small() {
|
||||||
|
println!("[testing irgen for \"examples/c/{HELLO_MAIN}.c\"]");
|
||||||
|
test_irgen(Path::new(&format!("examples/c/{HELLO_MAIN}.c")));
|
||||||
test_dir(Path::new("examples/c"), OsStr::new("c"), |path| {
|
test_dir(Path::new("examples/c"), OsStr::new("c"), |path| {
|
||||||
let path_str = &path.to_str().expect("`path` must be transformed to `&str`");
|
let path_str = &path.to_str().expect("`path` must be transformed to `&str`");
|
||||||
if !IRGEN_SMALL_TEST_IGNORE_LIST.contains(path_str) {
|
if !IRGEN_SMALL_TEST_IGNORE_LIST.contains(path_str) && !path_str.contains(HELLO_MAIN) {
|
||||||
|
println!("[testing irgen for {path:?}]");
|
||||||
test_irgen(path)
|
test_irgen(path)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -101,7 +112,8 @@ fn test_examples_irgen_small() {
|
|||||||
fn test_examples_irgen_large() {
|
fn test_examples_irgen_large() {
|
||||||
test_dir(Path::new("examples/c"), OsStr::new("c"), |path| {
|
test_dir(Path::new("examples/c"), OsStr::new("c"), |path| {
|
||||||
let path_str = &path.to_str().expect("`path` must be transformed to `&str`");
|
let path_str = &path.to_str().expect("`path` must be transformed to `&str`");
|
||||||
if IRGEN_SMALL_TEST_IGNORE_LIST.contains(path_str) {
|
if IRGEN_SMALL_TEST_IGNORE_LIST.contains(path_str) && !path_str.contains(HELLO_MAIN) {
|
||||||
|
println!("[testing irgen for {path:?}]");
|
||||||
test_irgen(path)
|
test_irgen(path)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -201,6 +213,14 @@ fn test_examples_optimize() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_examples_asmgen_small() {
|
fn test_examples_asmgen_small() {
|
||||||
|
for dir in ASMGEN_TEST_DIR_LIST.iter() {
|
||||||
|
test_dir(Path::new(dir), OsStr::new("ir"), |path| {
|
||||||
|
if path.to_str().unwrap().contains(HELLO_MAIN) {
|
||||||
|
println!("[testing asmgen for {path:?}]");
|
||||||
|
test_asmgen(path)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
for dir in ASMGEN_TEST_DIR_LIST.iter() {
|
for dir in ASMGEN_TEST_DIR_LIST.iter() {
|
||||||
test_dir(Path::new(dir), OsStr::new("ir"), |path| {
|
test_dir(Path::new(dir), OsStr::new("ir"), |path| {
|
||||||
let file_name = &path
|
let file_name = &path
|
||||||
@@ -208,7 +228,9 @@ fn test_examples_asmgen_small() {
|
|||||||
.expect("`path` must have a file name")
|
.expect("`path` must have a file name")
|
||||||
.to_str()
|
.to_str()
|
||||||
.expect("must be transformable to `&str`");
|
.expect("must be transformable to `&str`");
|
||||||
if !ASMGEN_SMALL_TEST_IGNORE_LIST.contains(file_name) {
|
if !ASMGEN_SMALL_TEST_IGNORE_LIST.contains(file_name) && !file_name.contains(HELLO_MAIN)
|
||||||
|
{
|
||||||
|
println!("[testing asmgen for {path:?}]");
|
||||||
test_asmgen(path)
|
test_asmgen(path)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -224,7 +246,9 @@ fn test_examples_asmgen_large() {
|
|||||||
.expect("`path` must have a file name")
|
.expect("`path` must have a file name")
|
||||||
.to_str()
|
.to_str()
|
||||||
.expect("must be transformable to `&str`");
|
.expect("must be transformable to `&str`");
|
||||||
if ASMGEN_SMALL_TEST_IGNORE_LIST.contains(file_name) {
|
if ASMGEN_SMALL_TEST_IGNORE_LIST.contains(file_name) && !file_name.contains(HELLO_MAIN)
|
||||||
|
{
|
||||||
|
println!("[testing asmgen for {path:?}]");
|
||||||
test_asmgen(path)
|
test_asmgen(path)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user