diff --git a/jit/src/instructions.rs b/jit/src/instructions.rs index 23e2b93c4..a4cebd7cc 100644 --- a/jit/src/instructions.rs +++ b/jit/src/instructions.rs @@ -313,31 +313,25 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> { } Instruction::UnaryOperation { op, .. } => { let a = self.stack.pop().ok_or(JitCompileError::BadBytecode)?; - - match a { - JitValue::Int(val) => match op { - UnaryOperator::Minus => { - // Compile minus as 0 - a. - let zero = self.builder.ins().iconst(types::I64, 0); - let out = self.compile_sub(zero, val); - self.stack.push(JitValue::Int(out)); - Ok(()) - } - UnaryOperator::Plus => { - // Nothing to do - self.stack.push(a); - Ok(()) - } - _ => Err(JitCompileError::NotSupported), - }, - JitValue::Bool(val) => match op { - UnaryOperator::Not => { - let not_val = self.builder.ins().bxor_imm(val, 1); - self.stack.push(JitValue::Bool(not_val)); - Ok(()) - } - _ => Err(JitCompileError::NotSupported), - }, + match (op, a) { + (UnaryOperator::Minus, JitValue::Int(val)) => { + // Compile minus as 0 - a. + let zero = self.builder.ins().iconst(types::I64, 0); + let out = self.compile_sub(zero, val); + self.stack.push(JitValue::Int(out)); + Ok(()) + } + (UnaryOperator::Plus, JitValue::Int(val)) => { + // Nothing to do + self.stack.push(JitValue::Int(val)); + Ok(()) + } + (UnaryOperator::Not, a) => { + let boolean = self.boolean_val(a)?; + let not_boolean = self.builder.ins().bxor_imm(boolean, 1); + self.stack.push(JitValue::Bool(not_boolean)); + Ok(()) + } _ => Err(JitCompileError::NotSupported), } } diff --git a/jit/tests/int_tests.rs b/jit/tests/int_tests.rs index ed7c24dae..314849a06 100644 --- a/jit/tests/int_tests.rs +++ b/jit/tests/int_tests.rs @@ -187,3 +187,15 @@ fn test_plus() { assert_eq!(plus(-3), Ok(-3)); assert_eq!(plus(0), Ok(0)); } + +#[test] +fn test_not() { + let not_ = jit_function! { not_(a: i64) -> bool => r##" + def not_(a: int): + return not a + "## }; + + assert_eq!(not_(0), Ok(true)); + assert_eq!(not_(1), Ok(false)); + assert_eq!(not_(-1), Ok(false)); +}