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:
Janggun Lee
2025-02-25 00:28:55 +09:00
parent fad9d02fea
commit 72dadc608d
50 changed files with 290 additions and 182 deletions

View File

@@ -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;
} }

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
} }

View File

@@ -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() {

View File

@@ -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;
} }

View File

@@ -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() {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -1,4 +1,4 @@
int (fibonacci)(int n) { int fibonacci(int n) {
if (n < 2) { if (n < 2) {
return n; return n;
} }

View File

@@ -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) {

View File

@@ -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);
} }

View File

@@ -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() {

View File

@@ -4,6 +4,6 @@ int main() {
int i = 0; int i = 0;
int k = 0; int k = 0;
} }
return 1; return 1;
} }

View File

@@ -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);
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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
View File

@@ -0,0 +1,3 @@
int main() {
return 1;
}

View File

@@ -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;
} }

View File

@@ -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() {

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -1,4 +1,4 @@
int (fibonacci)(int n) { int fibonacci(int n) {
if (n < 2) { if (n < 2) {
n += 2; n += 2;
} }

View File

@@ -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;

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -1,5 +1,5 @@
char temp = 0x00L; char temp = 0x00L;
int main(){ int main() {
return (temp = 0xEF36L) >= (2L); return (temp = 0xEF36L) >= (2L);
} }

View File

@@ -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;

View File

@@ -0,0 +1,13 @@
fun i32 @main () {
init:
bid: b0
allocations:
block b0:
ret 1:i32
block b1:
ret 1:i32
}

View File

@@ -0,0 +1,10 @@
fun i32 @main () {
init:
bid: b0
allocations:
block b0:
ret 0:i32
}

View File

@@ -0,0 +1,10 @@
fun i32 @main () {
init:
bid: b0
allocations:
block b0:
ret 1:i32
}

View File

@@ -0,0 +1,10 @@
fun i32 @main () {
init:
bid: b0
allocations:
block b0:
ret 1:i32
}

View File

@@ -0,0 +1,10 @@
fun i32 @main () {
init:
bid: b0
allocations:
block b0:
ret 1:i32
}

View File

@@ -0,0 +1,10 @@
fun i32 @main () {
init:
bid: b0
allocations:
block b0:
ret 1:i32
}

View File

@@ -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:?}`"#
)
}
}

View File

@@ -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;

View File

@@ -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!()
} }

View File

@@ -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,
}, },

View File

@@ -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;

View File

@@ -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.

View File

@@ -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)
} }

View File

@@ -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)
} }
}); });