Skip to main content

packtab/
ir.rs

1/// Integer types for generated code.
2#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3pub enum IntType {
4    U8,
5    U16,
6    U32,
7    U64,
8    I8,
9    I16,
10    I32,
11    I64,
12}
13
14impl IntType {
15    /// Bit width of this type.
16    pub fn bits(self) -> u8 {
17        match self {
18            IntType::U8 | IntType::I8 => 8,
19            IntType::U16 | IntType::I16 => 16,
20            IntType::U32 | IntType::I32 => 32,
21            IntType::U64 | IntType::I64 => 64,
22        }
23    }
24
25    /// Whether this is an unsigned type.
26    pub fn is_unsigned(self) -> bool {
27        matches!(self, IntType::U8 | IntType::U16 | IntType::U32 | IntType::U64)
28    }
29
30    /// The smallest type that fits [min_v, max_v].
31    pub fn for_range(min_v: i64, max_v: i64) -> IntType {
32        if 0 <= min_v && max_v <= 255 {
33            return IntType::U8;
34        }
35        if -128 <= min_v && max_v <= 127 {
36            return IntType::I8;
37        }
38        if 0 <= min_v && max_v <= 65535 {
39            return IntType::U16;
40        }
41        if -32768 <= min_v && max_v <= 32767 {
42            return IntType::I16;
43        }
44        if 0 <= min_v && max_v <= 4_294_967_295 {
45            return IntType::U32;
46        }
47        if -2_147_483_648 <= min_v && max_v <= 2_147_483_647 {
48            return IntType::I32;
49        }
50        if 0 <= min_v {
51            return IntType::U64;
52        }
53        IntType::I64
54    }
55
56    /// Short name like "u8", "i32".
57    pub fn abbr(self) -> &'static str {
58        match self {
59            IntType::U8 => "u8",
60            IntType::U16 => "u16",
61            IntType::U32 => "u32",
62            IntType::U64 => "u64",
63            IntType::I8 => "i8",
64            IntType::I16 => "i16",
65            IntType::I32 => "i32",
66            IntType::I64 => "i64",
67        }
68    }
69}
70
71/// A declared array in the generated code.
72#[derive(Debug, Clone)]
73pub struct ArrayDecl {
74    pub name: String,
75    pub typ: IntType,
76    pub values: Vec<i64>,
77    pub private: bool,
78}
79
80/// A declared function in the generated code.
81#[derive(Debug, Clone)]
82pub struct FuncDecl {
83    pub name: String,
84    pub ret_type: IntType,
85    pub arg_name: String,
86    pub body: String,
87    pub comment: Option<String>,
88    pub private: bool,
89    pub inline_always: bool,
90}
91
92/// Sub-byte accessor function declaration.
93#[derive(Debug, Clone)]
94pub struct AccessorDecl {
95    pub name: String,
96    pub unit_bits: u8,
97    pub inline_always: bool,
98}
99
100/// The complete generated code: arrays + functions.
101#[derive(Debug, Clone)]
102pub struct CodeIR {
103    pub arrays: Vec<ArrayDecl>,
104    pub accessors: Vec<AccessorDecl>,
105    pub functions: Vec<FuncDecl>,
106}
107
108impl CodeIR {
109    pub fn new() -> Self {
110        Self {
111            arrays: Vec::new(),
112            accessors: Vec::new(),
113            functions: Vec::new(),
114        }
115    }
116}