aboutsummaryrefslogtreecommitdiff
path: root/crates/sloth_bytecode/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/sloth_bytecode/src/lib.rs')
-rw-r--r--crates/sloth_bytecode/src/lib.rs89
1 files changed, 44 insertions, 45 deletions
diff --git a/crates/sloth_bytecode/src/lib.rs b/crates/sloth_bytecode/src/lib.rs
index bf20068..df91c41 100644
--- a/crates/sloth_bytecode/src/lib.rs
+++ b/crates/sloth_bytecode/src/lib.rs
@@ -7,65 +7,64 @@
unused_lifetimes
)]
-use sloth_bytecode_macros::instructions;
-
pub enum Error {
UnknownOpcode(u8),
InvalidArguments,
Eof,
}
-instructions! {
- Instruction;
-
- 0x00 Constant [u32] "Push a constant value onto the stack",
- 0x01 Load [u32] "Load a value from a variable",
- 0x02 Push [u32] "Push a value to a variable",
+macro_rules! opcodes {
+ ( $( $code:literal $name:ident $docs:literal ),* ) => {
+ #[repr(u8)]
+ #[derive(Clone, Copy, Eq, PartialEq)]
+ pub enum Opcode {
+ $(
+ #[doc = $docs]
+ $name = $code
+ ),*
+ }
- 0x10 Dup [] "Duplicate a value on the stack",
- 0x11 Del [] "Delete a value from the stack",
+ impl Opcode {
+ pub fn into_u8(self) -> u8 {
+ self as u8
+ }
- 0x20 Add [] "Add the last 2 values on the stack",
- 0x21 Sub [] "Subtract the last 2 values on the stack",
- 0x22 Mul [] "Multiply the last 2 values on the stack",
- 0x23 Div [] "Divide the last 2 values on the stack",
- 0x24 Mod [] "Modulo the last 2 values on the stack",
+ pub fn from_u8(value: u8) -> Opcode {
+ match value {
+ $( $code => Self:: $name , )*
+ _ => panic!("Invalid opcode"),
+ }
+ }
+ }
+ };
+}
- 0x30 Eq [] "Check if the last 2 values on the stack are equal",
- 0x31 Ne [] "Check if the last 2 values on the stack are not equal",
+opcodes! {
+ 0x00 Constant "Push a constant value onto the stack",
+ 0x01 Load "Load a value from a variable",
+ 0x02 Push "Push a value to a variable",
- 0x40 Jmp [u32] "Jump to a specific point in the program",
- 0x41 JmpIf [u32] "Jump to a specific point in the program if true is on the stack",
+ 0x10 Dup "Duplicate a value on the stack",
+ 0x11 Del "Delete a value from the stack",
- 0xE0 Hlt [] "Halt the program",
- 0xE1 Exit [] "Exit the program",
+ 0x20 Add "Add the last 2 values on the stack",
+ 0x21 Sub "Subtract the last 2 values on the stack",
+ 0x22 Mul "Multiply the last 2 values on the stack",
+ 0x23 Div "Divide the last 2 values on the stack",
+ 0x24 Mod "Modulo the last 2 values on the stack",
- 0xF0 VMReturn [] "[DEBUG] Pop value from stack and return it from the program",
-}
+ 0x30 Eq "Check if the last 2 values on the stack are equal",
+ 0x31 Ne "Check if the last 2 values on the stack are not equal",
-#[cfg(test)]
-mod tests {
- use crate::Instruction;
+ 0x40 Jmp "Jump to a specific point in the program",
+ 0x41 JmpIf "Jump to a specific point in the program if true is on the stack",
- #[test]
- #[rustfmt::skip]
- fn decompile_basic_instructions() {
- let code = [
- // Load constant 0
- 0x00, 0, 0, 0, 0,
- // Pop, Del, Add, Sub, Mul, Div, Mod
- 0x10, 0x11, 0x20, 0x21, 0x22, 0x23, 0x24,
- ];
+ 0x50 Call "Call function on stack",
+ 0x51 Return "Return from function on stack",
- let mut offset = 0;
+ 0xE0 Hlt "Halt the program",
+ 0xE1 Exit "Exit the program",
- assert_eq!(Instruction::disassemble(&code, &mut offset), Instruction::Constant(0));
- assert_eq!(Instruction::disassemble(&code, &mut offset), Instruction::Dup);
- assert_eq!(Instruction::disassemble(&code, &mut offset), Instruction::Del);
- assert_eq!(Instruction::disassemble(&code, &mut offset), Instruction::Add);
- assert_eq!(Instruction::disassemble(&code, &mut offset), Instruction::Sub);
- assert_eq!(Instruction::disassemble(&code, &mut offset), Instruction::Mul);
- assert_eq!(Instruction::disassemble(&code, &mut offset), Instruction::Div);
- assert_eq!(Instruction::disassemble(&code, &mut offset), Instruction::Mod);
- }
+ 0xF0 VMReturn "[DEBUG] Pop value from stack and return it fromthe program",
+ 0xF1 VMPrint "[DEBUG] Print value to console"
}