nlcc/tacky/
tast.rs

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),   //(src, dst)
36    SignExtend(TValue, TValue), // (src,dst)
37    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}