forked from AbleOS/holey-bytes
tests are now autogenerated from the readme, this makes test names DRY
I want to reduce friction of adding new tests as much as possible Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
parent
5c8f7c9c79
commit
51bfbdf7ae
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -12,3 +12,4 @@ db.sqlite-journal
|
|||
/depell/src/static-pages/*.html
|
||||
#**/*-sv.rs
|
||||
/bytecode/src/instrs.rs
|
||||
/lang/src/testcases.rs
|
||||
|
|
|
@ -736,28 +736,6 @@ main := fn(): uint {
|
|||
|
||||
### Incomplete Examples
|
||||
|
||||
#### string_array
|
||||
```hb
|
||||
|
||||
main := fn(): uint {
|
||||
strings := (^u8).["abcdefshijklmnop\0".ptr, "abcdefghijklnnop\0".ptr, "abcdefshijklmnop\0".ptr, "abcdefghijklmnop\0".ptr, "abcdefghijflmnop\0".ptr, "dbcdefghijklmnop\0".ptr, "abcdefghijklmnop\0".ptr]
|
||||
return *strings[0]
|
||||
}
|
||||
```
|
||||
|
||||
#### comptime_pointers
|
||||
```hb
|
||||
main := fn(): uint {
|
||||
$integer := 7
|
||||
modify(&integer)
|
||||
return integer
|
||||
}
|
||||
|
||||
modify := fn($num: ^uint): void {
|
||||
$: *num = 0
|
||||
}
|
||||
```
|
||||
|
||||
#### fb_driver
|
||||
```hb
|
||||
arm_fb_ptr := fn(): uint return 100
|
||||
|
@ -798,6 +776,30 @@ main := fn(): uint {
|
|||
|
||||
### Purely Testing Examples
|
||||
|
||||
#### string_array
|
||||
```hb
|
||||
|
||||
main := fn(): uint {
|
||||
strings := (^u8).["abcdefshijklmnop\0".ptr, "abcdefghijklnnop\0".ptr, "abcdefshijklmnop\0".ptr, "abcdefghijklmnop\0".ptr, "abcdefghijflmnop\0".ptr, "dbcdefghijklmnop\0".ptr, "abcdefghijklmnop\0".ptr]
|
||||
return *strings[0]
|
||||
}
|
||||
```
|
||||
|
||||
#### generic_function_in_struct
|
||||
```hb
|
||||
A := struct {
|
||||
a: uint,
|
||||
b := fn(self: ^Self, $T: type, c: T): T {
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
main := fn(): uint {
|
||||
a := A.(100)
|
||||
return a.b(uint, 100)
|
||||
}
|
||||
```
|
||||
|
||||
#### len_never_goes_down
|
||||
```hb
|
||||
chars := fn(iter: []u8): struct {
|
||||
|
|
35
lang/build.rs
Normal file
35
lang/build.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use std::{fmt::Write, iter};
|
||||
|
||||
fn main() {
|
||||
const TEST_FILE: &str = "src/testcases.rs";
|
||||
const INPUT: &str = include_str!("./README.md");
|
||||
|
||||
let mut out = String::new();
|
||||
for (name, code) in block_iter(INPUT) {
|
||||
let name = name.replace(' ', "_");
|
||||
_ = writeln!(
|
||||
out,
|
||||
"#[test] fn {name}() {{ run_codegen_test(\"{name}\", r##\"{code}\"##) }}"
|
||||
);
|
||||
}
|
||||
|
||||
std::fs::write(TEST_FILE, out).unwrap();
|
||||
}
|
||||
|
||||
fn block_iter(mut input: &str) -> impl Iterator<Item = (&str, &str)> {
|
||||
const CASE_PREFIX: &str = "#### ";
|
||||
const CASE_SUFFIX: &str = "\n```hb";
|
||||
|
||||
iter::from_fn(move || loop {
|
||||
let pos = input.find(CASE_PREFIX)?;
|
||||
input = unsafe { input.get_unchecked(pos + CASE_PREFIX.len()..) };
|
||||
let Some((test_name, rest)) = input.split_once(CASE_SUFFIX) else { continue };
|
||||
if !test_name.chars().all(|c| c.is_alphanumeric() || c == '_') {
|
||||
continue;
|
||||
}
|
||||
input = rest;
|
||||
let (body, rest) = input.split_once("```").unwrap_or((input, ""));
|
||||
input = rest;
|
||||
break Some((test_name, body));
|
||||
})
|
||||
}
|
|
@ -401,10 +401,10 @@ impl Default for FnvHasher {
|
|||
|
||||
#[cfg(test)]
|
||||
pub fn run_test(
|
||||
name: &'static str,
|
||||
ident: &'static str,
|
||||
input: &'static str,
|
||||
test: fn(&'static str, &'static str, &mut alloc::string::String),
|
||||
name: &str,
|
||||
ident: &str,
|
||||
input: &str,
|
||||
test: fn(&str, &str, &mut alloc::string::String),
|
||||
) {
|
||||
use std::{
|
||||
io::Write,
|
||||
|
@ -483,31 +483,6 @@ fn test_parse_files(
|
|||
std::{borrow::ToOwned, string::ToString},
|
||||
};
|
||||
|
||||
fn find_block<'a>(mut input: &'a str, test_name: &str) -> &'a str {
|
||||
const CASE_PREFIX: &str = "#### ";
|
||||
const CASE_SUFFIX: &str = "\n```hb";
|
||||
loop {
|
||||
let Some(pos) = input.find(CASE_PREFIX) else {
|
||||
unreachable!("test {test_name} not found");
|
||||
};
|
||||
|
||||
input = unsafe { input.get_unchecked(pos + CASE_PREFIX.len()..) };
|
||||
if !input.starts_with(test_name) {
|
||||
continue;
|
||||
}
|
||||
input = unsafe { input.get_unchecked(test_name.len()..) };
|
||||
if !input.starts_with(CASE_SUFFIX) {
|
||||
continue;
|
||||
}
|
||||
input = unsafe { input.get_unchecked(CASE_SUFFIX.len()..) };
|
||||
|
||||
let end = input.find("```").unwrap_or(input.len());
|
||||
break unsafe { input.get_unchecked(..end) };
|
||||
}
|
||||
}
|
||||
|
||||
let input = find_block(input, ident);
|
||||
|
||||
let mut module_map = Vec::new();
|
||||
let mut embed_map = Vec::new();
|
||||
let mut last_start = 0;
|
||||
|
|
112
lang/src/son.rs
112
lang/src/son.rs
|
@ -4389,7 +4389,7 @@ mod tests {
|
|||
core::fmt::Write,
|
||||
};
|
||||
|
||||
fn generate(ident: &'static str, input: &'static str, output: &mut String) {
|
||||
fn generate(ident: &str, input: &str, output: &mut String) {
|
||||
_ = log::set_logger(&crate::fs::Logger);
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
//log::set_max_level(log::LevelFilter::Trace);
|
||||
|
@ -4423,111 +4423,9 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
crate::run_tests! { generate:
|
||||
// Tour Examples
|
||||
main_fn;
|
||||
arithmetic;
|
||||
floating_point_arithmetic;
|
||||
functions;
|
||||
comments;
|
||||
if_statements;
|
||||
variables;
|
||||
hex_octal_binary_literals;
|
||||
loops;
|
||||
pointers;
|
||||
structs;
|
||||
tuples;
|
||||
struct_scopes;
|
||||
enums;
|
||||
unions;
|
||||
nullable_types;
|
||||
struct_operators;
|
||||
global_variables;
|
||||
constants;
|
||||
directives;
|
||||
c_strings;
|
||||
struct_patterns;
|
||||
arrays;
|
||||
slices;
|
||||
inline;
|
||||
idk;
|
||||
generic_functions;
|
||||
die;
|
||||
defer;
|
||||
unrolled_loops;
|
||||
|
||||
// Incomplete Examples;
|
||||
//comptime_pointers;
|
||||
generic_types;
|
||||
fb_driver;
|
||||
|
||||
// Purely Testing Examples;
|
||||
len_never_goes_down;
|
||||
slice_to_global_pointer;
|
||||
subsclice_bug;
|
||||
string_array;
|
||||
proper_ident_propagation;
|
||||
method_receiver_by_value;
|
||||
comparing_floating_points;
|
||||
pointer_comparison;
|
||||
different_function_destinations;
|
||||
triggering_store_in_divergent_branch;
|
||||
wrong_dead_code_elimination;
|
||||
memory_swap;
|
||||
very_nested_loops;
|
||||
generic_type_mishap;
|
||||
storing_into_nullable_struct;
|
||||
scheduling_block_did_dirty;
|
||||
null_check_returning_small_global;
|
||||
null_check_in_the_loop;
|
||||
stack_provenance;
|
||||
advanced_floating_point_arithmetic;
|
||||
nullable_structure;
|
||||
needless_unwrap;
|
||||
inlining_issues;
|
||||
null_check_test;
|
||||
only_break_loop;
|
||||
reading_idk;
|
||||
nonexistent_ident_import;
|
||||
big_array_crash;
|
||||
returning_global_struct;
|
||||
small_struct_bitcast;
|
||||
small_struct_assignment;
|
||||
intcast_store;
|
||||
string_flip;
|
||||
signed_to_unsigned_upcast;
|
||||
wide_ret;
|
||||
comptime_min_reg_leak;
|
||||
different_types;
|
||||
struct_return_from_module_function;
|
||||
sort_something_viredly;
|
||||
struct_in_register;
|
||||
comptime_function_from_another_file;
|
||||
inline_test;
|
||||
inlined_generic_functions;
|
||||
some_generic_code;
|
||||
integer_inference_issues;
|
||||
writing_into_string;
|
||||
request_page;
|
||||
tests_ptr_to_ptr_copy;
|
||||
global_variable_wiredness;
|
||||
inline_return_stack;
|
||||
|
||||
// Just Testing Optimizations;
|
||||
elide_stack_offsets_for_parameters_correctly;
|
||||
const_folding_with_arg;
|
||||
branch_assignments;
|
||||
exhaustive_loop_testing;
|
||||
pointer_opts;
|
||||
conditional_stores;
|
||||
loop_stores;
|
||||
dead_code_in_loop;
|
||||
infinite_loop_after_peephole;
|
||||
aliasing_overoptimization;
|
||||
global_aliasing_overptimization;
|
||||
overwrite_aliasing_overoptimization;
|
||||
more_if_opts;
|
||||
optional_from_eca;
|
||||
returning_optional_issues;
|
||||
fn run_codegen_test(name: &str, input: &str) {
|
||||
crate::run_test(&format!("{}::{}", module_path!(), name), name, input, generate);
|
||||
}
|
||||
|
||||
include!("./testcases.rs");
|
||||
}
|
||||
|
|
0
lang/tests/son_tests_generic_function_in_struct.txt
Normal file
0
lang/tests/son_tests_generic_function_in_struct.txt
Normal file
Loading…
Reference in a new issue