1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
#![feature(macro_metavar_expr)]
#![allow(dead_code)]
#![warn(
clippy::wildcard_imports,
clippy::string_add,
clippy::string_add_assign,
clippy::manual_ok_or,
unused_lifetimes
)]
macro_rules! instructions {
( $( $opcode:literal $name:ident [ $( $v_type:ident ),* ] $doc:literal ),* ) => {
#[repr(u8)]
enum Instruction {
$(
#[doc = $doc]
$name ( $( $v_type ),* ) = $opcode
),*
}
impl Instruction {
fn opcode(&self) -> u8 {
match self {
$(
Self::$name ( $( _ ${ignore(v_type)} ),* ) => $opcode
),*
}
}
fn from_bytecode(bytecode: &[u8]) -> Option<Self> {
if bytecode.is_empty() {
return None;
}
let opcode = bytecode[0];
let instruction = match opcode {
$(
$opcode => {
// TODO: Get the actual values
Some(Self::$name ( $( 0 ${ignore(v_type)} ),* ))
}
),*,
_ => None,
};
instruction
}
}
}
}
instructions! {
0x00 Constant [u64] "Push a constant value onto the stack",
0x01 Pop [] "Pop a value from the stack",
0x02 Dup [] "Duplicate a value on the stack",
0x10 Add [] "Add the last 2 values on the stack",
0x11 Sub [] "Subtract the last 2 values on the stack",
0x12 Mul [] "Multiply the last 2 values on the stack",
0x13 Div [] "Divide the last 2 values on the stack",
0x14 Mod [] "Modulo the last 2 values on the stack"
}
|