diff options
| author | Nic Gaffney <gaffney_nic@protonmail.com> | 2023-04-14 00:25:32 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-14 00:25:32 -0500 |
| commit | 97b7cd10d2bec408cc237e13c61562c810d8fd29 (patch) | |
| tree | 03d4151581277209f3df48c1a49a656c6c32a52b /crates/sloth_bytecode/src | |
| parent | 6b25c191a4522610877898506856bd00cd1fc4d5 (diff) | |
| parent | fa0da150a5a481be3d1de448edb6f23c170da9a9 (diff) | |
| download | sloth-97b7cd10d2bec408cc237e13c61562c810d8fd29.tar.gz | |
Merge pull request #4 from slothlang/vm-basics
Basic VM
Diffstat (limited to 'crates/sloth_bytecode/src')
| -rw-r--r-- | crates/sloth_bytecode/src/lib.rs | 95 |
1 files changed, 54 insertions, 41 deletions
diff --git a/crates/sloth_bytecode/src/lib.rs b/crates/sloth_bytecode/src/lib.rs index 3593f3c..2319330 100644 --- a/crates/sloth_bytecode/src/lib.rs +++ b/crates/sloth_bytecode/src/lib.rs @@ -7,56 +7,69 @@ unused_lifetimes )] -use sloth_bytecode_macros::instructions; - pub enum Error { UnknownOpcode(u8), InvalidArguments, Eof, } -instructions! { - Instructions; +macro_rules! opcodes { + ( $( $code:literal $name:ident $docs:literal ),* ) => { + #[repr(u8)] + #[derive(Debug, Clone, Copy, Eq, PartialEq)] + pub enum Opcode { + $( + #[doc = $docs] + $name = $code + ),* + } - 0x00 Constant [u64] "Push a constant value onto the stack", - 0x01 Load [u64] "Load a value from a variable", - 0x02 Push [u64] "Push a value to a variable", + impl Opcode { + pub fn into_u8(self) -> u8 { + self as u8 + } - 0x10 Dup [] "Duplicate a value on the stack", - 0x11 Pop [] "Pop a value from the stack", + pub fn from_u8(value: u8) -> Opcode { + match value { + $( $code => Self:: $name , )* + _ => panic!("Invalid opcode"), + } + } + } + }; +} - 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", +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", - 0xF0 Print [] "[DEBUG] Pop value from stack and print it" -} + 0x10 Dup "Duplicate a value on the stack", + 0x11 Pop "Pop a value from the stack", + + 0x12 GetGlobal "Get a global value", + 0x13 SetGlobal "Set a global value", + 0x14 GetLocal "Get a local value", + 0x15 SetLocal "Set a local value", + + 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", + + 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", + + 0x40 Jump "Jump to a specific point in the program", + 0x41 JumpIf "Jump to a specific point in the program if true is on the stack", + + 0x50 Call "Call function on stack", + 0x51 CallNative "Call native function", + 0x52 Return "Return from function on stack", + + 0xE0 Halt "Halt the program", -#[cfg(test)] -mod tests { - use crate::Instructions; - - #[test] - #[rustfmt::skip] - fn decompile_basic_instructions() { - let code = [ - // Load constant 0 - 0x00, 0, 0, 0, 0, 0, 0, 0, 0, - // Pop, Dup, Add, Sub, Mul, Div, Mod - 0x10, 0x11, 0x20, 0x21, 0x22, 0x23, 0x24, - ]; - - let mut offset = 0; - - assert_eq!(Instructions::disassemble(&code, &mut offset), Instructions::Constant(0)); - assert_eq!(Instructions::disassemble(&code, &mut offset), Instructions::Dup); - assert_eq!(Instructions::disassemble(&code, &mut offset), Instructions::Pop); - assert_eq!(Instructions::disassemble(&code, &mut offset), Instructions::Add); - assert_eq!(Instructions::disassemble(&code, &mut offset), Instructions::Sub); - assert_eq!(Instructions::disassemble(&code, &mut offset), Instructions::Mul); - assert_eq!(Instructions::disassemble(&code, &mut offset), Instructions::Div); - assert_eq!(Instructions::disassemble(&code, &mut offset), Instructions::Mod); - } + 0xF0 VMReturn "[DEBUG] Pop value from stack and return it fromthe program", + 0xF1 VMPrint "[DEBUG] Print value to console" } |
