lunar_wave/src/tests.rs

281 lines
5.5 KiB
Rust
Raw Normal View History

use crate::state::{
2023-09-25 00:47:17 +00:00
Block,
Chunk,
Instruction as Inst,
State,
Value,
};
2023-09-25 00:47:17 +00:00
#[test]
fn bools () {
/*
local function bool_to_x (b)
if b then
return 99
else
return 98
end
end
local x = bool_to_x (not not arg [1])
print (x)
return x
*/
let chunk = Chunk {
blocks: vec! [
Block {
instructions: vec! [
Inst::VarArgPrep (0),
Inst::Closure (0, 0),
Inst::Move (1, 0),
Inst::LoadFalse (2),
Inst::Call (1, 2, 1),
Inst::Move (1, 0),
Inst::LoadTrue (2),
Inst::Call (1, 2, 1),
Inst::Move (1, 0),
Inst::GetTabUp (2, 0, 0),
Inst::GetI (2, 2, 1),
Inst::Not (2, 2),
Inst::Not (2, 2),
Inst::Call (1, 2, 2),
Inst::GetTabUp (2, 0, 1),
Inst::Move (3, 1),
Inst::Call (2, 2, 1),
Inst::Return (1, 2, 1, false),
Inst::Return (2, 1, 1, false),
2023-09-25 00:47:17 +00:00
],
constants: vec! [
"arg".into (),
"print".into (),
],
upvalue_count: 1,
2023-09-25 00:47:17 +00:00
},
Block {
instructions: vec! [
Inst::Test (0, 0),
Inst::Jmp (3),
Inst::LoadI (1, 99),
Inst::Return1 (1),
Inst::Jmp (2),
Inst::LoadI (1, 98),
Inst::Return1 (1),
Inst::Return0,
],
constants: vec! [],
upvalue_count: 0,
2023-09-25 00:47:17 +00:00
},
],
};
for (arg, expected) in [
(vec! ["_exe_name"], vec! [98.into ()]),
(vec! ["_exe_name", "asdf"], vec! [99.into ()]),
] {
let mut vm = State::default ();
let upvalues = State::upvalues_from_args (arg.into_iter ().map (|s| s.to_string ()));
let actual = vm.execute_chunk (&chunk, &upvalues);
assert_eq! (actual, expected);
}
}
#[test]
fn floats () {
/*
local a = 0.5
local b = 3
local x = a + b
print (x)
return x
*/
2023-09-25 00:47:17 +00:00
let block = Block {
instructions: vec! [
Inst::VarArgPrep (0),
Inst::LoadK (0, 0),
Inst::LoadI (1, 3),
Inst::Add (2, 0, 1),
Inst::MmBin (0, 1, 6),
Inst::GetTabUp (3, 0, 1),
Inst::Move (4, 2),
Inst::Call (3, 2, 1),
Inst::Return (2, 2, 1, false),
Inst::Return (3, 1, 1, false),
],
constants: vec! [
0.5.into (),
"print".into (),
],
upvalue_count: 1,
};
2023-09-25 00:47:17 +00:00
let chunk = Chunk {
blocks: vec! [block],
};
for (arg, expected) in [
(vec! ["_exe_name"], vec! [3.5.into ()]),
2023-09-24 22:42:56 +00:00
(vec! ["_exe_name", " "], vec! [3.5.into ()]),
] {
let mut vm = State::default ();
let upvalues = State::upvalues_from_args (arg.into_iter ().map (|s| s.to_string ()));
let actual = vm.execute_chunk (&chunk, &upvalues);
assert_eq! (actual, expected);
}
}
#[test]
fn fma () {
/*
*/
let chunk = Chunk {
blocks: vec! [
Block {
instructions: vec! [
Inst::VarArgPrep (0),
Inst::Closure (0, 0),
Inst::Closure (1, 1),
Inst::Closure (2, 2),
Inst::Move (3, 2),
Inst::LoadI (4, 10),
Inst::LoadI (5, 11),
Inst::LoadI (6, 12),
Inst::Call (3, 4, 2),
Inst::GetTabUp (4, 0, 0),
Inst::Move (5, 3),
Inst::Call (4, 2, 1),
Inst::Return (3, 2, 1, false), // k?
Inst::Return (3, 2, 1, false), // k?
],
constants: vec! [
"print".into (),
],
upvalue_count: 1,
},
Block {
instructions: vec! [
Inst::Add (2, 0, 1),
Inst::MmBin (0, 1, 6),
Inst::Return1 (2),
Inst::Return0,
],
constants: vec! [],
upvalue_count: 0,
},
Block {
instructions: vec! [
Inst::Mul (2, 0, 1),
Inst::MmBin (0, 1, 8),
Inst::Return1 (2),
Inst::Return0,
],
constants: vec! [],
upvalue_count: 0,
},
Block {
instructions: vec! [
Inst::GetUpVal (3, 0), // add
Inst::GetUpVal (4, 1), // mul
Inst::Move (5, 0),
Inst::Move (6, 1),
Inst::Call (4, 3, 2),
Inst::Move (5, 2),
Inst::TailCall (3, 3, 0),
Inst::Return (3, 0, 0, false),
Inst::Return0,
],
constants: vec! [],
upvalue_count: 2,
},
],
};
for (arg, expected) in [
(vec! ["_exe_name"], vec! [122.into ()]),
(vec! ["_exe_name"], vec! [122.into ()]),
] {
let mut vm = State::default ();
let upvalues = State::upvalues_from_args (arg.into_iter ().map (|s| s.to_string ()));
let actual = vm.execute_chunk (&chunk, &upvalues);
assert_eq! (actual, expected);
}
}
#[test]
fn is_93 () {
/*
if arg [1] == "93" then
print "it's 93"
return 0
else
print "it's not 93"
return 1
end
*/
2023-09-25 00:47:17 +00:00
let block = Block {
instructions: vec! [
Inst::VarArgPrep (0),
Inst::GetTabUp (1, 0, 0),
Inst::GetI (1, 1, 1),
Inst::EqK (1, 1, 0),
Inst::Jmp (6),
Inst::GetTabUp (1, 0, 2),
Inst::LoadK (2, 3),
Inst::Call (1, 2, 1),
Inst::LoadI (1, 0),
Inst::Return (1, 2, 1, false),
Inst::Jmp (5),
Inst::GetTabUp (1, 0, 2),
Inst::LoadK (2, 4),
Inst::Call (1, 2, 1),
Inst::LoadI (1, 1),
Inst::Return (1, 2, 1, false),
Inst::Return (1, 1, 1, false),
],
constants: vec! [
"arg",
"93",
"print",
"it's 93",
"it's not 93",
2023-09-24 22:42:56 +00:00
].into_iter ().map (Value::from).collect (),
upvalue_count: 1,
};
2023-09-25 00:47:17 +00:00
let chunk = Chunk {
blocks: vec! [block],
};
for (arg, expected) in [
(vec! ["_exe_name"], vec! [1.into ()]),
(vec! ["_exe_name", "93"], vec! [0.into ()]),
(vec! ["_exe_name", "94"], vec! [1.into ()]),
] {
let mut vm = State::default ();
let upvalues = State::upvalues_from_args (arg.into_iter ().map (|s| s.to_string ()));
let actual = vm.execute_chunk (&chunk, &upvalues);
assert_eq! (actual, expected);
}
}
#[test]
fn loader () {
let bytecode = include_bytes! ("../test_vectors/closure.luac");
let mut rdr = std::io::Cursor::new (bytecode);
let file = crate::loader::parse_file (&mut rdr).unwrap ();
assert_eq! (file.file_name, "@test_vectors/closure.lua");
assert_eq! (file.blocks.len (), 3);
}