diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index b0eba79d..439a3ff2 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -1,5 +1,5 @@ use super::{AggFunc, BranchOffset, CursorID, FuncCtx, PageIdx}; -use crate::types::OwnedRecord; +use crate::types::{OwnedRecord, OwnedValue}; use limbo_macros::Description; #[derive(Description, Debug)] @@ -488,3 +488,150 @@ pub enum Insn { where_clause: String, }, } + +pub fn exec_add(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Integer(lhs + rhs), + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(lhs + rhs), + (OwnedValue::Float(f), OwnedValue::Integer(i)) + | (OwnedValue::Integer(i), OwnedValue::Float(f)) => OwnedValue::Float(*f + *i as f64), + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => todo!(), + } +} + +pub fn exec_subtract(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Integer(lhs - rhs), + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(lhs - rhs), + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Float(lhs - *rhs as f64), + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(*lhs as f64 - rhs), + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => todo!(), + } +} +pub fn exec_multiply(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Integer(lhs * rhs), + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(lhs * rhs), + (OwnedValue::Integer(i), OwnedValue::Float(f)) + | (OwnedValue::Float(f), OwnedValue::Integer(i)) => OwnedValue::Float(*i as f64 * { *f }), + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => todo!(), + } +} + +pub fn exec_divide(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (_, OwnedValue::Integer(0)) | (_, OwnedValue::Float(0.0)) => OwnedValue::Null, + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Integer(lhs / rhs), + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(lhs / rhs), + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Float(lhs / *rhs as f64), + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => OwnedValue::Float(*lhs as f64 / rhs), + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + _ => todo!(), + } +} + +pub fn exec_bit_and(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + (_, OwnedValue::Integer(0)) + | (OwnedValue::Integer(0), _) + | (_, OwnedValue::Float(0.0)) + | (OwnedValue::Float(0.0), _) => OwnedValue::Integer(0), + (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => OwnedValue::Integer(lh & rh), + (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { + OwnedValue::Integer(*lh as i64 & *rh as i64) + } + (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => OwnedValue::Integer(*lh as i64 & rh), + (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => OwnedValue::Integer(lh & *rh as i64), + _ => todo!(), + } +} +pub fn exec_bit_or(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Null, _) | (_, OwnedValue::Null) => OwnedValue::Null, + (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => OwnedValue::Integer(lh | rh), + (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => OwnedValue::Integer(*lh as i64 | rh), + (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => OwnedValue::Integer(lh | *rh as i64), + (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { + OwnedValue::Integer(*lh as i64 | *rh as i64) + } + _ => todo!(), + } +} + +pub fn exec_remainder(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = lhs { + lhs = agg.final_value(); + } + if let OwnedValue::Agg(agg) = rhs { + rhs = agg.final_value(); + } + match (lhs, rhs) { + (OwnedValue::Null, _) + | (_, OwnedValue::Null) + | (_, OwnedValue::Integer(0)) + | (_, OwnedValue::Float(0.0)) => OwnedValue::Null, + (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => OwnedValue::Integer(lhs % rhs), + (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float(((*lhs as i64) % (*rhs as i64)) as f64) + } + (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { + OwnedValue::Float(((*lhs as i64) % rhs) as f64) + } + (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { + OwnedValue::Float((lhs % *rhs as i64) as f64) + } + _ => todo!(), + } +} + +pub fn exec_bit_not(mut reg: &OwnedValue) -> OwnedValue { + if let OwnedValue::Agg(agg) = reg { + reg = agg.final_value(); + } + match reg { + OwnedValue::Null => OwnedValue::Null, + OwnedValue::Integer(i) => OwnedValue::Integer(!i), + OwnedValue::Float(f) => OwnedValue::Integer(!(*f as i64)), + _ => todo!(), + } +} diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index 20b5e39c..31193e60 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -42,6 +42,10 @@ use crate::vdbe::insn::Insn; use crate::{function::JsonFunc, json::get_json, json::json_array, json::json_array_length}; use crate::{Connection, Result, Rows, TransactionState, DATABASE_VERSION}; use datetime::{exec_date, exec_time, exec_unixepoch}; +use insn::{ + exec_add, exec_bit_and, exec_bit_not, exec_bit_or, exec_divide, exec_multiply, exec_remainder, + exec_subtract, +}; use likeop::{construct_like_escape_arg, exec_glob, exec_like_with_escape}; use rand::distributions::{Distribution, Uniform}; use rand::{thread_rng, Rng}; @@ -186,658 +190,42 @@ impl Program { state.pc = *target_pc; } Insn::Add { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Integer(lhs + rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs + rhs); - } - (OwnedValue::Float(f), OwnedValue::Integer(i)) - | (OwnedValue::Integer(i), OwnedValue::Float(f)) => { - state.registers[dest] = OwnedValue::Float(*f + *i as f64); - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Agg(aggctx), other) | (other, OwnedValue::Agg(aggctx)) => { - match other { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc + *i as f64); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(acc + i); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc + f); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(*acc as f64 + f); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Agg(aggctx2) => { - let acc = aggctx.final_value(); - let acc2 = aggctx2.final_value(); - match (acc, acc2) { - (OwnedValue::Integer(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = OwnedValue::Integer(acc + acc2); - } - (OwnedValue::Float(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = OwnedValue::Float(acc + acc2); - } - (OwnedValue::Integer(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = - OwnedValue::Float(*acc as f64 + acc2); - } - (OwnedValue::Float(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = - OwnedValue::Float(acc + *acc2 as f64); - } - _ => { - todo!("{:?} {:?}", acc, acc2); - } - } - } - rest => unimplemented!("{:?}", rest), - } - } - _ => { - todo!(); - } - } + state.registers[*dest] = + exec_add(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::Subtract { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Integer(lhs - rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs - rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs - *rhs as f64); - } - (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(*lhs as f64 - rhs); - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Agg(aggctx), rhs) => match rhs { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc - *i as f64); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(acc - i); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc - f); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(*acc as f64 - f); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Agg(aggctx2) => { - let acc = aggctx.final_value(); - let acc2 = aggctx2.final_value(); - match (acc, acc2) { - (OwnedValue::Integer(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = OwnedValue::Integer(acc - acc2); - } - (OwnedValue::Float(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = OwnedValue::Float(acc - acc2); - } - (OwnedValue::Integer(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = - OwnedValue::Float(*acc as f64 - acc2); - } - (OwnedValue::Float(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = - OwnedValue::Float(acc - *acc2 as f64); - } - _ => { - todo!("{:?} {:?}", acc, acc2); - } - } - } - rest => unimplemented!("{:?}", rest), - }, - (lhs, OwnedValue::Agg(aggctx)) => match lhs { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(*i as f64 - acc); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(i - acc); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(f - acc); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(f - *acc as f64); - } - _ => { - todo!("{:?}", aggctx); - } - }, - rest => unimplemented!("{:?}", rest), - }, - others => { - todo!("{:?}", others); - } - } + state.registers[*dest] = + exec_subtract(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::Multiply { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Integer(lhs * rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs * rhs); - } - (OwnedValue::Integer(i), OwnedValue::Float(f)) - | (OwnedValue::Float(f), OwnedValue::Integer(i)) => { - state.registers[dest] = OwnedValue::Float(*i as f64 * { *f }); - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Agg(aggctx), other) | (other, OwnedValue::Agg(aggctx)) => { - match other { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc * *i as f64); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(acc * i); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc * f); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(*acc as f64 * f); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Agg(aggctx2) => { - let acc = aggctx.final_value(); - let acc2 = aggctx2.final_value(); - match (acc, acc2) { - (OwnedValue::Integer(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = OwnedValue::Integer(acc * acc2); - } - (OwnedValue::Float(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = OwnedValue::Float(acc * acc2); - } - (OwnedValue::Integer(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = - OwnedValue::Float(*acc as f64 * acc2); - } - (OwnedValue::Float(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = - OwnedValue::Float(acc * *acc2 as f64); - } - _ => { - todo!("{:?} {:?}", acc, acc2); - } - } - } - rest => unimplemented!("{:?}", rest), - } - } - others => { - todo!("{:?}", others); - } - } + state.registers[*dest] = + exec_multiply(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::Divide { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - // If the divisor is zero, the result is NULL. - (_, OwnedValue::Integer(0)) | (_, OwnedValue::Float(0.0)) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Integer(lhs / rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs / rhs); - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - state.registers[dest] = OwnedValue::Float(lhs / *rhs as f64); - } - (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { - state.registers[dest] = OwnedValue::Float(*lhs as f64 / rhs); - } - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Agg(aggctx), rhs) => match rhs { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc / *i as f64); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(acc / i); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(acc / f); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(*acc as f64 / f); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Agg(aggctx2) => { - let acc = aggctx.final_value(); - let acc2 = aggctx2.final_value(); - match (acc, acc2) { - (OwnedValue::Integer(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = OwnedValue::Integer(acc / acc2); - } - (OwnedValue::Float(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = OwnedValue::Float(acc / acc2); - } - (OwnedValue::Integer(acc), OwnedValue::Float(acc2)) => { - state.registers[dest] = - OwnedValue::Float(*acc as f64 / acc2); - } - (OwnedValue::Float(acc), OwnedValue::Integer(acc2)) => { - state.registers[dest] = - OwnedValue::Float(acc / *acc2 as f64); - } - _ => { - todo!("{:?} {:?}", acc, acc2); - } - } - } - rest => unimplemented!("{:?}", rest), - }, - (lhs, OwnedValue::Agg(aggctx)) => match lhs { - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Integer(i) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(*i as f64 / acc); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Integer(i / acc); - } - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(f) => match aggctx.final_value() { - OwnedValue::Float(acc) => { - state.registers[dest] = OwnedValue::Float(f / acc); - } - OwnedValue::Integer(acc) => { - state.registers[dest] = OwnedValue::Float(f / *acc as f64); - } - _ => { - todo!("{:?}", aggctx); - } - }, - rest => unimplemented!("{:?}", rest), - }, - others => { - todo!("{:?}", others); - } - } + state.registers[*dest] = + exec_divide(&state.registers[*lhs], &state.registers[*rhs]); + state.pc += 1; + } + Insn::Remainder { lhs, rhs, dest } => { + state.registers[*dest] = + exec_remainder(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::BitAnd { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - // handle 0 and null cases - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (_, OwnedValue::Integer(0)) - | (OwnedValue::Integer(0), _) - | (_, OwnedValue::Float(0.0)) - | (OwnedValue::Float(0.0), _) => { - state.registers[dest] = OwnedValue::Integer(0); - } - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh & rh); - } - (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = OwnedValue::Integer(*lh as i64 & *rh as i64); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(*lh as i64 & rh); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh & *rh as i64); - } - (OwnedValue::Agg(aggctx), other) | (other, OwnedValue::Agg(aggctx)) => { - match other { - OwnedValue::Agg(aggctx2) => { - match (aggctx.final_value(), aggctx2.final_value()) { - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh & rh); - } - (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 & *rh as i64); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(lh & *rh as i64); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 & rh); - } - _ => { - unimplemented!( - "{:?} {:?}", - aggctx.final_value(), - aggctx2.final_value() - ); - } - } - } - other => match (aggctx.final_value(), other) { - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (_, OwnedValue::Integer(0)) - | (OwnedValue::Integer(0), _) - | (_, OwnedValue::Float(0.0)) - | (OwnedValue::Float(0.0), _) => { - state.registers[dest] = OwnedValue::Integer(0); - } - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh & rh); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 & rh); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(lh & *rh as i64); - } - _ => { - unimplemented!("{:?} {:?}", aggctx.final_value(), other); - } - }, - } - } - _ => { - unimplemented!("{:?} {:?}", state.registers[lhs], state.registers[rhs]); - } - } + state.registers[*dest] = + exec_bit_and(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::BitOr { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh | rh); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(*lh as i64 | rh); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh | *rh as i64); - } - (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = OwnedValue::Integer(*lh as i64 | *rh as i64); - } - (OwnedValue::Agg(aggctx), other) | (other, OwnedValue::Agg(aggctx)) => { - match other { - OwnedValue::Agg(aggctx2) => { - let final_lhs = aggctx.final_value(); - let final_rhs = aggctx2.final_value(); - match (final_lhs, final_rhs) { - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh | rh); - } - (OwnedValue::Float(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 | *rh as i64); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(lh | *rh as i64); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 | rh); - } - _ => { - unimplemented!("{:?} {:?}", final_lhs, final_rhs); - } - } - } - other => match (aggctx.final_value(), other) { - (OwnedValue::Null, _) | (_, OwnedValue::Null) => { - state.registers[dest] = OwnedValue::Null; - } - (OwnedValue::Integer(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = OwnedValue::Integer(lh | rh); - } - (OwnedValue::Float(lh), OwnedValue::Integer(rh)) => { - state.registers[dest] = - OwnedValue::Integer(*lh as i64 | rh); - } - (OwnedValue::Integer(lh), OwnedValue::Float(rh)) => { - state.registers[dest] = - OwnedValue::Integer(lh | *rh as i64); - } - _ => { - unimplemented!("{:?} {:?}", aggctx.final_value(), other); - } - }, - } - } - _ => { - unimplemented!("{:?} {:?}", state.registers[lhs], state.registers[rhs]); - } - } + state.registers[*dest] = + exec_bit_or(&state.registers[*lhs], &state.registers[*rhs]); state.pc += 1; } Insn::BitNot { reg, dest } => { - let reg = *reg; - let dest = *dest; - match &state.registers[reg] { - OwnedValue::Integer(i) => state.registers[dest] = OwnedValue::Integer(!i), - OwnedValue::Float(f) => { - state.registers[dest] = OwnedValue::Integer(!{ *f as i64 }) - } - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - OwnedValue::Agg(aggctx) => match aggctx.final_value() { - OwnedValue::Integer(i) => { - state.registers[dest] = OwnedValue::Integer(!i); - } - OwnedValue::Float(f) => { - state.registers[dest] = OwnedValue::Integer(!{ *f as i64 }); - } - OwnedValue::Null => { - state.registers[dest] = OwnedValue::Null; - } - _ => unimplemented!("{:?}", aggctx), - }, - _ => { - unimplemented!("{:?}", state.registers[reg]); - } - } - state.pc += 1; - } - Insn::Remainder { lhs, rhs, dest } => { - let lhs = *lhs; - let rhs = *rhs; - let dest = *dest; - state.registers[dest] = match (&state.registers[lhs], &state.registers[rhs]) { - (OwnedValue::Null, _) - | (_, OwnedValue::Null) - | (_, OwnedValue::Integer(0)) - | (_, OwnedValue::Float(0.0)) => OwnedValue::Null, - (OwnedValue::Integer(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Integer(lhs % rhs) - } - (OwnedValue::Float(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float(((*lhs as i64) % (*rhs as i64)) as f64) - } - (OwnedValue::Float(lhs), OwnedValue::Integer(rhs)) => { - OwnedValue::Float(((*lhs as i64) % rhs) as f64) - } - (OwnedValue::Integer(lhs), OwnedValue::Float(rhs)) => { - OwnedValue::Float((lhs % *rhs as i64) as f64) - } - (lhs, OwnedValue::Agg(agg_rhs)) => match lhs { - OwnedValue::Agg(agg_lhs) => { - let acc = agg_lhs.final_value(); - let acc2 = agg_rhs.final_value(); - match (acc, acc2) { - (_, OwnedValue::Integer(0)) - | (_, OwnedValue::Float(0.0)) - | (_, OwnedValue::Null) - | (OwnedValue::Null, _) => OwnedValue::Null, - (OwnedValue::Integer(l), OwnedValue::Integer(r)) => { - OwnedValue::Integer(l % r) - } - (OwnedValue::Float(lh_f), OwnedValue::Float(rh_f)) => { - OwnedValue::Float(((*lh_f as i64) % (*rh_f as i64)) as f64) - } - (OwnedValue::Integer(lh_i), OwnedValue::Float(rh_f)) => { - OwnedValue::Float((lh_i % (*rh_f as i64)) as f64) - } - _ => { - todo!("{:?} {:?}", acc, acc2); - } - } - } - OwnedValue::Integer(lh_i) => match agg_rhs.final_value() { - OwnedValue::Null => OwnedValue::Null, - OwnedValue::Float(rh_f) => { - OwnedValue::Float((lh_i % (*rh_f as i64)) as f64) - } - OwnedValue::Integer(rh_i) => OwnedValue::Integer(lh_i % rh_i), - _ => { - todo!("{:?}", agg_rhs); - } - }, - OwnedValue::Float(lh_f) => match agg_rhs.final_value() { - OwnedValue::Null => OwnedValue::Null, - OwnedValue::Float(rh_f) => { - OwnedValue::Float(((*lh_f as i64) % (*rh_f as i64)) as f64) - } - OwnedValue::Integer(rh_i) => { - OwnedValue::Float(((*lh_f as i64) % rh_i) as f64) - } - _ => { - todo!("{:?}", agg_rhs); - } - }, - _ => todo!("{:?}", rhs), - }, - (OwnedValue::Agg(aggctx), rhs) => match rhs { - OwnedValue::Integer(rh_i) => match aggctx.final_value() { - OwnedValue::Null => OwnedValue::Null, - OwnedValue::Float(lh_f) => { - OwnedValue::Float(((*lh_f as i64) % rh_i) as f64) - } - OwnedValue::Integer(lh_i) => OwnedValue::Integer(lh_i % rh_i), - _ => { - todo!("{:?}", aggctx); - } - }, - OwnedValue::Float(rh_f) => match aggctx.final_value() { - OwnedValue::Null => OwnedValue::Null, - OwnedValue::Float(lh_f) => { - OwnedValue::Float(((*lh_f as i64) % (*rh_f as i64)) as f64) - } - OwnedValue::Integer(lh_i) => { - OwnedValue::Float((lh_i % (*rh_f as i64)) as f64) - } - _ => { - todo!("{:?}", aggctx); - } - }, - _ => todo!("{:?}", rhs), - }, - _ => todo!("{:?} {:?}", state.registers[lhs], state.registers[rhs]), - }; + state.registers[*dest] = exec_bit_not(&state.registers[*reg]); state.pc += 1; } Insn::Null { dest, dest_end } => {