parent
bfeb70dd5a
commit
abe785cd89
@ -0,0 +1,24 @@
|
||||
use std::path::Path;
|
||||
|
||||
pub fn read_basic_files(path: impl AsRef<Path>) -> impl Iterator<Item = (String, String)> {
|
||||
path.as_ref().read_dir().unwrap().filter_map(|entry| {
|
||||
let Ok(entry) = entry else {
|
||||
return None;
|
||||
};
|
||||
|
||||
if entry
|
||||
.file_name()
|
||||
.into_string()
|
||||
.map(|name| name.ends_with(".mbas"))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
let file_name = entry.file_name().into_string().unwrap();
|
||||
let file = std::fs::read_to_string(entry.path()).unwrap_or_else(|e| {
|
||||
panic!("Error opening {:?}: {:?}", file_name, e);
|
||||
});
|
||||
Some((file_name, file))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
LET sum = 0
|
||||
|
||||
FOR i = 2 TO 5
|
||||
sum = sum + i
|
||||
NEXT i
|
||||
|
||||
IF sum == 14 THEN
|
||||
PRINT "success"
|
||||
ELSE
|
||||
PRINT "fail"
|
||||
END IF
|
@ -0,0 +1,26 @@
|
||||
LET x = 0
|
||||
|
||||
GOSUB double
|
||||
GOSUB add_one
|
||||
GOSUB double
|
||||
GOSUB double
|
||||
GOSUB add_one
|
||||
|
||||
IF x == 5 THEN
|
||||
PRINT "success"
|
||||
ELSE
|
||||
PRINT "fail"
|
||||
END IF
|
||||
|
||||
END
|
||||
PRINT "unreachable (after END)\n"
|
||||
|
||||
double:
|
||||
x = x * 2
|
||||
RETURN
|
||||
PRINT "unreachable (after RETURN in double)\n"
|
||||
|
||||
add_one:
|
||||
x = x + 1
|
||||
RETURN
|
||||
PRINT "unreachable (after RETURN in add_one)\n"
|
@ -0,0 +1 @@
|
||||
PRINT "success"
|
@ -0,0 +1,13 @@
|
||||
LET x = 32
|
||||
|
||||
start:
|
||||
x = x / 2
|
||||
IF x > 1 THEN
|
||||
GOTO start
|
||||
END IF
|
||||
|
||||
IF x == 1 THEN
|
||||
PRINT "success"
|
||||
ELSE
|
||||
PRINT "fail"
|
||||
END IF
|
@ -0,0 +1,7 @@
|
||||
LET x = 1
|
||||
|
||||
IF x > 0 THEN
|
||||
PRINT "success"
|
||||
ELSE
|
||||
PRINT "fail"
|
||||
END IF
|
@ -0,0 +1,11 @@
|
||||
LET x = 32
|
||||
|
||||
WHILE x > 1
|
||||
x = x / 2
|
||||
END WHILE
|
||||
|
||||
IF x == 1 THEN
|
||||
PRINT "success"
|
||||
ELSE
|
||||
PRINT "fail"
|
||||
END IF
|
@ -0,0 +1,64 @@
|
||||
#![feature(fs_try_exists)]
|
||||
|
||||
#[path = "./common.rs"]
|
||||
mod common;
|
||||
use common::*;
|
||||
|
||||
use basic_to_mindustry::{
|
||||
interpreter::{run, StopCondition, Value},
|
||||
optimize::{optimize_constant, optimize_jump_always, optimize_jump_op},
|
||||
parse_and_translate,
|
||||
prelude::MindustryProgram,
|
||||
};
|
||||
|
||||
/// Verifies that each test file in the `tests/print-success` test suite return `success` in the `@print` buffer.
|
||||
#[test]
|
||||
fn test_interprete_success() {
|
||||
fn test(program: &MindustryProgram, file_name: &str, opt_name: &str) {
|
||||
let result = run(&program, StopCondition::End);
|
||||
|
||||
assert_eq!(
|
||||
result.get("@print"),
|
||||
Some(&Value::String(String::from("success"))),
|
||||
"File {file_name} did not print 'success' in the {opt_name} configuration: {:?}",
|
||||
result.get("@print").cloned().unwrap_or_default()
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! chain {
|
||||
( $( $optimizer:expr ),* ) => {
|
||||
Box::new(|prog| {
|
||||
let res = prog;
|
||||
$(
|
||||
let res = $optimizer(res);
|
||||
)*
|
||||
res
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let optimizations: Vec<(
|
||||
&'static str,
|
||||
Box<dyn Fn(MindustryProgram) -> MindustryProgram>,
|
||||
)> = vec![
|
||||
("unoptimized", chain!()),
|
||||
("constant", chain!(optimize_constant)),
|
||||
(
|
||||
"constant+jump_op",
|
||||
chain!(optimize_constant, optimize_jump_op),
|
||||
),
|
||||
(
|
||||
"level-1",
|
||||
chain!(optimize_constant, optimize_jump_op, optimize_jump_always),
|
||||
),
|
||||
];
|
||||
|
||||
for (file_name, file) in read_basic_files("./tests/print-success/") {
|
||||
let unoptimized = parse_and_translate(&file, &Default::default()).unwrap();
|
||||
|
||||
for (opt_name, optimizer) in optimizations.iter() {
|
||||
let optimized = optimizer(unoptimized.clone());
|
||||
test(&optimized, &file_name, opt_name);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue