Implement Not

This commit is contained in:
psvri
2025-01-20 00:21:23 +05:30
parent 876788588b
commit e616bd5361
6 changed files with 59 additions and 4 deletions

View File

@@ -1748,7 +1748,15 @@ pub fn translate_expr(
});
Ok(target_register)
}
_ => todo!(),
(UnaryOperator::Not, _) => {
let reg = program.alloc_register();
translate_expr(program, referenced_tables, expr, reg, resolver)?;
program.emit_insn(Insn::Not {
reg,
dest: target_register,
});
Ok(target_register)
}
},
ast::Expr::Variable(name) => {
let index = program.parameters.push(name);

View File

@@ -1083,6 +1083,15 @@ pub fn insn_to_str(
rg1, rg2, dest, dest
),
),
Insn::Not { reg, dest } => (
"Not",
*reg as i32,
*dest as i32,
0,
OwnedValue::build_text(Rc::new("".to_string())),
0,
format!("r[{}]=!r[{}]", dest, reg),
),
};
format!(
"{:<4} {:<17} {:<4} {:<4} {:<4} {:<13} {:<2} {}",

View File

@@ -516,6 +516,11 @@ pub enum Insn {
rg2: usize,
dest: usize,
},
/// Interpret the value in reg as boolean and store its compliment in destination
Not {
reg: usize,
dest: usize,
},
}
fn cast_text_to_numerical(value: &str) -> OwnedValue {
@@ -845,3 +850,16 @@ fn compute_shr(lhs: i64, rhs: i64) -> i64 {
lhs >> rhs
}
}
pub fn exec_boolean_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 == 0) as i64),
OwnedValue::Float(f) => OwnedValue::Integer((*f == 0.0) as i64),
OwnedValue::Text(text) => exec_boolean_not(&cast_text_to_numerical(&text.value)),
_ => todo!(),
}
}

View File

@@ -46,8 +46,8 @@ use crate::{
use crate::{resolve_ext_path, Connection, Result, Rows, TransactionState, DATABASE_VERSION};
use datetime::{exec_date, exec_datetime_full, exec_julianday, exec_time, exec_unixepoch};
use insn::{
exec_add, exec_bit_and, exec_bit_not, exec_bit_or, exec_divide, exec_multiply, exec_remainder,
exec_shift_left, exec_shift_right, exec_subtract,
exec_add, exec_bit_and, exec_bit_not, exec_bit_or, exec_boolean_not, exec_divide,
exec_multiply, exec_remainder, exec_shift_left, exec_shift_right, exec_subtract,
};
use likeop::{construct_like_escape_arg, exec_glob, exec_like_with_escape};
use rand::distributions::{Distribution, Uniform};
@@ -2265,6 +2265,10 @@ impl Program {
}
state.pc += 1;
}
Insn::Not { reg, dest } => {
state.registers[*dest] = exec_boolean_not(&state.registers[*reg]);
state.pc += 1;
}
}
}
}