gbf_core/decompiler/handlers/
un_op.rs1#![deny(missing_docs)]
2
3use std::backtrace::Backtrace;
4
5use crate::{
6 decompiler::{
7 ProcessedInstruction, ProcessedInstructionBuilder,
8 ast::{new_unary_op, unary_op::UnaryOpType},
9 function_decompiler::FunctionDecompilerError,
10 function_decompiler_context::FunctionDecompilerContext,
11 },
12 instruction::Instruction,
13 opcode::Opcode,
14};
15
16use super::OpcodeHandler;
17
18pub struct UnaryOperationHandler;
20
21impl OpcodeHandler for UnaryOperationHandler {
22 fn handle_instruction(
23 &self,
24 context: &mut FunctionDecompilerContext,
25 instruction: &Instruction,
26 ) -> Result<ProcessedInstruction, FunctionDecompilerError> {
27 let expr = context.pop_expression()?;
28
29 let op_type: UnaryOpType = match instruction.opcode {
30 Opcode::LogicalNot => UnaryOpType::LogicalNot,
31 Opcode::BitwiseInvert => UnaryOpType::BitwiseNot,
32 Opcode::UnarySubtract => UnaryOpType::Negate,
33 _ => {
34 return Err(FunctionDecompilerError::UnimplementedOpcode {
35 opcode: instruction.opcode,
36 context: context.get_error_context(),
37 backtrace: Backtrace::capture(),
38 });
39 }
40 };
41
42 let op =
43 new_unary_op(expr, op_type).map_err(|e| FunctionDecompilerError::AstNodeError {
44 source: e,
45 context: context.get_error_context(),
46 backtrace: Backtrace::capture(),
47 })?;
48 context.push_one_node(op.into())?;
52
53 Ok(ProcessedInstructionBuilder::new().build())
54 }
55}