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 在 编程语言
每月下载 171次
在 cambridge-asm-cli 中使用
94KB
2.5K SLoC
cambridge-asm
扩展指令集
使用宏
#[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