1use crate::{Location, lexer::Token, parser::TypeSet};
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 Struct(StructDef),
20}
21
22#[derive(Debug, Clone)]
24pub struct StructDef {
25 pub struct_token: Token,
26 pub name: Token,
27 pub opening_brace: Token,
28 pub fields: Vec<StructField>,
29 pub closing_brace: Token,
30}
31
32impl StructDef {
33 pub fn location(&self) -> Location {
34 Location {
35 start: self.struct_token.location.start,
36 end: self.closing_brace.location.end,
37 }
38 }
39}
40
41#[derive(Debug, Clone)]
43pub struct StructField {
44 pub name: Token,
45 pub colon: Token,
46 pub field_type: TypeHint,
47}
48
49#[derive(Debug)]
50pub struct GlobalVariable<T>
51where
52 T: TypeSet,
53{
54 pub decl_token: Token,
55 pub identifier: Token,
56 pub colon: Token,
57 pub type_token: TypeHint,
58 pub equals_token: Token,
59 pub initializer: Expression<T>,
60 pub semicolon: Token,
61}
62impl<T> GlobalVariable<T>
63where
64 T: TypeSet,
65{
66 pub fn location(&self) -> Location {
67 let start = self.decl_token.location.start;
68 let end = self.semicolon.location.end;
69 Location { start, end }
70 }
71}
72
73#[derive(Debug)]
74pub struct ReturnDecl {
75 pub return_token: Token,
76 pub return_type: TypeHint,
77}
78
79#[derive(Debug)]
80pub struct ExternalFunction {
81 pub extern_fn_token: Token,
82 pub fn_token: Token,
83 pub name: Token,
84 pub opening_paren: Token,
85 pub arguments: Vec<FunctionArgument>,
86 pub closing_paren: Token,
87 pub return_decl: Option<ReturnDecl>,
88 pub semicolon: Token,
89}
90
91#[derive(Debug)]
92pub struct Function<T>
93where
94 T: TypeSet,
95{
96 pub fn_token: Token,
97 pub name: Token,
98 pub opening_paren: Token,
99 pub arguments: Vec<FunctionArgument>,
100 pub closing_paren: Token,
101 pub return_decl: Option<ReturnDecl>,
102 pub body: Body<T>,
103}
104
105#[derive(Debug)]
106pub struct Body<T>
107where
108 T: TypeSet,
109{
110 pub opening_brace: Token,
111 pub statements: Vec<Statement<T>>,
112 pub closing_brace: Token,
113}
114impl<T: TypeSet> Body<T> {
115 pub fn location(&self) -> Location {
116 Location {
117 start: self.opening_brace.location.start,
118 end: self.closing_brace.location.end,
119 }
120 }
121}
122
123impl<T> Clone for Body<T>
124where
125 T: TypeSet,
126{
127 fn clone(&self) -> Self {
128 Self {
129 opening_brace: self.opening_brace,
130 statements: self.statements.clone(),
131 closing_brace: self.closing_brace,
132 }
133 }
134}
135
136#[derive(Debug)]
137pub struct FunctionArgument {
138 pub name: Token,
139 pub colon: Token,
140 pub reference_token: Option<Token>,
141 pub arg_type: TypeHint,
142}
143
144#[derive(Clone, Copy, Debug)]
145pub struct TypeHint {
146 pub type_name: Token,
147}
148
149#[derive(Debug)]
150pub struct VariableDefinition<T>
151where
152 T: TypeSet,
153{
154 pub decl_token: Token,
155 pub identifier: Token,
156 pub type_token: Option<TypeHint>,
157 pub equals_token: Token,
158 pub initializer: RightHandExpression<T>,
159 pub semicolon: Token,
160}
161
162impl<T> Clone for VariableDefinition<T>
163where
164 T: TypeSet,
165{
166 fn clone(&self) -> Self {
167 Self {
168 decl_token: self.decl_token,
169 identifier: self.identifier,
170 type_token: self.type_token,
171 equals_token: self.equals_token,
172 initializer: self.initializer.clone(),
173 semicolon: self.semicolon,
174 }
175 }
176}
177
178impl<T> VariableDefinition<T>
179where
180 T: TypeSet,
181{
182 pub fn location(&self) -> Location {
183 let start = self.decl_token.location.start;
184 let end = self.semicolon.location.end;
185 Location { start, end }
186 }
187}
188
189#[derive(Debug)]
190pub struct ReturnWithValue<T>
191where
192 T: TypeSet,
193{
194 pub return_token: Token,
195 pub expression: RightHandExpression<T>,
196 pub semicolon: Token,
197}
198
199impl<T> Clone for ReturnWithValue<T>
200where
201 T: TypeSet,
202{
203 fn clone(&self) -> Self {
204 Self {
205 return_token: self.return_token,
206 expression: self.expression.clone(),
207 semicolon: self.semicolon,
208 }
209 }
210}
211
212impl<T> ReturnWithValue<T>
213where
214 T: TypeSet,
215{
216 pub fn location(&self) -> Location {
217 let start = self.return_token.location.start;
218 let end = self.semicolon.location.end;
219 Location { start, end }
220 }
221}
222
223#[derive(Debug, Clone)]
224pub struct EmptyReturn {
225 pub return_token: Token,
226 pub semicolon: Token,
227}
228
229impl EmptyReturn {
230 pub fn location(&self) -> Location {
231 let start = self.return_token.location.start;
232 let end = self.semicolon.location.end;
233 Location { start, end }
234 }
235}
236
237#[derive(Debug)]
238pub struct If<T>
239where
240 T: TypeSet,
241{
242 pub if_token: Token,
243 pub condition: RightHandExpression<T>,
244 pub body: Body<T>,
245 pub else_branch: Option<Else<T>>,
246}
247impl<T> If<T>
248where
249 T: TypeSet,
250{
251 pub fn location(&self) -> Location {
252 Location {
253 start: self.if_token.location.start,
254 end: self
255 .else_branch
256 .as_ref()
257 .map(|else_branch| else_branch.location().end)
258 .unwrap_or_else(|| self.body.location().end),
259 }
260 }
261}
262
263impl<T> Clone for If<T>
264where
265 T: TypeSet,
266{
267 fn clone(&self) -> Self {
268 Self {
269 if_token: self.if_token,
270 condition: self.condition.clone(),
271 body: self.body.clone(),
272 else_branch: self.else_branch.clone(),
273 }
274 }
275}
276
277#[derive(Debug)]
278pub struct Loop<T>
279where
280 T: TypeSet,
281{
282 pub loop_token: Token,
283 pub body: Body<T>,
284}
285impl<T> Loop<T>
286where
287 T: TypeSet,
288{
289 pub fn location(&self) -> Location {
290 Location {
291 start: self.loop_token.location.start,
292 end: self.body.location().end,
293 }
294 }
295}
296
297impl<T> Clone for Loop<T>
298where
299 T: TypeSet,
300{
301 fn clone(&self) -> Self {
302 Self {
303 loop_token: self.loop_token,
304 body: self.body.clone(),
305 }
306 }
307}
308
309#[derive(Debug)]
310pub struct For<T>
311where
312 T: TypeSet,
313{
314 pub for_token: Token,
315 pub variable: Token,
316 pub var_type: Option<TypeHint>,
317 pub in_token: Token,
318 pub iterable: RightHandExpression<T>,
319 pub body: Body<T>,
320}
321impl<T> For<T>
322where
323 T: TypeSet,
324{
325 pub fn location(&self) -> Location {
326 Location {
327 start: self.for_token.location.start,
328 end: self.body.location().end,
329 }
330 }
331}
332
333impl<T> Clone for For<T>
334where
335 T: TypeSet,
336{
337 fn clone(&self) -> Self {
338 Self {
339 for_token: self.for_token,
340 variable: self.variable,
341 var_type: self.var_type,
342 in_token: self.in_token,
343 iterable: self.iterable.clone(),
344 body: self.body.clone(),
345 }
346 }
347}
348
349#[derive(Debug, Clone)]
350pub struct Break {
351 pub break_token: Token,
352 pub semicolon: Token,
353}
354
355impl Break {
356 pub fn location(&self) -> Location {
357 let start = self.break_token.location.start;
358 let end = self.semicolon.location.end;
359 Location { start, end }
360 }
361}
362
363#[derive(Debug, Clone)]
364pub struct Continue {
365 pub continue_token: Token,
366 pub semicolon: Token,
367}
368
369impl Continue {
370 pub fn location(&self) -> Location {
371 let start = self.continue_token.location.start;
372 let end = self.semicolon.location.end;
373 Location { start, end }
374 }
375}
376
377#[derive(Debug)]
378pub enum Statement<T>
379where
380 T: TypeSet,
381{
382 VariableDefinition(VariableDefinition<T>),
383 Return(ReturnWithValue<T>),
384 EmptyReturn(EmptyReturn),
385 If(If<T>),
386 Loop(Loop<T>),
387 For(For<T>),
388 Break(Break),
389 Continue(Continue),
390 Scope(Body<T>),
391 Expression {
392 expression: Expression<T>,
393 semicolon: Token,
394 },
395 ImplicitReturn(RightHandExpression<T>),
396}
397impl<T: TypeSet> Statement<T> {
398 pub fn location(&self) -> Location {
399 match self {
400 Statement::VariableDefinition(variable_definition) => variable_definition.location(),
401 Statement::Return(return_with_value) => return_with_value.location(),
402 Statement::EmptyReturn(empty_return) => empty_return.location(),
403 Statement::If(if_stmt) => if_stmt.location(),
404 Statement::Loop(loop_stmt) => loop_stmt.location(),
405 Statement::For(for_stmt) => for_stmt.location(),
406 Statement::Break(break_stmt) => break_stmt.location(),
407 Statement::Continue(continue_stmt) => continue_stmt.location(),
408 Statement::Scope(body) => body.location(),
409 Statement::Expression {
410 expression,
411 semicolon,
412 } => Location {
413 start: expression.location().start,
414 end: semicolon.location.end,
415 },
416 Statement::ImplicitReturn(right_hand_expression) => right_hand_expression.location(),
417 }
418 }
419}
420
421impl<T> Clone for Statement<T>
422where
423 T: TypeSet,
424{
425 fn clone(&self) -> Self {
426 match self {
427 Self::VariableDefinition(arg0) => Self::VariableDefinition(arg0.clone()),
428 Self::Return(arg0) => Self::Return(arg0.clone()),
429 Self::EmptyReturn(arg0) => Self::EmptyReturn(arg0.clone()),
430 Self::If(arg0) => Self::If(arg0.clone()),
431 Self::Loop(arg0) => Self::Loop(arg0.clone()),
432 Self::For(arg0) => Self::For(arg0.clone()),
433 Self::Break(arg0) => Self::Break(arg0.clone()),
434 Self::Continue(arg0) => Self::Continue(arg0.clone()),
435 Self::Scope(body) => Self::Scope(body.clone()),
436 Self::Expression {
437 expression,
438 semicolon,
439 } => Self::Expression {
440 expression: expression.clone(),
441 semicolon: *semicolon,
442 },
443 Statement::ImplicitReturn(expression) => Self::ImplicitReturn(expression.clone()),
444 }
445 }
446}
447
448#[derive(Debug)]
449pub struct Else<T>
450where
451 T: TypeSet,
452{
453 pub else_token: Token,
454 pub else_body: Body<T>,
455}
456impl<T> Else<T>
457where
458 T: TypeSet,
459{
460 pub fn location(&self) -> Location {
461 Location {
462 start: self.else_token.location.start,
463 end: self.else_body.location().end,
464 }
465 }
466}
467
468impl<T> Clone for Else<T>
469where
470 T: TypeSet,
471{
472 fn clone(&self) -> Self {
473 Self {
474 else_token: self.else_token,
475 else_body: self.else_body.clone(),
476 }
477 }
478}
479
480#[derive(Debug)]
481pub enum Expression<T>
482where
483 T: TypeSet,
484{
485 Assignment {
486 left_expr: LeftHandExpression,
487 operator: Token,
488 right_expr: RightHandExpression<T>,
489 },
490 Expression {
491 expression: RightHandExpression<T>,
492 },
493}
494impl<T> Clone for Expression<T>
495where
496 T: TypeSet,
497{
498 fn clone(&self) -> Self {
499 match self {
500 Expression::Assignment {
501 left_expr,
502 operator,
503 right_expr,
504 } => Self::Assignment {
505 left_expr: left_expr.clone(),
506 operator: *operator,
507 right_expr: right_expr.clone(),
508 },
509 Expression::Expression { expression } => Self::Expression {
510 expression: expression.clone(),
511 },
512 }
513 }
514}
515impl<T> Expression<T>
516where
517 T: TypeSet,
518{
519 pub fn location(&self) -> Location {
520 match self {
521 Expression::Expression { expression } => expression.location(),
522 Expression::Assignment {
523 left_expr,
524 operator: _,
525 right_expr,
526 } => {
527 let mut location = left_expr.location();
528
529 location.start = location.start.min(right_expr.location().start);
530 location.end = location.end.max(right_expr.location().end);
531
532 location
533 }
534 }
535 }
536}
537
538#[derive(Debug, Clone)]
539pub enum LeftHandExpression {
540 Name {
541 variable: Token,
542 },
543 Deref {
544 operator: Token,
545 name: Token,
546 },
547 Field {
550 base: Box<LeftHandExpression>,
551 dot: Token,
552 field: Token,
553 },
554}
555
556impl LeftHandExpression {
557 pub fn location(&self) -> Location {
558 match self {
559 LeftHandExpression::Name { variable } => variable.location,
560 LeftHandExpression::Deref { operator, name } => {
561 let mut location = operator.location;
562
563 location.start = location.start.min(name.location.start);
564 location.end = location.end.max(name.location.end);
565
566 location
567 }
568 LeftHandExpression::Field { base, field, .. } => {
569 let mut location = base.location();
570
571 location.start = location.start.min(field.location.start);
572 location.end = location.end.max(field.location.end);
573
574 location
575 }
576 }
577 }
578}
579
580#[derive(Debug)]
581pub enum RightHandExpression<T>
582where
583 T: TypeSet,
584{
585 Variable {
586 variable: Token,
587 },
588 Literal {
589 value: Literal<T>,
590 },
591 UnaryOperator {
592 name: Token,
593 operand: Box<Self>,
594 },
595 BinaryOperator {
596 name: Token,
597 operands: Box<[Self; 2]>,
598 },
599 FunctionCall {
600 name: Token,
601 arguments: Box<[Self]>,
602 },
603 FieldAccess {
605 base: Box<Self>,
606 dot: Token,
607 field: Token,
608 },
609 StructLiteral {
611 name: Token,
612 opening_brace: Token,
613 fields: Vec<StructLiteralField<T>>,
614 closing_brace: Token,
615 },
616}
617
618#[derive(Debug)]
620pub struct StructLiteralField<T>
621where
622 T: TypeSet,
623{
624 pub name: Token,
625 pub colon: Token,
626 pub value: RightHandExpression<T>,
627}
628
629impl<T> Clone for StructLiteralField<T>
630where
631 T: TypeSet,
632{
633 fn clone(&self) -> Self {
634 Self {
635 name: self.name,
636 colon: self.colon,
637 value: self.value.clone(),
638 }
639 }
640}
641
642impl<T> Clone for RightHandExpression<T>
643where
644 T: TypeSet,
645{
646 fn clone(&self) -> Self {
647 match self {
648 Self::Variable { variable } => Self::Variable {
649 variable: *variable,
650 },
651 Self::Literal { value } => Self::Literal {
652 value: value.clone(),
653 },
654 Self::UnaryOperator { name, operand } => Self::UnaryOperator {
655 name: *name,
656 operand: operand.clone(),
657 },
658 Self::BinaryOperator { name, operands } => Self::BinaryOperator {
659 name: *name,
660 operands: operands.clone(),
661 },
662 Self::FunctionCall { name, arguments } => Self::FunctionCall {
663 name: *name,
664 arguments: arguments.clone(),
665 },
666 Self::FieldAccess { base, dot, field } => Self::FieldAccess {
667 base: base.clone(),
668 dot: *dot,
669 field: *field,
670 },
671 Self::StructLiteral {
672 name,
673 opening_brace,
674 fields,
675 closing_brace,
676 } => Self::StructLiteral {
677 name: *name,
678 opening_brace: *opening_brace,
679 fields: fields.clone(),
680 closing_brace: *closing_brace,
681 },
682 }
683 }
684}
685impl<T> RightHandExpression<T>
686where
687 T: TypeSet,
688{
689 pub fn location(&self) -> Location {
690 match self {
691 RightHandExpression::Variable { variable } => variable.location,
692 RightHandExpression::Literal { value } => value.location,
693 RightHandExpression::FunctionCall { name, arguments } => {
694 let mut location = name.location;
695 for arg in arguments {
696 location.start = location.start.min(arg.location().start);
697 location.end = location.end.max(arg.location().end);
698 }
699 location
700 }
701 RightHandExpression::UnaryOperator { name, operand: rhs } => {
702 let mut location = name.location;
703
704 location.start = location.start.min(rhs.location().start);
705 location.end = location.end.max(rhs.location().end);
706
707 location
708 }
709 RightHandExpression::BinaryOperator {
710 name,
711 operands: arguments,
712 } => {
713 let mut location = name.location;
714 for arg in arguments.iter() {
715 location.start = location.start.min(arg.location().start);
716 location.end = location.end.max(arg.location().end);
717 }
718 location
719 }
720 RightHandExpression::FieldAccess { base, field, .. } => {
721 let mut location = base.location();
722 location.start = location.start.min(field.location.start);
723 location.end = location.end.max(field.location.end);
724 location
725 }
726 RightHandExpression::StructLiteral {
727 name,
728 closing_brace,
729 ..
730 } => Location {
731 start: name.location.start,
732 end: closing_brace.location.end,
733 },
734 }
735 }
736}
737
738#[derive(Debug)]
739pub struct Literal<T>
740where
741 T: TypeSet,
742{
743 pub value: LiteralValue<T>,
744 pub location: Location,
745}
746
747impl<T> Clone for Literal<T>
748where
749 T: TypeSet,
750{
751 fn clone(&self) -> Self {
752 Self {
753 value: self.value.clone(),
754 location: self.location,
755 }
756 }
757}
758
759#[derive(Debug)]
760pub enum LiteralValue<T>
761where
762 T: TypeSet,
763{
764 Integer(T::Integer),
765 Float(T::Float),
766 String(String),
767 Boolean(bool),
768}
769
770impl<T> Clone for LiteralValue<T>
771where
772 T: TypeSet,
773{
774 fn clone(&self) -> Self {
775 match self {
776 Self::Integer(arg0) => Self::Integer(*arg0),
777 Self::Float(arg0) => Self::Float(*arg0),
778 Self::String(arg0) => Self::String(arg0.clone()),
779 Self::Boolean(arg0) => Self::Boolean(*arg0),
780 }
781 }
782}