1use crate::{
2 lexer::{Location, Token},
3 parser::{DefaultTypeSet, TypeSet},
4};
5
6#[derive(Debug)]
7pub struct Program {
8 pub items: Vec<Item>,
9}
10
11#[derive(Debug)]
12pub enum Item {
13 Function(Function),
14 ExternFunction(ExternalFunction),
15 GlobalVariable(GlobalVariable),
16}
17
18#[derive(Debug)]
19pub struct GlobalVariable {
20 pub decl_token: Token,
21 pub identifier: Token,
22 pub colon: Token,
23 pub type_token: TypeHint,
24 pub equals_token: Token,
25 pub initializer: Expression,
26 pub semicolon: Token,
27}
28impl GlobalVariable {
29 pub fn location(&self) -> Location {
30 let start = self.decl_token.location.start;
31 let end = self.semicolon.location.end;
32 Location { start, end }
33 }
34}
35
36#[derive(Debug)]
37pub struct ReturnDecl {
38 pub return_token: Token,
39 pub return_type: TypeHint,
40}
41
42#[derive(Debug)]
43pub struct ExternalFunction {
44 pub extern_fn_token: Token,
45 pub fn_token: Token,
46 pub name: Token,
47 pub opening_paren: Token,
48 pub arguments: Vec<FunctionArgument>,
49 pub closing_paren: Token,
50 pub return_decl: Option<ReturnDecl>,
51 pub semicolon: Token,
52}
53
54#[derive(Debug)]
55pub struct Function {
56 pub fn_token: Token,
57 pub name: Token,
58 pub opening_paren: Token,
59 pub arguments: Vec<FunctionArgument>,
60 pub closing_paren: Token,
61 pub return_decl: Option<ReturnDecl>,
62 pub body: Body,
63}
64
65#[derive(Debug, Clone)]
66pub struct Body {
67 pub opening_brace: Token,
68 pub statements: Vec<Statement>,
69 pub closing_brace: Token,
70}
71
72#[derive(Debug)]
73pub struct FunctionArgument {
74 pub name: Token,
75 pub colon: Token,
76 pub reference_token: Option<Token>,
77 pub arg_type: TypeHint,
78}
79
80#[derive(Clone, Copy, Debug)]
81pub struct TypeHint {
82 pub type_name: Token,
83}
84
85#[derive(Debug, Clone)]
86pub struct VariableDefinition {
87 pub decl_token: Token,
88 pub identifier: Token,
89 pub type_token: Option<TypeHint>,
90 pub equals_token: Token,
91 pub initializer: Expression,
92 pub semicolon: Token,
93}
94
95impl VariableDefinition {
96 pub fn location(&self) -> Location {
97 let start = self.decl_token.location.start;
98 let end = self.semicolon.location.end;
99 Location { start, end }
100 }
101}
102
103#[derive(Debug, Clone)]
104pub struct ReturnWithValue {
105 pub return_token: Token,
106 pub expression: Expression,
107 pub semicolon: Token,
108}
109
110impl ReturnWithValue {
111 pub fn location(&self) -> Location {
112 let start = self.return_token.location.start;
113 let end = self.semicolon.location.end;
114 Location { start, end }
115 }
116}
117
118#[derive(Debug, Clone)]
119pub struct EmptyReturn {
120 pub return_token: Token,
121 pub semicolon: Token,
122}
123
124impl EmptyReturn {
125 pub fn location(&self) -> Location {
126 let start = self.return_token.location.start;
127 let end = self.semicolon.location.end;
128 Location { start, end }
129 }
130}
131
132#[derive(Debug, Clone)]
133pub struct If {
134 pub if_token: Token,
135 pub condition: Expression,
136 pub body: Body,
137 pub else_branch: Option<Else>,
138}
139
140#[derive(Debug, Clone)]
141pub struct Loop {
142 pub loop_token: Token,
143 pub body: Body,
144}
145
146#[derive(Debug, Clone)]
147pub struct Break {
148 pub break_token: Token,
149 pub semicolon: Token,
150}
151
152#[derive(Debug, Clone)]
153pub struct Continue {
154 pub continue_token: Token,
155 pub semicolon: Token,
156}
157
158#[derive(Debug, Clone)]
159pub enum Statement {
160 VariableDefinition(VariableDefinition),
161 Return(ReturnWithValue),
162 EmptyReturn(EmptyReturn),
163 If(If),
164 Loop(Loop),
165 Break(Break),
166 Continue(Continue),
167 Expression {
168 expression: Expression,
169 semicolon: Token,
170 },
171}
172
173#[derive(Debug, Clone)]
174pub struct Else {
175 pub else_token: Token,
176 pub else_body: Body,
177}
178
179#[derive(Debug, Clone)]
180pub enum Expression<T = DefaultTypeSet>
181where
182 T: TypeSet,
183{
184 Variable {
185 variable: Token,
186 },
187 Literal {
188 value: Literal<T>,
189 },
190 UnaryOperator {
191 name: Token,
192 operand: Box<Self>,
193 },
194 BinaryOperator {
195 name: Token,
196 operands: Box<[Self; 2]>,
197 },
198 FunctionCall {
199 name: Token,
200 arguments: Box<[Self]>,
201 },
202}
203impl<T> Expression<T>
204where
205 T: TypeSet,
206{
207 pub fn location(&self) -> Location {
208 match self {
209 Expression::Variable { variable } => variable.location,
210 Expression::Literal { value } => value.location,
211 Expression::FunctionCall { name, arguments } => {
212 let mut location = name.location;
213 for arg in arguments {
214 location.start = location.start.min(arg.location().start);
215 location.end = location.end.max(arg.location().end);
216 }
217 location
218 }
219 Expression::UnaryOperator { name, operand: rhs } => {
220 let mut location = name.location;
221
222 location.start = location.start.min(rhs.location().start);
223 location.end = location.end.max(rhs.location().end);
224
225 location
226 }
227 Expression::BinaryOperator {
228 name,
229 operands: arguments,
230 } => {
231 let mut location = name.location;
232 for arg in arguments.iter() {
233 location.start = location.start.min(arg.location().start);
234 location.end = location.end.max(arg.location().end);
235 }
236 location
237 }
238 }
239 }
240
241 pub fn as_variable(&self) -> Option<Token> {
242 if let Expression::Variable { variable } = self {
243 Some(*variable)
244 } else {
245 None
246 }
247 }
248}
249
250#[derive(Debug, Clone)]
251pub struct Literal<T = DefaultTypeSet>
252where
253 T: TypeSet,
254{
255 pub value: LiteralValue<T>,
256 pub location: Location,
257}
258
259#[derive(Debug, Clone)]
260pub enum LiteralValue<T = DefaultTypeSet>
261where
262 T: TypeSet,
263{
264 Integer(T::Integer),
265 Float(T::Float),
266 String(String),
267 Boolean(bool),
268}