1use std::fmt::Display;
2
3use crate::semantic_analysis::{identifier_resolution::UniqId, label::TempLabel, type_check::slice_to_string};
4
5#[derive(Debug, Clone)]
7pub struct AProgram {
8 pub declarations: Vec<Declaration>,
9}
10
11#[derive(Debug, Clone)]
15pub struct AFunctionDeclaration {
16 pub id: AId,
17 pub param_list: Params,
18 pub body: Option<Block>,
19 pub class: Option<StorageClass>,
20 pub global: Option<bool>,
22}
23
24#[derive(Debug, Clone)]
26pub enum Params {
27 Void,
28 V(Vec<AId>),
29}
30
31#[derive(Debug, Clone)]
32pub enum Declaration {
33 V(AVariableDeclaration),
34 F(AFunctionDeclaration),
35}
36
37#[derive(Debug, Clone)]
39pub struct AVariableDeclaration {
40 pub name: AId,
41 pub init: Option<AExpr>,
42 pub class: Option<StorageClass>,
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46pub enum StorageClass {
47 Static,
48 Extern,
49}
50
51#[derive(Debug, Clone)]
53pub enum ABlockItem {
54 D(Declaration),
55 S(AStatement),
56}
57
58#[derive(Debug, Clone)]
69pub enum AStatement {
70 Ret(AExpr),
71 E(AExpr),
72 If(AExpr, Box<AStatement>, Option<Box<AStatement>>),
74 B(Block),
75 Break(Option<TempLabel>),
76 Continue(Option<TempLabel>),
77 While(AExpr, Box<AStatement>, Option<TempLabel>),
78 DoWhile(AExpr, Box<AStatement>, Option<TempLabel>),
79 For(
81 AForInit,
82 Option<AExpr>,
83 Option<AExpr>,
84 Box<AStatement>,
85 Option<TempLabel>,
86 ),
87 Nul,
88}
89
90#[derive(Debug, Clone)]
92pub enum AForInit {
93 D(AVariableDeclaration),
94 E(AExpr),
95 Nul,
96}
97
98#[derive(Debug, Clone)]
100pub struct Block(pub Vec<ABlockItem>);
101
102#[derive(Debug, Clone)]
107pub enum AExpr {
108 F(Box<AFactor>),
109 B(Binop, Box<AExpr>, Box<AExpr>),
110 A(Box<AExpr>, Box<AExpr>),
111 C(Box<AExpr>, Box<AExpr>, Box<AExpr>),
112}
113
114#[derive(Debug, Clone)]
117pub enum AFactor {
118 Int(AConstant),
119 U(Unop, Box<AFactor>),
120 E(AExpr),
121 I(AId),
122 FunctionCall(AId, Option<Vec<AExpr>>),
123}
124
125#[derive(Debug, Clone, Copy, PartialEq, Eq)]
127pub enum Unop {
128 Neg,
129 Complement,
130 Not,
131 PreIncr,
132 PostIncr,
133 PreDecr,
134 PostDecr,
135}
136impl Display for Unop {
137 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
138 let look = self.what_does_it_look_like();
139 write!(f, "{look}")
140 }
141}
142impl Unop {
143 fn what_does_it_look_like(&self) -> &str {
144 match self {
145 Unop::Neg => "-",
146 Unop::Complement => "~",
147 Unop::Not => "!",
148 Unop::PreIncr => "++ (Pre)",
149 Unop::PostIncr => "++ (Post)",
150 Unop::PreDecr => "-- (Pre)",
151 Unop::PostDecr => "-- (Post)",
152 }
153 }
154}
155
156#[derive(Debug, Clone, Copy, PartialEq, Eq)]
159pub enum Binop {
160 Subtract,
161 Add,
162 Multiply,
163 Divide,
164 Modulo,
165 And,
166 Or,
167 EqualTo,
168 NotEqualTo,
169 LessThan,
170 LessThanOrEqual,
171 MoreThan,
172 MoreThanOrEqual,
173 Equal,
174 Ternary,
176}
177impl Display for Binop {
178 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
179 write!(f, "{}", self.what_does_it_look_like())
180 }
181}
182
183impl Binop {
184 fn what_does_it_look_like(&self) -> &str {
185 match self {
186 Binop::Subtract => "-",
187 Binop::Add => "+",
188 Binop::Multiply => "*",
189 Binop::Divide => "/",
190 Binop::Modulo => "%",
191 Binop::And => "&",
192 Binop::Or => "^",
193 Binop::EqualTo => "==",
194 Binop::NotEqualTo => "!=",
195 Binop::LessThan => "<",
196 Binop::LessThanOrEqual => "<=",
197 Binop::MoreThan => ">",
198 Binop::MoreThanOrEqual => ">=",
199 Binop::Equal => "=",
200 Binop::Ternary => panic!(),
202 }
203 }
204}
205
206#[derive(Debug, Clone, Copy, PartialEq, Eq)]
208pub enum AConstant {
209 A(S),
210 C(i64),
211}
212impl AConstant {
213 #[must_use]
214 pub fn to_string(&self, code: &[u8]) -> String {
215 match self {
216 AConstant::A(s) => slice_to_string(code, *s),
217 AConstant::C(num) => num.to_string(),
218 }
219 }
220}
221
222#[derive(Debug, Clone, Copy)]
224pub struct AId(pub S, pub Option<UniqId>);
225
226#[derive(Debug, Clone, Copy, PartialEq, Eq)]
228pub struct S(pub usize, pub usize);