1use crate::{lexer::Token, parser::TypeSet, Location};
2
3#[derive(Debug)]
4pub struct Program<T>
5where
6 T: TypeSet,
7{
8 pub items: Vec<Item<T>>,
9}
10
11#[derive(Debug)]
12pub enum Item<T>
13where
14 T: TypeSet,
15{
16 Function(Function<T>),
17 ExternFunction(ExternalFunction),
18 GlobalVariable(GlobalVariable<T>),
19}
20
21#[derive(Debug)]
22pub struct GlobalVariable<T>
23where
24 T: TypeSet,
25{
26 pub decl_token: Token,
27 pub identifier: Token,
28 pub colon: Token,
29 pub type_token: TypeHint,
30 pub equals_token: Token,
31 pub initializer: Expression<T>,
32 pub semicolon: Token,
33}
34impl<T> GlobalVariable<T>
35where
36 T: TypeSet,
37{
38 pub fn location(&self) -> Location {
39 let start = self.decl_token.location.start;
40 let end = self.semicolon.location.end;
41 Location { start, end }
42 }
43}
44
45#[derive(Debug)]
46pub struct ReturnDecl {
47 pub return_token: Token,
48 pub return_type: TypeHint,
49}
50
51#[derive(Debug)]
52pub struct ExternalFunction {
53 pub extern_fn_token: Token,
54 pub fn_token: Token,
55 pub name: Token,
56 pub opening_paren: Token,
57 pub arguments: Vec<FunctionArgument>,
58 pub closing_paren: Token,
59 pub return_decl: Option<ReturnDecl>,
60 pub semicolon: Token,
61}
62
63#[derive(Debug)]
64pub struct Function<T>
65where
66 T: TypeSet,
67{
68 pub fn_token: Token,
69 pub name: Token,
70 pub opening_paren: Token,
71 pub arguments: Vec<FunctionArgument>,
72 pub closing_paren: Token,
73 pub return_decl: Option<ReturnDecl>,
74 pub body: Body<T>,
75}
76
77#[derive(Debug)]
78pub struct Body<T>
79where
80 T: TypeSet,
81{
82 pub opening_brace: Token,
83 pub statements: Vec<Statement<T>>,
84 pub closing_brace: Token,
85}
86impl<T: TypeSet> Body<T> {
87 pub fn location(&self) -> Location {
88 Location {
89 start: self.opening_brace.location.start,
90 end: self.closing_brace.location.end,
91 }
92 }
93}
94
95impl<T> Clone for Body<T>
96where
97 T: TypeSet,
98{
99 fn clone(&self) -> Self {
100 Self {
101 opening_brace: self.opening_brace,
102 statements: self.statements.clone(),
103 closing_brace: self.closing_brace,
104 }
105 }
106}
107
108#[derive(Debug)]
109pub struct FunctionArgument {
110 pub name: Token,
111 pub colon: Token,
112 pub reference_token: Option<Token>,
113 pub arg_type: TypeHint,
114}
115
116#[derive(Clone, Copy, Debug)]
117pub struct TypeHint {
118 pub type_name: Token,
119}
120
121#[derive(Debug)]
122pub struct VariableDefinition<T>
123where
124 T: TypeSet,
125{
126 pub decl_token: Token,
127 pub identifier: Token,
128 pub type_token: Option<TypeHint>,
129 pub equals_token: Token,
130 pub initializer: RightHandExpression<T>,
131 pub semicolon: Token,
132}
133
134impl<T> Clone for VariableDefinition<T>
135where
136 T: TypeSet,
137{
138 fn clone(&self) -> Self {
139 Self {
140 decl_token: self.decl_token,
141 identifier: self.identifier,
142 type_token: self.type_token,
143 equals_token: self.equals_token,
144 initializer: self.initializer.clone(),
145 semicolon: self.semicolon,
146 }
147 }
148}
149
150impl<T> VariableDefinition<T>
151where
152 T: TypeSet,
153{
154 pub fn location(&self) -> Location {
155 let start = self.decl_token.location.start;
156 let end = self.semicolon.location.end;
157 Location { start, end }
158 }
159}
160
161#[derive(Debug)]
162pub struct ReturnWithValue<T>
163where
164 T: TypeSet,
165{
166 pub return_token: Token,
167 pub expression: RightHandExpression<T>,
168 pub semicolon: Token,
169}
170
171impl<T> Clone for ReturnWithValue<T>
172where
173 T: TypeSet,
174{
175 fn clone(&self) -> Self {
176 Self {
177 return_token: self.return_token,
178 expression: self.expression.clone(),
179 semicolon: self.semicolon,
180 }
181 }
182}
183
184impl<T> ReturnWithValue<T>
185where
186 T: TypeSet,
187{
188 pub fn location(&self) -> Location {
189 let start = self.return_token.location.start;
190 let end = self.semicolon.location.end;
191 Location { start, end }
192 }
193}
194
195#[derive(Debug, Clone)]
196pub struct EmptyReturn {
197 pub return_token: Token,
198 pub semicolon: Token,
199}
200
201impl EmptyReturn {
202 pub fn location(&self) -> Location {
203 let start = self.return_token.location.start;
204 let end = self.semicolon.location.end;
205 Location { start, end }
206 }
207}
208
209#[derive(Debug)]
210pub struct If<T>
211where
212 T: TypeSet,
213{
214 pub if_token: Token,
215 pub condition: RightHandExpression<T>,
216 pub body: Body<T>,
217 pub else_branch: Option<Else<T>>,
218}
219impl<T> If<T>
220where
221 T: TypeSet,
222{
223 pub fn location(&self) -> Location {
224 Location {
225 start: self.if_token.location.start,
226 end: self
227 .else_branch
228 .as_ref()
229 .map(|else_branch| else_branch.location().end)
230 .unwrap_or_else(|| self.body.location().end),
231 }
232 }
233}
234
235impl<T> Clone for If<T>
236where
237 T: TypeSet,
238{
239 fn clone(&self) -> Self {
240 Self {
241 if_token: self.if_token,
242 condition: self.condition.clone(),
243 body: self.body.clone(),
244 else_branch: self.else_branch.clone(),
245 }
246 }
247}
248
249#[derive(Debug)]
250pub struct Loop<T>
251where
252 T: TypeSet,
253{
254 pub loop_token: Token,
255 pub body: Body<T>,
256}
257impl<T> Loop<T>
258where
259 T: TypeSet,
260{
261 pub fn location(&self) -> Location {
262 Location {
263 start: self.loop_token.location.start,
264 end: self.body.location().end,
265 }
266 }
267}
268
269impl<T> Clone for Loop<T>
270where
271 T: TypeSet,
272{
273 fn clone(&self) -> Self {
274 Self {
275 loop_token: self.loop_token,
276 body: self.body.clone(),
277 }
278 }
279}
280
281#[derive(Debug, Clone)]
282pub struct Break {
283 pub break_token: Token,
284 pub semicolon: Token,
285}
286
287impl Break {
288 pub fn location(&self) -> Location {
289 let start = self.break_token.location.start;
290 let end = self.semicolon.location.end;
291 Location { start, end }
292 }
293}
294
295#[derive(Debug, Clone)]
296pub struct Continue {
297 pub continue_token: Token,
298 pub semicolon: Token,
299}
300
301impl Continue {
302 pub fn location(&self) -> Location {
303 let start = self.continue_token.location.start;
304 let end = self.semicolon.location.end;
305 Location { start, end }
306 }
307}
308
309#[derive(Debug)]
310pub enum Statement<T>
311where
312 T: TypeSet,
313{
314 VariableDefinition(VariableDefinition<T>),
315 Return(ReturnWithValue<T>),
316 EmptyReturn(EmptyReturn),
317 If(If<T>),
318 Loop(Loop<T>),
319 Break(Break),
320 Continue(Continue),
321 Scope(Body<T>),
322 Expression {
323 expression: Expression<T>,
324 semicolon: Token,
325 },
326 ImplicitReturn(RightHandExpression<T>),
327}
328impl<T: TypeSet> Statement<T> {
329 pub fn location(&self) -> Location {
330 match self {
331 Statement::VariableDefinition(variable_definition) => variable_definition.location(),
332 Statement::Return(return_with_value) => return_with_value.location(),
333 Statement::EmptyReturn(empty_return) => empty_return.location(),
334 Statement::If(if_stmt) => if_stmt.location(),
335 Statement::Loop(loop_stmt) => loop_stmt.location(),
336 Statement::Break(break_stmt) => break_stmt.location(),
337 Statement::Continue(continue_stmt) => continue_stmt.location(),
338 Statement::Scope(body) => body.location(),
339 Statement::Expression {
340 expression,
341 semicolon,
342 } => Location {
343 start: expression.location().start,
344 end: semicolon.location.end,
345 },
346 Statement::ImplicitReturn(right_hand_expression) => right_hand_expression.location(),
347 }
348 }
349}
350
351impl<T> Clone for Statement<T>
352where
353 T: TypeSet,
354{
355 fn clone(&self) -> Self {
356 match self {
357 Self::VariableDefinition(arg0) => Self::VariableDefinition(arg0.clone()),
358 Self::Return(arg0) => Self::Return(arg0.clone()),
359 Self::EmptyReturn(arg0) => Self::EmptyReturn(arg0.clone()),
360 Self::If(arg0) => Self::If(arg0.clone()),
361 Self::Loop(arg0) => Self::Loop(arg0.clone()),
362 Self::Break(arg0) => Self::Break(arg0.clone()),
363 Self::Continue(arg0) => Self::Continue(arg0.clone()),
364 Self::Scope(body) => Self::Scope(body.clone()),
365 Self::Expression {
366 expression,
367 semicolon,
368 } => Self::Expression {
369 expression: expression.clone(),
370 semicolon: *semicolon,
371 },
372 Statement::ImplicitReturn(expression) => Self::ImplicitReturn(expression.clone()),
373 }
374 }
375}
376
377#[derive(Debug)]
378pub struct Else<T>
379where
380 T: TypeSet,
381{
382 pub else_token: Token,
383 pub else_body: Body<T>,
384}
385impl<T> Else<T>
386where
387 T: TypeSet,
388{
389 pub fn location(&self) -> Location {
390 Location {
391 start: self.else_token.location.start,
392 end: self.else_body.location().end,
393 }
394 }
395}
396
397impl<T> Clone for Else<T>
398where
399 T: TypeSet,
400{
401 fn clone(&self) -> Self {
402 Self {
403 else_token: self.else_token,
404 else_body: self.else_body.clone(),
405 }
406 }
407}
408
409#[derive(Debug)]
410pub enum Expression<T>
411where
412 T: TypeSet,
413{
414 Assignment {
415 left_expr: LeftHandExpression,
416 operator: Token,
417 right_expr: RightHandExpression<T>,
418 },
419 Expression {
420 expression: RightHandExpression<T>,
421 },
422}
423impl<T> Clone for Expression<T>
424where
425 T: TypeSet,
426{
427 fn clone(&self) -> Self {
428 match self {
429 Expression::Assignment {
430 left_expr,
431 operator,
432 right_expr,
433 } => Self::Assignment {
434 left_expr: *left_expr,
435 operator: *operator,
436 right_expr: right_expr.clone(),
437 },
438 Expression::Expression { expression } => Self::Expression {
439 expression: expression.clone(),
440 },
441 }
442 }
443}
444impl<T> Expression<T>
445where
446 T: TypeSet,
447{
448 pub fn location(&self) -> Location {
449 match self {
450 Expression::Expression { expression } => expression.location(),
451 Expression::Assignment {
452 left_expr,
453 operator: _,
454 right_expr,
455 } => {
456 let mut location = left_expr.location();
457
458 location.start = location.start.min(right_expr.location().start);
459 location.end = location.end.max(right_expr.location().end);
460
461 location
462 }
463 }
464 }
465}
466
467#[derive(Debug, Clone, Copy)]
468pub enum LeftHandExpression {
469 Name { variable: Token },
470 Deref { operator: Token, name: Token },
471}
472
473impl LeftHandExpression {
474 pub fn location(&self) -> Location {
475 match self {
476 LeftHandExpression::Name { variable } => variable.location,
477 LeftHandExpression::Deref { operator, name } => {
478 let mut location = operator.location;
479
480 location.start = location.start.min(name.location.start);
481 location.end = location.end.max(name.location.end);
482
483 location
484 }
485 }
486 }
487}
488
489#[derive(Debug)]
490pub enum RightHandExpression<T>
491where
492 T: TypeSet,
493{
494 Variable {
495 variable: Token,
496 },
497 Literal {
498 value: Literal<T>,
499 },
500 UnaryOperator {
501 name: Token,
502 operand: Box<Self>,
503 },
504 BinaryOperator {
505 name: Token,
506 operands: Box<[Self; 2]>,
507 },
508 FunctionCall {
509 name: Token,
510 arguments: Box<[Self]>,
511 },
512}
513
514impl<T> Clone for RightHandExpression<T>
515where
516 T: TypeSet,
517{
518 fn clone(&self) -> Self {
519 match self {
520 Self::Variable { variable } => Self::Variable {
521 variable: *variable,
522 },
523 Self::Literal { value } => Self::Literal {
524 value: value.clone(),
525 },
526 Self::UnaryOperator { name, operand } => Self::UnaryOperator {
527 name: *name,
528 operand: operand.clone(),
529 },
530 Self::BinaryOperator { name, operands } => Self::BinaryOperator {
531 name: *name,
532 operands: operands.clone(),
533 },
534 Self::FunctionCall { name, arguments } => Self::FunctionCall {
535 name: *name,
536 arguments: arguments.clone(),
537 },
538 }
539 }
540}
541impl<T> RightHandExpression<T>
542where
543 T: TypeSet,
544{
545 pub fn location(&self) -> Location {
546 match self {
547 RightHandExpression::Variable { variable } => variable.location,
548 RightHandExpression::Literal { value } => value.location,
549 RightHandExpression::FunctionCall { name, arguments } => {
550 let mut location = name.location;
551 for arg in arguments {
552 location.start = location.start.min(arg.location().start);
553 location.end = location.end.max(arg.location().end);
554 }
555 location
556 }
557 RightHandExpression::UnaryOperator { name, operand: rhs } => {
558 let mut location = name.location;
559
560 location.start = location.start.min(rhs.location().start);
561 location.end = location.end.max(rhs.location().end);
562
563 location
564 }
565 RightHandExpression::BinaryOperator {
566 name,
567 operands: arguments,
568 } => {
569 let mut location = name.location;
570 for arg in arguments.iter() {
571 location.start = location.start.min(arg.location().start);
572 location.end = location.end.max(arg.location().end);
573 }
574 location
575 }
576 }
577 }
578}
579
580#[derive(Debug)]
581pub struct Literal<T>
582where
583 T: TypeSet,
584{
585 pub value: LiteralValue<T>,
586 pub location: Location,
587}
588
589impl<T> Clone for Literal<T>
590where
591 T: TypeSet,
592{
593 fn clone(&self) -> Self {
594 Self {
595 value: self.value.clone(),
596 location: self.location,
597 }
598 }
599}
600
601#[derive(Debug)]
602pub enum LiteralValue<T>
603where
604 T: TypeSet,
605{
606 Integer(T::Integer),
607 Float(T::Float),
608 String(String),
609 Boolean(bool),
610}
611
612impl<T> Clone for LiteralValue<T>
613where
614 T: TypeSet,
615{
616 fn clone(&self) -> Self {
617 match self {
618 Self::Integer(arg0) => Self::Integer(*arg0),
619 Self::Float(arg0) => Self::Float(*arg0),
620 Self::String(arg0) => Self::String(arg0.clone()),
621 Self::Boolean(arg0) => Self::Boolean(*arg0),
622 }
623 }
624}