#object-file #read-write #section #kerbal #io-write #opcode #write-file

kerbalobjects

一个允许您读取或写入 KerbalObject 文件的 crate

51 个稳定版本

4.0.3 2023 年 6 月 21 日
4.0.2 2022 年 11 月 11 日
4.0.1 2022 年 10 月 27 日
3.1.13 2021 年 12 月 5 日
1.0.4 2020 年 11 月 17 日

#451解析器实现

Download history 1/week @ 2024-07-02

196 每月下载量
3 crate 中使用

GPL-3.0 许可证

335KB
4K SLoC

KerbalObjects

github github github License Crates.io Downloads

GitHub Workflow Status Libraries.io dependency status for GitHub repo

一个 Rust crate,允许任何人读取或写入 Kerbal Machine Code 文件或 Kerbal Object 文件。

[dependencies]
kerbalobjects = "4.0"

示例

Kerbal Machine Code hello world 程序示例

use std::io::Write;
use kerbalobjects::ksm::sections::{ArgumentSection, CodeSection, CodeType, DebugEntry, DebugRange, DebugSection};
use kerbalobjects::ksm::{Instr, KSMFile};
use kerbalobjects::{Opcode, KOSValue, ToBytes};

let mut arg_section = ArgumentSection::new();
let mut main_code = CodeSection::new(CodeType::Main);

let one = arg_section.add_checked(KOSValue::Int16(1));

// Corresponds to the KerbalScript code:
// PRINT("Hello, world!").

main_code.add(Instr::OneOp(Opcode::Push, arg_section.add_checked(KOSValue::String("@0001".into()))));
main_code.add(Instr::TwoOp(Opcode::Bscp, one, arg_section.add_checked(KOSValue::Int16(0))));
main_code.add(Instr::ZeroOp(Opcode::Argb));
main_code.add(Instr::OneOp(Opcode::Push, arg_section.add_checked(KOSValue::ArgMarker)));
main_code.add(Instr::OneOp(Opcode::Push, arg_section.add_checked(KOSValue::StringValue("Hello, world!".into()))));
main_code.add(Instr::TwoOp(Opcode::Call, arg_section.add_checked(KOSValue::String("".into())), arg_section.add_checked(KOSValue::String("print()".into()))));
main_code.add(Instr::ZeroOp(Opcode::Pop));
main_code.add(Instr::OneOp(Opcode::Escp, one));

let code_sections = vec![
    CodeSection::new(CodeType::Function),
    CodeSection::new(CodeType::Initialization),
    main_code
];

// A completely wrong and useless debug section, but we NEED to have one
let mut debug_entry =  DebugEntry::new(1).with_range(DebugRange::new(0x06, 0x13));

let debug_section = DebugSection::new(debug_entry);

let mut file_buffer = Vec::with_capacity(2048);

let ksm_file = KSMFile::new_from_parts(arg_section, code_sections, debug_section);

ksm_file.write(&mut file_buffer);

let mut file = std::fs::File::create("hello.ksm").expect("Couldn't open output file");

file.write_all(file_buffer.as_slice()).expect("Failed to write to output file");

Kerbal Object hello world 程序示例

use kerbalobjects::ko::symbols::{KOSymbol, SymBind, SymType};
use kerbalobjects::ko::{Instr, KOFile};
use kerbalobjects::{KOSValue, Opcode};
use kerbalobjects::ko::SectionIdx;
use kerbalobjects::ko::sections::DataIdx;
use std::io::Write;
use std::path::PathBuf;

let mut ko = KOFile::new();

let mut data_section = ko.new_data_section(".data");
let mut start = ko.new_func_section("_start");
let mut symtab = ko.new_symtab(".symtab");
let mut symstrtab = ko.new_strtab(".symstrtab");

// Set up the main code function section
let one = data_section.add_checked(KOSValue::Int16(1));

start.add(Instr::TwoOp(
    Opcode::Bscp,
    one,
    data_section.add_checked(KOSValue::Int16(0)),
));
start.add(Instr::ZeroOp(Opcode::Argb));
start.add(Instr::OneOp(
    Opcode::Push,
    data_section.add_checked(KOSValue::ArgMarker),
));
start.add(Instr::OneOp(
    Opcode::Push,
    data_section.add_checked(KOSValue::StringValue("Hello, world!".into())),
));
start.add(Instr::TwoOp(
    Opcode::Call,
    data_section.add_checked(KOSValue::String("".into())),
    data_section.add_checked(KOSValue::String("print()".into())),
));
start.add(Instr::ZeroOp(Opcode::Pop));
start.add(Instr::OneOp(Opcode::Escp, one));

// Set up our symbols
let file_symbol = KOSymbol::new(
    symstrtab.add("test.kasm"),
    DataIdx::PLACEHOLDER,
    0,
    SymBind::Global,
    SymType::File,
    SectionIdx::NULL,
);
let start_symbol = KOSymbol::new(
    symstrtab.add("_start"),
    DataIdx::PLACEHOLDER,
    start.size() as u16,
    SymBind::Global,
    SymType::Func,
    start.section_index(),
);

symtab.add(file_symbol);
symtab.add(start_symbol);

ko.add_data_section(data_section);
ko.add_func_section(start);
ko.add_str_tab(symstrtab);
ko.add_sym_tab(symtab);

// Write the file out to disk
let mut file_buffer = Vec::with_capacity(2048);

let ko = ko.validate().expect("Could not update KO headers properly");
ko.write(&mut file_buffer);

let file_path = PathBuf::from("test.ko");
let mut file =
    std::fs::File::create(file_path).expect("Output file could not be created: test.ko");

file.write_all(file_buffer.as_slice())
    .expect("File test.ko could not be written to.");

文档

有关如何使用此库的信息,请参阅 kerbalobjects docs.rs

有关 kOS 指令 及其功能的文档。

支持

除了文档外,您还可以在Discord 服务器中找到库作者的额外支持。

如果这不适用于您的用例

如果此库未实现您的程序所需的功能,请创建一个新问题或联系开发者。

如果问题无法解决,请参阅 docs/ 中的示例和 KSMKO 文件格式的说明以及如何创建或读取它们。

依赖项

~0.5–1MB
~22K SLoC