From 4554c3f09613db1b167c0bacd1e6fa47d853eb31 Mon Sep 17 00:00:00 2001 From: Patrice Tisserand Date: Thu, 25 Jul 2024 23:49:47 +0200 Subject: [PATCH] feat: #17 add `OP_MIN` opcode --- src/compiler.cairo | 1 + src/opcodes/opcodes.cairo | 28 ++++++++++++++ src/opcodes/tests/test_opcodes.cairo | 57 ++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/src/compiler.cairo b/src/compiler.cairo index 9e853b3d..6e2825e4 100644 --- a/src/compiler.cairo +++ b/src/compiler.cairo @@ -36,6 +36,7 @@ pub impl CompilerTraitImpl of CompilerTrait { opcodes.insert('OP_15', Opcode::OP_15); opcodes.insert('OP_16', Opcode::OP_16); opcodes.insert('OP_ADD', Opcode::OP_ADD); + opcodes.insert('OP_MIN', Opcode::OP_MIN); Compiler { opcodes } } diff --git a/src/opcodes/opcodes.cairo b/src/opcodes/opcodes.cairo index 02f21240..63e6a00b 100644 --- a/src/opcodes/opcodes.cairo +++ b/src/opcodes/opcodes.cairo @@ -17,6 +17,7 @@ pub mod Opcode { pub const OP_15: u8 = 95; pub const OP_16: u8 = 96; pub const OP_ADD: u8 = 147; + pub const OP_MIN: u8 = 163; use shinigami::engine::Engine; use shinigami::stack::ScriptStackTrait; @@ -170,6 +171,22 @@ pub mod Opcode { 145 => not_implemented(ref engine), 146 => not_implemented(ref engine), 147 => opcode_add(ref engine), + 148 => not_implemented(ref engine), + 149 => not_implemented(ref engine), + 150 => not_implemented(ref engine), + 151 => not_implemented(ref engine), + 152 => not_implemented(ref engine), + 153 => not_implemented(ref engine), + 154 => not_implemented(ref engine), + 155 => not_implemented(ref engine), + 156 => not_implemented(ref engine), + 157 => not_implemented(ref engine), + 158 => not_implemented(ref engine), + 159 => not_implemented(ref engine), + 160 => not_implemented(ref engine), + 161 => not_implemented(ref engine), + 162 => not_implemented(ref engine), + 163 => opcode_min(ref engine), _ => not_implemented(ref engine) } } @@ -189,6 +206,17 @@ pub mod Opcode { engine.dstack.push_int(a + b); } + fn opcode_min(ref engine: Engine) { + let a = engine.dstack.pop_int(); + let b = engine.dstack.pop_int(); + + engine.dstack.push_int(if a < b { + a + } else { + b + }); + } + fn not_implemented(ref engine: Engine) { panic!("Opcode not implemented"); } diff --git a/src/opcodes/tests/test_opcodes.cairo b/src/opcodes/tests/test_opcodes.cairo index f16d66be..d2c6bbca 100644 --- a/src/opcodes/tests/test_opcodes.cairo +++ b/src/opcodes/tests/test_opcodes.cairo @@ -141,3 +141,60 @@ fn test_op_add() { let expected_stack = array!["\0\0\0\0\0\0\0\x02"]; assert_eq!(dstack, expected_stack.span(), "Stack is not equal to expected"); } + +#[test] +fn test_op_min_min_first() { + let program = "OP_1 OP_2 OP_MIN"; + let mut compiler = CompilerTraitImpl::new(); + let bytecode = compiler.compile(program); + let mut engine = EngineTraitImpl::new(bytecode); + + let _ = engine.step(); + let _ = engine.step(); + let res = engine.step(); + assert!(res, "Execution of run failed"); + + let dstack = engine.get_dstack(); + assert_eq!(dstack.len(), 1, "Stack length is not 1"); + + let expected_stack = array!["\0\0\0\0\0\0\0\x01"]; + assert_eq!(dstack, expected_stack.span(), "Stack is not equal to expected"); +} + +#[test] +fn test_op_min_min_second() { + let program = "OP_2 OP_1 OP_MIN"; + let mut compiler = CompilerTraitImpl::new(); + let bytecode = compiler.compile(program); + let mut engine = EngineTraitImpl::new(bytecode); + + let _ = engine.step(); + let _ = engine.step(); + let res = engine.step(); + assert!(res, "Execution of run failed"); + + let dstack = engine.get_dstack(); + assert_eq!(dstack.len(), 1, "Stack length is not 1"); + + let expected_stack = array!["\0\0\0\0\0\0\0\x01"]; + assert_eq!(dstack, expected_stack.span(), "Stack is not equal to expected"); +} + +#[test] +fn test_op_min_same_value() { + let program = "OP_1 OP_1 OP_MIN"; + let mut compiler = CompilerTraitImpl::new(); + let bytecode = compiler.compile(program); + let mut engine = EngineTraitImpl::new(bytecode); + + let _ = engine.step(); + let _ = engine.step(); + let res = engine.step(); + assert!(res, "Execution of run failed"); + + let dstack = engine.get_dstack(); + assert_eq!(dstack.len(), 1, "Stack length is not 1"); + + let expected_stack = array!["\0\0\0\0\0\0\0\x01"]; + assert_eq!(dstack, expected_stack.span(), "Stack is not equal to expected"); +}