gbf_core/decompiler/ast/
block.rs1#![deny(missing_docs)]
2
3use gbf_macros::AstNodeTransform;
4use serde::{Deserialize, Serialize};
5
6use super::{AstKind, AstVisitable, ptr::P, visitors::AstVisitor};
7
8#[derive(Debug, Clone, Serialize, Deserialize, Eq, AstNodeTransform)]
10#[convert_to(AstKind::Block)]
11pub struct BlockNode {
12 pub instructions: Vec<AstKind>,
14}
15
16impl BlockNode {
17 pub fn new<V>(instructions: Vec<V>) -> Self
22 where
23 V: Into<AstKind>,
24 {
25 Self {
26 instructions: instructions.into_iter().map(Into::into).collect(),
27 }
28 }
29}
30
31impl AstVisitable for P<BlockNode> {
32 fn accept<V: AstVisitor>(&self, visitor: &mut V) -> V::Output {
33 visitor.visit_block(self)
34 }
35}
36
37impl PartialEq for BlockNode {
39 fn eq(&self, other: &Self) -> bool {
40 self.instructions == other.instructions
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47 use crate::decompiler::ast::{emit, new_assignment, new_float, new_id};
48
49 #[test]
50 fn test_block_node() {
51 let stmt_1 = new_assignment(new_id("foo"), new_id("bar"));
52 let stmt_2 = new_assignment(new_id("baz"), new_float("3.14"));
53 let block = BlockNode::new(vec![stmt_1, stmt_2]);
54 assert_eq!(block.instructions.len(), 2);
55 }
56
57 #[test]
58 fn test_block_emit() {
59 let stmt_1 = new_assignment(new_id("foo"), new_id("bar"));
60 let stmt_2 = new_assignment(new_id("baz"), new_float("3.14"));
61 let block = BlockNode::new(vec![stmt_1, stmt_2]);
62 let output = emit(block);
63 assert_eq!(output, "\n{\n foo = bar;\n baz = 3.14;\n}");
64 }
65}