Module kerbalobjects::ksm

source ·
Expand description

Kerbal Machine Code files

This module is for describing, reading, and writing Kerbal Machine Code files

There must be at least a function, initialization, and main section in a KSMFile, and at the bare minimum the main section should contain at least one instruction.

There must be at least one debug entry in the debug section.

If these are not provided, expect a cryptic “too many arguments were passed to run” error message from kOS which tells you absolutely nothing about what actually went wrong about loading your file.

If an error occurs in a part of the code section, if it is filled with instructions, that is not mentioned in the debug section, kOS will say “maybe the error really is internal”, so if you can, provide valid debug sections.

There is a builder-style interface for creating a KSMFile documented in the module.

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");

Re-exports

Modules

  • A module containing code related to the KSMFileBuilder type, which allows for the creation of a KSMFile with a builder-like interface.
  • Errors specifically for when parsing a KSM file
  • kOS instructions as stored in a KSM file.
  • A collection of the sections that can be contained within a KSM file

Structs

Enums

  • Describes the number of bytes that are required to store a given integer.