Cesar Rodas преди 8 месеца
родител
ревизия
a661fe4b18
променени са 3 файла, в които са добавени 74 реда и са изтрити 2 реда
  1. 53 1
      utxo/src/filter_expr/runtime.rs
  2. 20 1
      utxo/src/filter_expr/tests/mod.rs
  3. 1 0
      utxo/src/filter_expr/tests/or.expr

+ 53 - 1
utxo/src/filter_expr/runtime.rs

@@ -43,6 +43,7 @@ pub fn execute<'a>(
 
     loop {
         match code.get(*execution).ok_or(Error::OutOfBoundaries)? {
+            OpCode::LABEL(_addr) => {}
             OpCode::LOAD_EXTERNAL(dst, name) => {
                 let value = external_variables
                     .get(name)
@@ -66,6 +67,17 @@ pub fn execute<'a>(
                     .into();
                 set!(registers, dst, new_value);
             }
+            OpCode::SUB(dst, reg1, reg2) => {
+                let num1 = get!(registers, reg1).as_number()?;
+                let num2 = get!(registers, reg2).as_number()?;
+                set!(
+                    registers,
+                    dst,
+                    num1.checked_sub(num2)
+                        .map(|number| Value::Number(number).into())
+                        .ok_or(Error::Overflow)?
+                );
+            }
             OpCode::AND(dst, reg2, reg3) => {
                 let new_value = Value::Bool(
                     get!(registers, reg2).as_boolean()? && get!(registers, reg3).as_boolean()?,
@@ -73,10 +85,51 @@ pub fn execute<'a>(
                 .into();
                 set!(registers, dst, new_value);
             }
+            OpCode::MOD(dst, reg1, reg2) => {
+                let num1 = get!(registers, reg1).as_number()?;
+                let num2 = get!(registers, reg2).as_number()?;
+                set!(
+                    registers,
+                    dst,
+                    num1.checked_rem(num2)
+                        .map(|number| Value::Number(number).into())
+                        .ok_or(Error::Overflow)?
+                );
+            }
+            OpCode::NEG(dst, reg1) => {
+                let num1 = get!(registers, reg1).as_number()?;
+                set!(
+                    registers,
+                    dst,
+                    num1.checked_neg()
+                        .map(|number| Value::Number(number).into())
+                        .ok_or(Error::Overflow)?
+                );
+            }
+            OpCode::GE(dst, reg1, reg2) => {
+                let new_value = Value::Bool(get!(registers, reg1) >= get!(registers, reg2)).into();
+                set!(registers, dst, new_value);
+            }
+            OpCode::GT(dst, reg1, reg2) => {
+                let new_value = Value::Bool(get!(registers, reg1) > get!(registers, reg2)).into();
+                set!(registers, dst, new_value);
+            }
+            OpCode::LE(dst, reg1, reg2) => {
+                let new_value = Value::Bool(get!(registers, reg1) <= get!(registers, reg2)).into();
+                set!(registers, dst, new_value);
+            }
+            OpCode::LT(dst, reg1, reg2) => {
+                let new_value = Value::Bool(get!(registers, reg1) < get!(registers, reg2)).into();
+                set!(registers, dst, new_value);
+            }
             OpCode::EQ(dst, reg1, reg2) => {
                 let new_value = Value::Bool(get!(registers, reg1) == get!(registers, reg2)).into();
                 set!(registers, dst, new_value);
             }
+            OpCode::NE(dst, reg1, reg2) => {
+                let new_value = Value::Bool(get!(registers, reg1) != get!(registers, reg2)).into();
+                set!(registers, dst, new_value);
+            }
             OpCode::DIV(dst, reg1, reg2) => {
                 let num1 = get!(registers, reg1).as_number()?;
                 let num2 = get!(registers, reg2).as_number()?;
@@ -131,7 +184,6 @@ pub fn execute<'a>(
                     .map(|x| x.into())
                     .ok_or_else(|| Error::EmptyRegister(return_register.to_owned()));
             }
-            x => println!("{:?} is not implemented", x),
         }
 
         execution.next();

+ 20 - 1
utxo/src/filter_expr/tests/mod.rs

@@ -24,7 +24,26 @@ fn testsuite<K: Into<Variable>, V: Into<Value>, R: Into<Value>>(
 }
 
 #[test]
-fn test_1() {
+fn or_() {
+    testsuite(
+        include_str!("or.expr"),
+        vec![("foo", 2), ("bar", 3)],
+        Ok(false),
+    );
+    testsuite(
+        include_str!("or.expr"),
+        vec![("foo", 1), ("bar", 3)],
+        Ok(true),
+    );
+    testsuite(
+        include_str!("or.expr"),
+        vec![("foo", 2), ("bar", 2)],
+        Ok(true),
+    );
+}
+
+#[test]
+fn program_1() {
     testsuite(
         include_str!("program1.expr"),
         vec![("external", 5)],

+ 1 - 0
utxo/src/filter_expr/tests/or.expr

@@ -0,0 +1 @@
+foo = 1 OR bar = 2