Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ implicit_hasher = "allow"
match_same_arms = "allow"
similar_names = "allow"
cast_possible_truncation = "allow"
case_sensitive_file_extension_comparisons = "allow"

[workspace.dependencies]
rue-lexer = { path = "crates/rue-lexer", version = "0.6.0" }
Expand Down
2 changes: 1 addition & 1 deletion crates/rue-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ fn test(args: TestArgs) -> Result<()> {
process::exit(1);
}

let tests = tree.tests(&mut ctx, &mut allocator, None, None, &base_path)?;
let tests = tree.tests(&mut ctx, &mut allocator, None, None, &base_path, false)?;

let len = tests.len();

Expand Down
10 changes: 9 additions & 1 deletion crates/rue-compiler/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ pub enum FileTree {
static STD_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/src/std");

impl FileTree {
pub fn empty(ctx: &mut Compiler) -> Result<Self, Error> {
Self::load_std_dir(ctx, "empty".to_string(), &[])
}

pub(crate) fn load_std(ctx: &mut Compiler) -> Result<Self, Error> {
Self::load_std_dir(ctx, "std".to_string(), STD_DIR.entries())
}
Expand Down Expand Up @@ -167,7 +171,6 @@ impl FileTree {
.to_string();

if fs::metadata(path)?.is_file() {
#[allow(clippy::case_sensitive_file_extension_comparisons)]
if !file_name.ends_with(".rue") {
return Ok(None);
}
Expand Down Expand Up @@ -391,6 +394,7 @@ impl FileTree {
path: Option<&SourceKind>,
search_term: Option<&str>,
base_path: &Path,
std: bool,
) -> Result<Vec<CompiledTest>, Error> {
let tests = ctx
.tests()
Expand All @@ -401,6 +405,10 @@ impl FileTree {
return false;
}

if matches!(test.path, SourceKind::Std(_)) && !std {
return false;
}

if let Some(search_term) = search_term {
let Some(name) = &test.name else {
return false;
Expand Down
8 changes: 4 additions & 4 deletions crates/rue-hir/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,12 @@ impl<'d, 'a, 'g> Lowerer<'d, 'a, 'g> {
BinaryOp::BitwiseAnd => self.arena.alloc(Lir::Logand(vec![left, right])),
BinaryOp::BitwiseOr => self.arena.alloc(Lir::Logior(vec![left, right])),
BinaryOp::BitwiseXor => self.arena.alloc(Lir::Logxor(vec![left, right])),
BinaryOp::LeftShift => {
BinaryOp::RightShift => {
let zero = self.arena.alloc(Lir::Atom(vec![]));
let neg = self.arena.alloc(Lir::Sub(vec![zero, right]));
self.arena.alloc(Lir::Ash(left, neg))
}
BinaryOp::RightShift => self.arena.alloc(Lir::Ash(left, right)),
BinaryOp::LeftShift => self.arena.alloc(Lir::Ash(left, right)),
BinaryOp::Gt => self.arena.alloc(Lir::Gt(left, right)),
BinaryOp::Lt => self.arena.alloc(Lir::Gt(right, left)),
BinaryOp::Gte => {
Expand Down Expand Up @@ -657,7 +657,7 @@ impl<'d, 'a, 'g> Lowerer<'d, 'a, 'g> {

let raise = if self.options.debug_symbols {
let error = self.arena.alloc(Lir::Atom(
format!("assertion failed at {}", srcloc.start()).into_bytes(),
format!("assertion failed at {}", srcloc.display(&self.base_path)).into_bytes(),
));
vec![error]
} else {
Expand All @@ -677,7 +677,7 @@ impl<'d, 'a, 'g> Lowerer<'d, 'a, 'g> {
}

let error = self.arena.alloc(Lir::Atom(
format!("raise called at {}", srcloc.start()).into_bytes(),
format!("raise called at {}", srcloc.display(&self.base_path)).into_bytes(),
));
let lir = hir.map(|hir| self.lower_hir(env, hir));

Expand Down
88 changes: 86 additions & 2 deletions crates/rue-tests/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,81 @@ fn run_tests(filter_arg: Option<&str>, base_path: &Path, update: bool) -> Result
walk_dir(&base_path.join("tests"), filter_arg, update, &mut failed)?;
walk_dir(&base_path.join("examples"), filter_arg, update, &mut failed)?;

println!("Running std tests");

let yaml_file = base_path.join("std_tests.yaml");

let mut file: TestFile = if yaml_file.try_exists()? {
serde_yml::from_str(&fs::read_to_string(&yaml_file)?)?
} else {
TestFile::default()
};

let original = file.clone();

let mut allocator = Allocator::new();

let mut ctx = Compiler::new(CompilerOptions::default());
let mut debug_ctx = Compiler::new(CompilerOptions::debug());

let unit = FileTree::empty(&mut ctx)?;
let debug_unit = FileTree::empty(&mut debug_ctx)?;

file.diagnostics = Vec::new();

let mut codegen = true;

for diagnostic in ctx.take_diagnostics() {
file.diagnostics.push(diagnostic.message(base_path));

if diagnostic.kind.severity() == DiagnosticSeverity::Error {
codegen = false;
}
}

let tests = codegen
.then(|| unit.tests(&mut ctx, &mut allocator, None, None, base_path, true))
.transpose()?
.unwrap_or_default();
let debug_tests = codegen
.then(|| debug_unit.tests(&mut debug_ctx, &mut allocator, None, None, base_path, true))
.transpose()?
.unwrap_or_default();

if file.tests.len() > tests.len() {
file.tests.truncate(tests.len());
}

for _ in file.tests.len()..tests.len() {
file.tests.push(TestCase::default());
}

assert_eq!(debug_tests.len(), tests.len());

for (i, test_case) in file.tests.iter_mut().enumerate() {
test_case.name.clone_from(&tests[i].name);

handle_test_case(
&mut allocator,
test_case,
Some(tests[i].ptr),
Some(debug_tests[i].ptr),
)?;
}

if file != original {
if update {
eprintln!("Test failed, updated yaml file");
} else {
eprintln!("Test failed, moving on");
}
failed = true;
}

if update {
fs::write(yaml_file, serde_yml::to_string(&file)?)?;
}

Ok(failed)
}

Expand Down Expand Up @@ -224,11 +299,20 @@ fn handle_test_file(
.flatten();

let tests = codegen
.then(|| unit.tests(&mut ctx, &mut allocator, None, None, &base_path))
.then(|| unit.tests(&mut ctx, &mut allocator, None, None, &base_path, false))
.transpose()?
.unwrap_or_default();
let debug_tests = codegen
.then(|| debug_unit.tests(&mut debug_ctx, &mut allocator, None, None, &base_path))
.then(|| {
debug_unit.tests(
&mut debug_ctx,
&mut allocator,
None,
None,
&base_path,
false,
)
})
.transpose()?
.unwrap_or_default();

Expand Down
2 changes: 1 addition & 1 deletion examples/factorial.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ total_cost: 1008876
tests:
- name: tests
program: (a (q 2 (i (= (a 2 (c 2 (q . -1))) (q . 1)) (q 2 (i (= (a 2 (c 2 ())) (q . 1)) (q 2 (i (= (a 2 (c 2 (q . 1))) (q . 1)) (q 2 (i (= (a 2 (c 2 (q . 2))) (q . 2)) (q 2 (i (= (a 2 (c 2 (q . 3))) (q . 6)) (q 2 (i (= (a 2 (c 2 (q . 4))) (q . 24)) (q 2 (i (= (a 2 (c 2 (q . 5))) (q . 120)) (q) (q 8)) 1) (q 8)) 1) (q 8)) 1) (q 8)) 1) (q 8)) 1) (q 8)) 1) (q 8)) 1) (c (q 2 (i (> 3 (q . 1)) (q 18 3 (a 2 (c 2 (- 3 (q . 1))))) (q 1 . 1)) 1) ()))
debug_program: (a (q 2 (i (= (a 2 (c 2 (- () (q . 1)))) (q . 1)) (q 2 (i (= (a 2 (c 2 ())) (q . 1)) (q 2 (i (= (a 2 (c 2 (q . 1))) (q . 1)) (q 2 (i (= (a 2 (c 2 (q . 2))) (q . 2)) (q 2 (i (= (a 2 (c 2 (q . 3))) (q . 6)) (q 2 (i (= (a 2 (c 2 (q . 4))) (q . 24)) (q 2 (i (= (a 2 (c 2 (q . 5))) (q . 120)) (q) (q 8 (q . "assertion failed at 20:5"))) 1) (q 8 (q . "assertion failed at 19:5"))) 1) (q 8 (q . "assertion failed at 18:5"))) 1) (q 8 (q . "assertion failed at 17:5"))) 1) (q 8 (q . "assertion failed at 16:5"))) 1) (q 8 (q . "assertion failed at 15:5"))) 1) (q 8 (q . "assertion failed at 14:5"))) 1) (c (q 2 (i (> 3 (q . 1)) (q 18 3 (a 2 (c 2 (- 3 (q . 1))))) (q 1 . 1)) 1) ()))
debug_program: (a (q 2 (i (= (a 2 (c 2 (- () (q . 1)))) (q . 1)) (q 2 (i (= (a 2 (c 2 ())) (q . 1)) (q 2 (i (= (a 2 (c 2 (q . 1))) (q . 1)) (q 2 (i (= (a 2 (c 2 (q . 2))) (q . 2)) (q 2 (i (= (a 2 (c 2 (q . 3))) (q . 6)) (q 2 (i (= (a 2 (c 2 (q . 4))) (q . 24)) (q 2 (i (= (a 2 (c 2 (q . 5))) (q . 120)) (q) (q 8 (q . "assertion failed at factorial.rue:20:5"))) 1) (q 8 (q . "assertion failed at factorial.rue:19:5"))) 1) (q 8 (q . "assertion failed at factorial.rue:18:5"))) 1) (q 8 (q . "assertion failed at factorial.rue:17:5"))) 1) (q 8 (q . "assertion failed at factorial.rue:16:5"))) 1) (q 8 (q . "assertion failed at factorial.rue:15:5"))) 1) (q 8 (q . "assertion failed at factorial.rue:14:5"))) 1) (c (q 2 (i (> 3 (q . 1)) (q 18 3 (a 2 (c 2 (- 3 (q . 1))))) (q 1 . 1)) 1) ()))
output: ()
runtime_cost: 39041
byte_cost: 4368000
Expand Down
2 changes: 1 addition & 1 deletion examples/fizz_buzz.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ total_cost: 5860496
tests:
- name: tests
program: (a (q 2 (i (= (a 4 (c 4 (a 10 (c (c 10 (c 22 (c 46 62))) (c (q . 1) (q . 1)))))) (a 4 (c 4 (c (q . 49) ())))) (q 2 (i (= (a 4 (c 4 (a 10 (c (c 10 (c 22 (c 46 62))) (c (q . 1) (q . 5)))))) (a 4 (c 4 (c (q . 49) (c (q . 50) (c (q . "Fizz") (c (q . 52) (c (q . "Buzz") ())))))))) (q 2 (i (= (a 4 (c 4 (a 10 (c (c 10 (c 22 (c 46 62))) (c (q . 1) (q . 15)))))) (a 4 (c 4 (c (q . 49) (c (q . 50) (c (q . "Fizz") (c (q . 52) (c (q . "Buzz") (c (q . "Fizz") (c (q . 55) (c (q . 56) (c (q . "Fizz") (c (q . "Buzz") (c (q . 12593) (c (q . "Fizz") (c (q . 12595) (c (q . 12596) (c (q . "FizzBuzz") ())))))))))))))))))) (q) (q 8)) 1) (q 8)) 1) (q 8)) 1) (c (c (q 2 (i (l 3) (q 11 (q . 2) (a 2 (c 2 5)) (a 2 (c 2 7))) (q 11 (q . 1) 3)) 1) (c (q 4 (a 30 (c (c 10 22) 5)) (a (i (= 5 7) (q) (q 2 4 (c (c 4 (c 10 (c 22 30))) (c (+ 5 (q . 1)) 7)))) 1)) (c (q 2 (i (> () 3) (q 14 (q . 45) (a 4 (c (c 4 6) (- () 3)))) (q 2 (i (> (q . 10) 3) (q 2 6 3) (q 14 (a 4 (c (c 4 6) (/ 3 (q . 10)))) (a 6 (% 3 (q . 10))))) 1)) 1) (c (q 16 1 (q . 48)) (q 2 (i (a (i (% 3 (q . 3)) (q) (q 2 (i (% 3 (q . 5)) (q) (q 1 . 1)) 1)) 1) (q 1 . "FizzBuzz") (q 2 (i (% 3 (q . 3)) (q 2 (i (% 3 (q . 5)) (q 2 4 (c (c 4 6) 3)) (q 1 . "Buzz")) 1) (q 1 . "Fizz")) 1)) 1))))) ()))
debug_program: (a (q 2 (i (= (a 4 (c 4 (a 10 (c (c 10 (c 22 (c 46 62))) (c (q . 1) (q . 1)))))) (a 4 (c 4 (c (q . 49) ())))) (q 2 (i (= (a 4 (c 4 (a 10 (c (c 10 (c 22 (c 46 62))) (c (q . 1) (q . 5)))))) (a 4 (c 4 (c (q . 49) (c (q . 50) (c (q . "Fizz") (c (q . 52) (c (q . "Buzz") ())))))))) (q 2 (i (= (a 4 (c 4 (a 10 (c (c 10 (c 22 (c 46 62))) (c (q . 1) (q . 15)))))) (a 4 (c 4 (c (q . 49) (c (q . 50) (c (q . "Fizz") (c (q . 52) (c (q . "Buzz") (c (q . "Fizz") (c (q . 55) (c (q . 56) (c (q . "Fizz") (c (q . "Buzz") (c (q . 12593) (c (q . "Fizz") (c (q . 12595) (c (q . 12596) (c (q . "FizzBuzz") ())))))))))))))))))) (q) (q 8 (q . "assertion failed at 43:5"))) 1) (q 8 (q . "assertion failed at 42:5"))) 1) (q 8 (q . "assertion failed at 41:5"))) 1) (c (c (q 2 (i (not (l 3)) (q 11 (concat (q . 1) 3)) (q 11 (concat (concat (q . 2) (a 2 (c 2 (f 3)))) (a 2 (c 2 (r 3)))))) 1) (c (q 2 (q 4 (a 61 (c (c 21 45) 11)) 2) (c (a (i (= 5 7) (q) (q 2 4 (c (c 4 (c 10 (c 22 30))) (c (+ 5 (q . 1)) 7)))) 1) 1)) (c (q 2 (i (> () 3) (q 14 (q . 45) (a 4 (c (c 4 6) (- () 3)))) (q 2 (i (> (q . 10) 3) (q 2 6 3) (q 14 (a 4 (c (c 4 6) (/ 3 (q . 10)))) (a 6 (% 3 (q . 10))))) 1)) 1) (c (q 16 (q . 48) 1) (q 2 (i (a (i (= (% 3 (q . 3)) ()) (q 2 (i (= (% 3 (q . 5)) ()) (q 1 . 1) (q)) 1) (q)) 1) (q 1 . "FizzBuzz") (q 2 (i (= (% 3 (q . 3)) ()) (q 1 . "Fizz") (q 2 (i (= (% 3 (q . 5)) ()) (q 1 . "Buzz") (q 2 4 (c (c 4 6) 3))) 1)) 1)) 1))))) ()))
debug_program: (a (q 2 (i (= (a 4 (c 4 (a 10 (c (c 10 (c 22 (c 46 62))) (c (q . 1) (q . 1)))))) (a 4 (c 4 (c (q . 49) ())))) (q 2 (i (= (a 4 (c 4 (a 10 (c (c 10 (c 22 (c 46 62))) (c (q . 1) (q . 5)))))) (a 4 (c 4 (c (q . 49) (c (q . 50) (c (q . "Fizz") (c (q . 52) (c (q . "Buzz") ())))))))) (q 2 (i (= (a 4 (c 4 (a 10 (c (c 10 (c 22 (c 46 62))) (c (q . 1) (q . 15)))))) (a 4 (c 4 (c (q . 49) (c (q . 50) (c (q . "Fizz") (c (q . 52) (c (q . "Buzz") (c (q . "Fizz") (c (q . 55) (c (q . 56) (c (q . "Fizz") (c (q . "Buzz") (c (q . 12593) (c (q . "Fizz") (c (q . 12595) (c (q . 12596) (c (q . "FizzBuzz") ())))))))))))))))))) (q) (q 8 (q . "assertion failed at fizz_buzz.rue:43:5"))) 1) (q 8 (q . "assertion failed at fizz_buzz.rue:42:5"))) 1) (q 8 (q . "assertion failed at fizz_buzz.rue:41:5"))) 1) (c (c (q 2 (i (not (l 3)) (q 11 (concat (q . 1) 3)) (q 11 (concat (concat (q . 2) (a 2 (c 2 (f 3)))) (a 2 (c 2 (r 3)))))) 1) (c (q 2 (q 4 (a 61 (c (c 21 45) 11)) 2) (c (a (i (= 5 7) (q) (q 2 4 (c (c 4 (c 10 (c 22 30))) (c (+ 5 (q . 1)) 7)))) 1) 1)) (c (q 2 (i (> () 3) (q 14 (q . 45) (a 4 (c (c 4 6) (- () 3)))) (q 2 (i (> (q . 10) 3) (q 2 6 3) (q 14 (a 4 (c (c 4 6) (/ 3 (q . 10)))) (a 6 (% 3 (q . 10))))) 1)) 1) (c (q 16 (q . 48) 1) (q 2 (i (a (i (= (% 3 (q . 3)) ()) (q 2 (i (= (% 3 (q . 5)) ()) (q 1 . 1) (q)) 1) (q)) 1) (q 1 . "FizzBuzz") (q 2 (i (= (% 3 (q . 3)) ()) (q 1 . "Fizz") (q 2 (i (= (% 3 (q . 5)) ()) (q 1 . "Buzz") (q 2 4 (c (c 4 6) 3))) 1)) 1)) 1))))) ()))
output: ()
runtime_cost: 316023
byte_cost: 11940000
Expand Down
2 changes: 1 addition & 1 deletion examples/hello_world.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ total_cost: 192020
tests:
- name: tests
program: (a (i (= (q . "Hello, world!") (q . "Hello, world!")) (q) (q 8)) 1)
debug_program: (a (q 2 (i (= (a 2 ()) (q . "Hello, world!")) (q) (q 8 (q . "assertion failed at 6:5"))) 1) (c (q 1 . "Hello, world!") ()))
debug_program: (a (q 2 (i (= (a 2 ()) (q . "Hello, world!")) (q) (q 8 (q . "assertion failed at hello_world.rue:6:5"))) 1) (c (q 1 . "Hello, world!") ()))
output: ()
runtime_cost: 437
byte_cost: 684000
Expand Down
Loading