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");
+}