29个版本 (16个重大更新)

0.20.0 2023年12月18日
0.19.0 2023年9月22日
0.18.1 2023年5月6日
0.16.0 2022年8月10日
0.7.0 2021年7月1日

#135编程语言

Download history 9/week @ 2024-03-14 68/week @ 2024-03-28 24/week @ 2024-04-04

每月下载 171次
cambridge-asm-cli 中使用

MPL-2.0 许可证

94KB
2.5K SLoC

cambridge-asm

GitHub Workflow Status Crates.io

扩展指令集

使用宏

#[macro_use]
extern crate cambridge_asm;

// Import `Core` instruction set
use cambridge_asm::parse::Core;

// Custom instruction
inst! {
    ext (ctx) {
        // I/O accessed with ctx.io
        // Output is ctx.io.write
        // Use with write! or writeln! macros
        writeln!(ctx.io.write, "This is a custom instruction").unwrap();

        // Set r0 to detect custom instruction call
        ctx.gprs[0] = 20;
    }
}

// Extend `Core` instruction set
extend! {
    Ext extends Core {
        EXT => ext,
    }
}

不使用宏

// Import `Core` instruction set
use cambridge_asm::parse::Core;

// Imports of essential types
use cambridge_asm::{
    exec::{Context, ExecFunc, PasmResult},
    inst::{InstSet, Op},
};

pub fn ext(ctx: &mut Context, _: &Op) -> PasmResult {
    // I/O accessed with ctx.io
    // Output is ctx.io.write
    // Use with write! or writeln! macros
    writeln!(ctx.io.write, "This is a custom instruction").unwrap();

    // Set r0 to detect custom instruction call
    ctx.gprs[0] = 20;

    // Return Ok
    Ok(())
}

enum Ext {
    EXT,
    Parent(Core),
}

impl std::str::FromStr for Ext {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.to_uppercase().as_str() {
            "EXT" => Ok(Self::EXT),
            s => Ok(Self::Parent(s.parse::<Core>()?)),
        }
    }
}

impl std::fmt::Display for Ext {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::EXT => f.write_str("EXT"),
            Self::Parent(p) => write!(f, "{}", p),
        }
    }
}

impl InstSet for Ext {
    fn as_func_ptr(&self) -> ExecFunc {
        match self {
            Self::EXT => ext,
            Self::Parent(p) => p.as_func_ptr(),
        }
    }

    fn from_func_ptr(f: ExecFunc) -> Result<Self, String> {
        const EXT: ExecFunc = ext;

        match f {
            EXT => Ok(Self::EXT),
            f => Ok(Self::Parent(Core::from_func_ptr(f)?)),
        }
    }
}

使用方法

fn main() {
    use cambridge_asm::{exec::Io, parse::jit};

    const PROG: &str = r#"EXT
END

NONE:
"#;
    let out = TestStdout::new(vec![]);

    let mut e = jit::<Ext>(PROG, Io::default()).unwrap();
    e.exec::<Ext>();

    // Check if r0 == 20
    assert_eq!(e.ctx.gprs[0], 20);
}

参考 src/parse.rs 了解如何使用宏构建扩展指令集

使用完全自定义的指令集

#[macro_use]
extern crate cambridge_asm;

inst! {
    h (ctx) {
        write!(ctx.io.write, "H").unwrap();
    }
}

inst! {
    e (ctx) {
        write!(ctx.io.write, "E").unwrap();
    }
}

inst! {
    l (ctx) {
        write!(ctx.io.write, "L").unwrap();
    }
}

inst! {
    o (ctx) {
        write!(ctx.io.write, "O").unwrap();
    }
}

// Define a new instruction set
inst_set! {
    Custom {
        H => h,
        E => e,
        L => l,
        O => o,
        END => cambridge_asm::exec::io::end,
    }
}

// Using it
fn main() {
    use cambridge_asm::{exec::Io, parse::jit};

    // Outputs "HELLO"
    const PROG: &str = r#"H
E
L
L
O
END

NONE:
"#;

    let out = TestStdout::new(vec![]);

    let mut e = jit::<Custom>(PROG, Io::default()).unwrap();
    e.exec::<Custom>();
}

依赖关系

~1.8–2.4MB
~23K SLoC