1use std::fmt;
8
9use crate::loc::Loc;
10
11pub struct Program<'a> {
12 pub imports: Vec<Loc<Import<'a>>>,
13 pub functions: Vec<Loc<Function<'a>>>,
14}
15
16pub struct ImportedFunctionAlias<'a> {
17 pub as_token: Loc<()>,
18 pub name: Loc<&'a str>,
19}
20
21pub struct ImportedFunction<'a> {
22 pub name: Loc<&'a str>,
23 pub alias: Option<Loc<ImportedFunctionAlias<'a>>>,
24}
25
26pub struct Import<'a> {
27 pub from_token: Loc<()>,
28 pub path: Loc<&'a str>,
29 pub import_token: Loc<()>,
30 pub imported_functions: Vec<Loc<ImportedFunction<'a>>>,
31}
32
33pub struct Function<'a> {
34 pub name: Loc<&'a str>,
35 pub parameters: Vec<(Loc<&'a str>, Loc<TypeAnnotation>)>,
36 pub return_type: Option<Loc<TypeAnnotation>>,
37 pub body: Vec<Loc<FunctionCode<'a>>>,
38}
39
40pub enum FunctionCode<'a> {
41 Label {
42 label: Loc<Label<'a>>,
43 colon_token: Loc<()>,
44 },
45 Instruction(Loc<Instruction<'a>>),
46}
47
48pub struct Label<'a> {
49 pub name: Loc<&'a str>,
50}
51
52#[derive(Debug, Clone)]
53pub enum Type {
54 Int,
55 Bool,
56 Float,
57 Char,
58 Ptr(Box<Loc<Type>>),
59}
60
61impl Type {
62 pub fn is_same_type_as(&self, other: &Self) -> bool {
63 match (self, other) {
64 (Type::Int, Type::Int)
65 | (Type::Bool, Type::Bool)
66 | (Type::Float, Type::Float)
67 | (Type::Char, Type::Char) => true,
68 (Type::Ptr(inner), Type::Ptr(inner2)) => inner.is_same_type_as(inner2),
69 _ => false,
70 }
71 }
72}
73
74impl fmt::Display for Type {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 match self {
77 Type::Int => "int".fmt(f),
78 Type::Bool => "bool".fmt(f),
79 Type::Float => "float".fmt(f),
80 Type::Char => "char".fmt(f),
81 Type::Ptr(inner) => write!(f, "ptr<{}>", inner),
82 }
83 }
84}
85
86pub struct TypeAnnotation {
87 pub colon_token: Loc<()>,
88 pub ty: Loc<Type>,
89}
90
91pub enum Instruction<'a> {
92 Constant(Loc<Constant<'a>>),
93 ValueOperation(Loc<ValueOperation<'a>>),
94 EffectOperation(Loc<EffectOperation<'a>>),
95}
96
97pub enum ConstantValue {
98 IntegerLiteral(Loc<i64>),
99 BooleanLiteral(Loc<bool>),
100 FloatLiteral(Loc<f64>),
101 CharacterLiteral(Loc<char>),
102}
103
104pub struct Constant<'a> {
105 pub name: Loc<&'a str>,
106 pub type_annotation: Option<Loc<TypeAnnotation>>,
107 pub equals_token: Loc<()>,
108 pub const_token: Loc<()>,
109 pub value: Loc<ConstantValue>,
110 pub semi_token: Loc<()>,
111}
112
113pub enum ValueOperationOp<'a> {
114 Add(Loc<&'a str>, Loc<&'a str>),
115 Mul(Loc<&'a str>, Loc<&'a str>),
116 Sub(Loc<&'a str>, Loc<&'a str>),
117 Div(Loc<&'a str>, Loc<&'a str>),
118
119 Eq(Loc<&'a str>, Loc<&'a str>),
120 Lt(Loc<&'a str>, Loc<&'a str>),
121 Gt(Loc<&'a str>, Loc<&'a str>),
122 Le(Loc<&'a str>, Loc<&'a str>),
123 Ge(Loc<&'a str>, Loc<&'a str>),
124
125 Not(Loc<&'a str>),
126 And(Loc<&'a str>, Loc<&'a str>),
127 Or(Loc<&'a str>, Loc<&'a str>),
128
129 Call(Loc<&'a str>, Vec<Loc<&'a str>>),
131 Id(Loc<&'a str>),
132
133 Fadd(Loc<&'a str>, Loc<&'a str>),
134 Fmul(Loc<&'a str>, Loc<&'a str>),
135 Fsub(Loc<&'a str>, Loc<&'a str>),
136 Fdiv(Loc<&'a str>, Loc<&'a str>),
137 Feq(Loc<&'a str>, Loc<&'a str>),
138 Flt(Loc<&'a str>, Loc<&'a str>),
139 Fle(Loc<&'a str>, Loc<&'a str>),
140 Fgt(Loc<&'a str>, Loc<&'a str>),
141 Fge(Loc<&'a str>, Loc<&'a str>),
142
143 Alloc(Loc<&'a str>),
144 Load(Loc<&'a str>),
145 PtrAdd(Loc<&'a str>, Loc<&'a str>),
146
147 Ceq(Loc<&'a str>, Loc<&'a str>),
148 Clt(Loc<&'a str>, Loc<&'a str>),
149 Cgt(Loc<&'a str>, Loc<&'a str>),
150 Cle(Loc<&'a str>, Loc<&'a str>),
151 Cge(Loc<&'a str>, Loc<&'a str>),
152 Char2Int(Loc<&'a str>),
153 Int2Char(Loc<&'a str>),
154}
155
156pub struct ValueOperation<'a> {
157 pub name: Loc<&'a str>,
158 pub type_annotation: Option<Loc<TypeAnnotation>>,
159 pub equals_token: Loc<()>,
160 pub op: Loc<ValueOperationOp<'a>>,
161 pub semi_token: Loc<()>,
162}
163
164pub enum EffectOperationOp<'a> {
165 Jmp(Loc<Label<'a>>),
166 Br(Loc<&'a str>, Loc<Label<'a>>, Loc<Label<'a>>),
167 Call(Loc<&'a str>, Vec<Loc<&'a str>>),
169 Ret(Option<Loc<&'a str>>),
170
171 Print(Vec<Loc<&'a str>>),
172 Nop,
173
174 Store(Loc<&'a str>, Loc<&'a str>),
175 Free(Loc<&'a str>),
176}
177
178pub struct EffectOperation<'a> {
179 pub op: Loc<EffectOperationOp<'a>>,
180 pub semi_token: Loc<()>,
181}