#![cfg(feature = "ksm")]
use std::io::{Read, Write};
use std::path::PathBuf;
use kerbalobjects::ksm::sections::{ArgumentSection, DebugSection};
use kerbalobjects::{
ksm::{
sections::{CodeSection, CodeType, DebugEntry, DebugRange},
Instr, KSMFile,
},
BufferIterator, KOSValue, Opcode,
};
#[test]
fn read_kosos_kash() {
let mut buffer = Vec::with_capacity(2048);
let file_path = PathBuf::from("tests").join("kash.ksm");
let mut file = std::fs::File::open(file_path).expect("Error opening KSM file");
file.read_to_end(&mut buffer)
.expect("Error reading kash.ksm");
let mut buffer_iter = BufferIterator::new(&buffer);
let expected_args = vec![
KOSValue::String("@0001".into()),
KOSValue::Int16(1),
KOSValue::Int16(0),
KOSValue::StringValue("kpp 1.1".into()),
KOSValue::StringValue("https://gitlab.com/thexa4/kos-kpp".into()),
KOSValue::String("$class".into()),
KOSValue::String("__new".into()),
KOSValue::ArgMarker,
KOSValue::String("@0481".into()),
KOSValue::Int16(2),
KOSValue::String("$r".into()),
KOSValue::String("@0063".into()),
KOSValue::Int16(3),
];
let ksm = KSMFile::parse(&mut buffer_iter).expect("Error reading KSM file");
let mut arg_section_args = ksm.arg_section.arguments();
for arg in expected_args {
assert_eq!(&arg, arg_section_args.next().unwrap());
}
let mut code_sections = ksm.code_sections();
code_sections.next().unwrap();
code_sections.next().unwrap();
let main_code = code_sections.next().unwrap();
assert!(code_sections.next().is_none());
let expected_instrs = vec![
Opcode::Lbrt,
Opcode::Bscp,
Opcode::Argb,
Opcode::Push,
Opcode::Pop,
Opcode::Push,
Opcode::Pop,
Opcode::Push,
Opcode::Gmet,
Opcode::Push,
Opcode::Push,
Opcode::Jmp,
Opcode::Bscp,
Opcode::Stol,
Opcode::Argb,
Opcode::Push,
];
let mut instructions = main_code.instructions();
for opcode in expected_instrs {
assert_eq!(opcode, instructions.next().unwrap().opcode());
}
}
#[test]
fn read_kos_ksm() {
let mut buffer = Vec::with_capacity(2048);
let file_path = PathBuf::from("tests").join("example.ksm");
let mut file = std::fs::File::open(file_path).expect("Error opening KSM file");
file.read_to_end(&mut buffer)
.expect("Error reading example.ksm");
let mut buffer_iter = BufferIterator::new(&buffer);
let _ksm = KSMFile::parse(&mut buffer_iter).expect("Error reading KSM file");
}
#[test]
fn read_write_ksm() {
write_ksm();
read_ksm();
}
fn write_ksm() {
let print = KOSValue::String(String::from("print()"));
let empty = KOSValue::String(String::from(""));
let two = KOSValue::ScalarInt(2);
let marker = KOSValue::ArgMarker;
let first = KOSValue::String(String::from("@0001"));
let one = KOSValue::Int16(1);
let zero = KOSValue::Int16(0);
let mut arg_section = ArgumentSection::new();
let first_index = arg_section.add(first);
let print_index = arg_section.add(print);
let empty_index = arg_section.add(empty);
let two_index = arg_section.add(two);
let marker_index = arg_section.add(marker);
let one_index = arg_section.add(one);
let zero_index = arg_section.add(zero);
let push_marker = Instr::OneOp(Opcode::Push, marker_index);
let add_instr = Instr::ZeroOp(Opcode::Add);
let push_two_instr = Instr::OneOp(Opcode::Push, two_index);
let call_print = Instr::TwoOp(Opcode::Call, empty_index, print_index);
let lbrt_instr = Instr::OneOp(Opcode::Lbrt, first_index);
let begin_scope = Instr::TwoOp(Opcode::Bscp, one_index, zero_index);
let pop_instr = Instr::ZeroOp(Opcode::Pop);
let end_scope = Instr::OneOp(Opcode::Escp, one_index);
let argb_instr = Instr::ZeroOp(Opcode::Argb);
let mut main_section = CodeSection::new(CodeType::Main);
let init_section = CodeSection::new(CodeType::Initialization);
let func_section = CodeSection::new(CodeType::Function);
main_section.add(lbrt_instr);
main_section.add(begin_scope);
main_section.add(argb_instr);
main_section.add(push_marker);
main_section.add(push_two_instr);
main_section.add(push_two_instr);
main_section.add(add_instr);
main_section.add(call_print);
main_section.add(pop_instr);
main_section.add(end_scope);
let code_sections = vec![func_section, init_section, main_section];
let debug_entry = DebugEntry::new(1).with_range(DebugRange::new(6, 0x18));
let debug_section = DebugSection::new(debug_entry);
let mut file_buffer = Vec::with_capacity(2048);
let ksm = KSMFile::new_from_parts(arg_section, code_sections, debug_section);
ksm.write(&mut file_buffer);
let file_path = PathBuf::from("tests").join("test.ksm");
let mut file = std::fs::File::create(file_path).expect("Error opening test.ksm");
file.write_all(file_buffer.as_slice())
.expect("test.ksm could not be written to.");
}
fn read_ksm() {
let mut buffer = Vec::with_capacity(2048);
let file_path = PathBuf::from("tests").join("test.ksm");
let mut file = std::fs::File::open(file_path).expect("Error opening test.ksm");
file.read_to_end(&mut buffer)
.expect("Error reading test.ksm");
let mut buffer_iter = BufferIterator::new(&buffer);
let _ksm = KSMFile::parse(&mut buffer_iter);
}