cambridge_asm/exec/
inst.rs1use crate::{
7 exec::{Context, RtResult},
8 inst::Op,
9};
10
11pub type ExecFunc = fn(&mut Context, &Op) -> RtResult;
13
14#[derive(Clone)]
16pub struct ExecInst {
17 pub id: u64,
19 pub func: ExecFunc,
20 pub op: Op,
21}
22
23impl ExecInst {
24 pub fn new(id: u64, inst: ExecFunc, op: Op) -> Self {
25 Self { func: inst, op, id }
26 }
27}
28
29#[macro_export]
47macro_rules! inst {
48 ($(#[$outer:meta])* $vis:vis $name:ident ($ctx:ident, $op:ident) { $( $code:tt )* }) => {
49 $(#[$outer])*
50 $vis fn $name($ctx: &mut $crate::exec::Context, $op: & $crate::inst::Op) -> $crate::exec::RtResult {
51 use $crate::inst::Op::*;
52 $( $code )*
53 Ok(())
54 }
55 };
56 ($(#[$outer:meta])* $vis:vis $name:ident ($ctx:ident) { $( $code:tt )* }) => {
57 $(#[$outer])*
58 $vis fn $name($ctx: &mut $crate::exec::Context, _: & $crate::inst::Op) -> $crate::exec::RtResult {
59 $( $code )*
60 Ok(())
61 }
62 };
63 ($(#[$outer:meta])* $vis:vis $name:ident { $( $code:tt )* }) => {
64 $(#[$outer])*
65 $vis fn $name(_: &mut $crate::exec::Context, _: & $crate::inst::Op) -> $crate::exec::RtResult {
66 $( $code )*
67 Ok(())
68 }
69 };
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use crate::inst::Op::*;
76
77 #[test]
78 fn op_parsing() {
79 let ops = [
80 ("200", Addr(200)),
81 ("#x80", Literal(128)),
82 ("#b001", Literal(1)),
83 ("#800", Literal(800)),
84 (
85 "200,#8,be",
86 MultiOp(vec![Addr(200), Literal(8), Fail("be".into())]),
87 ),
88 ("", Null),
89 ("ACC,r10,#x10", MultiOp(vec![Acc, Gpr(10), Literal(16)])),
90 ];
91
92 for (op, res) in ops {
93 assert_eq!(Op::from(op), res);
94 }
95 }
96}