1use crate::ast::{AstBinaryOp, AstConst, AstUnaryOp, Identifier, Type};
2use crate::semantic_analysis::{StaticInit, SYM_TABLE};
3
4#[derive(Clone, Debug)]
5pub struct TAst {
6 pub toplevel_items: Vec<TopLevelItem>,
7}
8
9pub type TInstructions = Vec<TInstruction>;
10
11#[derive(Debug, Clone)]
12pub struct TFunction {
13 pub name: Identifier,
14 pub params: Vec<Identifier>,
15 pub body: TInstructions,
16 pub global: bool,
17}
18
19#[derive(Debug, Clone)]
20pub struct StaticVariable {
21 pub name: Identifier,
22 pub global: bool,
23 pub init: StaticInit,
24 pub var_type: Type,
25}
26
27#[derive(Debug, Clone)]
28pub enum TopLevelItem {
29 Fun(TFunction),
30 Var(StaticVariable),
31}
32
33#[derive(Clone, Debug)]
34pub enum TInstruction {
35 Truncate(TValue, TValue), SignExtend(TValue, TValue), ZeroExtend(TValue, TValue),
38 Return(TValue),
39 Unary(TUnaryOp, TValue, TValue),
40 Binary(TBinaryOp, TValue, TValue, TValue),
41 Copy(TValue, TValue),
42 Jump(Identifier),
43 JumpIfZero(TValue, Identifier),
44 JumpIfNotZero(TValue, Identifier),
45 Label(Identifier),
46 FunCall {
47 name: Identifier,
48 args: Vec<TValue>,
49 dst: TValue,
50 },
51}
52
53#[derive(Copy, Clone, Debug)]
54pub enum TBinaryOp {
55 Add,
56 Substract,
57 Multiply,
58 Divide,
59 Reminder,
60 IsEqual,
61 IsNotEqual,
62 IsLessThan,
63 IsLessOrEqual,
64 IsGreaterThan,
65 IsGreaterOrEqual,
66 BitwiseAnd,
67 BitwiseOr,
68 BitwiseXor,
69 ShiftLeft,
70 ShiftRight,
71}
72
73#[derive(Clone, Debug)]
74pub enum TValue {
75 Constant(AstConst),
76 Var(Identifier),
77}
78
79impl TValue {
80 pub fn get_type(&self) -> Type {
81 match self {
82 Self::Constant(c) => c.get_type(),
83 Self::Var(name) => SYM_TABLE.get_type(name).expect("Should be in symbol table"),
84 }
85 }
86}
87
88#[derive(Copy, Clone, Debug)]
89pub enum TUnaryOp {
90 Complement,
91 Negate,
92 LogicalNot,
93}
94
95impl TBinaryOp {
96 pub fn is_shift(self) -> bool {
97 matches!(self, TBinaryOp::ShiftLeft | TBinaryOp::ShiftRight)
98 }
99 pub fn is_divrem(self) -> bool {
100 matches!(self, TBinaryOp::Divide | TBinaryOp::Reminder)
101 }
102
103 pub fn is_rem(self) -> bool {
104 matches!(self, TBinaryOp::Reminder)
105 }
106
107 pub fn is_relational(self) -> bool {
108 matches!(
109 self,
110 Self::IsEqual
111 | Self::IsNotEqual
112 | Self::IsLessThan
113 | Self::IsLessOrEqual
114 | Self::IsGreaterThan
115 | Self::IsGreaterOrEqual
116 )
117 }
118}
119
120impl From<AstUnaryOp> for TUnaryOp {
121 fn from(value: AstUnaryOp) -> Self {
122 match value {
123 AstUnaryOp::Complement => TUnaryOp::Complement,
124 AstUnaryOp::Negate => TUnaryOp::Negate,
125 AstUnaryOp::LogicalNot => TUnaryOp::LogicalNot,
126 _ => unimplemented!(),
127 }
128 }
129}
130
131impl From<AstBinaryOp> for TBinaryOp {
132 fn from(value: AstBinaryOp) -> Self {
133 match value {
134 AstBinaryOp::Add => Self::Add,
135 AstBinaryOp::Substract => Self::Substract,
136 AstBinaryOp::Mod => Self::Reminder,
137 AstBinaryOp::Multiply => Self::Multiply,
138 AstBinaryOp::Div => Self::Divide,
139 AstBinaryOp::IsEqual => Self::IsEqual,
140 AstBinaryOp::IsNotEqual => Self::IsNotEqual,
141 AstBinaryOp::LessThan => Self::IsLessThan,
142 AstBinaryOp::LessOrEqual => Self::IsLessOrEqual,
143 AstBinaryOp::GreaterThan => Self::IsGreaterThan,
144 AstBinaryOp::GreaterOrEqual => Self::IsGreaterOrEqual,
145 AstBinaryOp::BitwiseAnd => Self::BitwiseAnd,
146 AstBinaryOp::BitwiseOr => Self::BitwiseOr,
147 AstBinaryOp::BitwiseXor => Self::BitwiseXor,
148 AstBinaryOp::ShiftLeft => Self::ShiftLeft,
149 AstBinaryOp::ShiftRight => Self::ShiftRight,
150 _ => unimplemented!(),
151 }
152 }
153}