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