diff --git a/src/compiler.cairo b/src/compiler.cairo index 6444ac72..5f9991ce 100644 --- a/src/compiler.cairo +++ b/src/compiler.cairo @@ -40,6 +40,7 @@ pub impl CompilerTraitImpl of CompilerTrait { opcodes.insert('OP_1ADD', Opcode::OP_1ADD); opcodes.insert('OP_ADD', Opcode::OP_ADD); opcodes.insert('OP_MAX', Opcode::OP_MAX); + opcodes.insert('OP_WITHIN', Opcode::OP_WITHIN); Compiler { opcodes } } diff --git a/src/opcodes/opcodes.cairo b/src/opcodes/opcodes.cairo index 6354b3e1..b430ba5b 100644 --- a/src/opcodes/opcodes.cairo +++ b/src/opcodes/opcodes.cairo @@ -21,6 +21,7 @@ pub mod Opcode { pub const OP_1ADD: u8 = 139; pub const OP_ADD: u8 = 147; pub const OP_MAX: u8 = 164; + pub const OP_WITHIN: u8 = 165; use shinigami::engine::Engine; use shinigami::stack::ScriptStackTrait; @@ -191,6 +192,7 @@ pub mod Opcode { 162 => not_implemented(ref engine), 163 => not_implemented(ref engine), 164 => opcode_max(ref engine), + 165 => opcode_within(ref engine), _ => not_implemented(ref engine) } } @@ -234,4 +236,15 @@ pub mod Opcode { b }); } + + fn opcode_within(ref engine: Engine) { + let max = engine.dstack.pop_int(); + let min = engine.dstack.pop_int(); + let value = engine.dstack.pop_int(); + engine.dstack.push_int(if value >= min && value < max { + 1 + } else { + 0 + }); + } } diff --git a/src/opcodes/tests/test_opcodes.cairo b/src/opcodes/tests/test_opcodes.cairo index 29f593f6..bd683a52 100644 --- a/src/opcodes/tests/test_opcodes.cairo +++ b/src/opcodes/tests/test_opcodes.cairo @@ -70,6 +70,25 @@ fn test_op_max() { assert_eq!(dstack, expected_stack.span(), "Stack is not equal to expected"); } +#[test] +fn test_op_within() { + let program = "OP_1 OP_0 OP_1 OP_WITHIN"; + let mut compiler = CompilerTraitImpl::new(); + let bytecode = compiler.compile(program); + let mut engine = EngineTraitImpl::new(bytecode); + let _ = engine.step(); + 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\0"]; + assert_eq!(dstack, expected_stack.span(), "Stack is not equal to expected"); +} + fn test_op_depth_empty_stack() { let program = "OP_DEPTH"; let mut compiler = CompilerTraitImpl::new();