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)]
282pub struct For<T>
283where
284 T: TypeSet,
285{
286 pub for_token: Token,
287 pub variable: Token,
288 pub var_type: Option<TypeHint>,
289 pub in_token: Token,
290 pub iterable: RightHandExpression<T>,
291 pub body: Body<T>,
292}
293impl<T> For<T>
294where
295 T: TypeSet,
296{
297 pub fn location(&self) -> Location {
298 Location {
299 start: self.for_token.location.start,
300 end: self.body.location().end,
301 }
302 }
303}
304
305impl<T> Clone for For<T>
306where
307 T: TypeSet,
308{
309 fn clone(&self) -> Self {
310 Self {
311 for_token: self.for_token,
312 variable: self.variable,
313 var_type: self.var_type,
314 in_token: self.in_token,
315 iterable: self.iterable.clone(),
316 body: self.body.clone(),
317 }
318 }
319}
320
321#[derive(Debug, Clone)]
322pub struct Break {
323 pub break_token: Token,
324 pub semicolon: Token,
325}
326
327impl Break {
328 pub fn location(&self) -> Location {
329 let start = self.break_token.location.start;
330 let end = self.semicolon.location.end;
331 Location { start, end }
332 }
333}
334
335#[derive(Debug, Clone)]
336pub struct Continue {
337 pub continue_token: Token,
338 pub semicolon: Token,
339}
340
341impl Continue {
342 pub fn location(&self) -> Location {
343 let start = self.continue_token.location.start;
344 let end = self.semicolon.location.end;
345 Location { start, end }
346 }
347}
348
349#[derive(Debug)]
350pub enum Statement<T>
351where
352 T: TypeSet,
353{
354 VariableDefinition(VariableDefinition<T>),
355 Return(ReturnWithValue<T>),
356 EmptyReturn(EmptyReturn),
357 If(If<T>),
358 Loop(Loop<T>),
359 For(For<T>),
360 Break(Break),
361 Continue(Continue),
362 Scope(Body<T>),
363 Expression {
364 expression: Expression<T>,
365 semicolon: Token,
366 },
367 ImplicitReturn(RightHandExpression<T>),
368}
369impl<T: TypeSet> Statement<T> {
370 pub fn location(&self) -> Location {
371 match self {
372 Statement::VariableDefinition(variable_definition) => variable_definition.location(),
373 Statement::Return(return_with_value) => return_with_value.location(),
374 Statement::EmptyReturn(empty_return) => empty_return.location(),
375 Statement::If(if_stmt) => if_stmt.location(),
376 Statement::Loop(loop_stmt) => loop_stmt.location(),
377 Statement::For(for_stmt) => for_stmt.location(),
378 Statement::Break(break_stmt) => break_stmt.location(),
379 Statement::Continue(continue_stmt) => continue_stmt.location(),
380 Statement::Scope(body) => body.location(),
381 Statement::Expression {
382 expression,
383 semicolon,
384 } => Location {
385 start: expression.location().start,
386 end: semicolon.location.end,
387 },
388 Statement::ImplicitReturn(right_hand_expression) => right_hand_expression.location(),
389 }
390 }
391}
392
393impl<T> Clone for Statement<T>
394where
395 T: TypeSet,
396{
397 fn clone(&self) -> Self {
398 match self {
399 Self::VariableDefinition(arg0) => Self::VariableDefinition(arg0.clone()),
400 Self::Return(arg0) => Self::Return(arg0.clone()),
401 Self::EmptyReturn(arg0) => Self::EmptyReturn(arg0.clone()),
402 Self::If(arg0) => Self::If(arg0.clone()),
403 Self::Loop(arg0) => Self::Loop(arg0.clone()),
404 Self::For(arg0) => Self::For(arg0.clone()),
405 Self::Break(arg0) => Self::Break(arg0.clone()),
406 Self::Continue(arg0) => Self::Continue(arg0.clone()),
407 Self::Scope(body) => Self::Scope(body.clone()),
408 Self::Expression {
409 expression,
410 semicolon,
411 } => Self::Expression {
412 expression: expression.clone(),
413 semicolon: *semicolon,
414 },
415 Statement::ImplicitReturn(expression) => Self::ImplicitReturn(expression.clone()),
416 }
417 }
418}
419
420#[derive(Debug)]
421pub struct Else<T>
422where
423 T: TypeSet,
424{
425 pub else_token: Token,
426 pub else_body: Body<T>,
427}
428impl<T> Else<T>
429where
430 T: TypeSet,
431{
432 pub fn location(&self) -> Location {
433 Location {
434 start: self.else_token.location.start,
435 end: self.else_body.location().end,
436 }
437 }
438}
439
440impl<T> Clone for Else<T>
441where
442 T: TypeSet,
443{
444 fn clone(&self) -> Self {
445 Self {
446 else_token: self.else_token,
447 else_body: self.else_body.clone(),
448 }
449 }
450}
451
452#[derive(Debug)]
453pub enum Expression<T>
454where
455 T: TypeSet,
456{
457 Assignment {
458 left_expr: LeftHandExpression,
459 operator: Token,
460 right_expr: RightHandExpression<T>,
461 },
462 Expression {
463 expression: RightHandExpression<T>,
464 },
465}
466impl<T> Clone for Expression<T>
467where
468 T: TypeSet,
469{
470 fn clone(&self) -> Self {
471 match self {
472 Expression::Assignment {
473 left_expr,
474 operator,
475 right_expr,
476 } => Self::Assignment {
477 left_expr: *left_expr,
478 operator: *operator,
479 right_expr: right_expr.clone(),
480 },
481 Expression::Expression { expression } => Self::Expression {
482 expression: expression.clone(),
483 },
484 }
485 }
486}
487impl<T> Expression<T>
488where
489 T: TypeSet,
490{
491 pub fn location(&self) -> Location {
492 match self {
493 Expression::Expression { expression } => expression.location(),
494 Expression::Assignment {
495 left_expr,
496 operator: _,
497 right_expr,
498 } => {
499 let mut location = left_expr.location();
500
501 location.start = location.start.min(right_expr.location().start);
502 location.end = location.end.max(right_expr.location().end);
503
504 location
505 }
506 }
507 }
508}
509
510#[derive(Debug, Clone, Copy)]
511pub enum LeftHandExpression {
512 Name { variable: Token },
513 Deref { operator: Token, name: Token },
514}
515
516impl LeftHandExpression {
517 pub fn location(&self) -> Location {
518 match self {
519 LeftHandExpression::Name { variable } => variable.location,
520 LeftHandExpression::Deref { operator, name } => {
521 let mut location = operator.location;
522
523 location.start = location.start.min(name.location.start);
524 location.end = location.end.max(name.location.end);
525
526 location
527 }
528 }
529 }
530}
531
532#[derive(Debug)]
533pub enum RightHandExpression<T>
534where
535 T: TypeSet,
536{
537 Variable {
538 variable: Token,
539 },
540 Literal {
541 value: Literal<T>,
542 },
543 UnaryOperator {
544 name: Token,
545 operand: Box<Self>,
546 },
547 BinaryOperator {
548 name: Token,
549 operands: Box<[Self; 2]>,
550 },
551 FunctionCall {
552 name: Token,
553 arguments: Box<[Self]>,
554 },
555}
556
557impl<T> Clone for RightHandExpression<T>
558where
559 T: TypeSet,
560{
561 fn clone(&self) -> Self {
562 match self {
563 Self::Variable { variable } => Self::Variable {
564 variable: *variable,
565 },
566 Self::Literal { value } => Self::Literal {
567 value: value.clone(),
568 },
569 Self::UnaryOperator { name, operand } => Self::UnaryOperator {
570 name: *name,
571 operand: operand.clone(),
572 },
573 Self::BinaryOperator { name, operands } => Self::BinaryOperator {
574 name: *name,
575 operands: operands.clone(),
576 },
577 Self::FunctionCall { name, arguments } => Self::FunctionCall {
578 name: *name,
579 arguments: arguments.clone(),
580 },
581 }
582 }
583}
584impl<T> RightHandExpression<T>
585where
586 T: TypeSet,
587{
588 pub fn location(&self) -> Location {
589 match self {
590 RightHandExpression::Variable { variable } => variable.location,
591 RightHandExpression::Literal { value } => value.location,
592 RightHandExpression::FunctionCall { name, arguments } => {
593 let mut location = name.location;
594 for arg in arguments {
595 location.start = location.start.min(arg.location().start);
596 location.end = location.end.max(arg.location().end);
597 }
598 location
599 }
600 RightHandExpression::UnaryOperator { name, operand: rhs } => {
601 let mut location = name.location;
602
603 location.start = location.start.min(rhs.location().start);
604 location.end = location.end.max(rhs.location().end);
605
606 location
607 }
608 RightHandExpression::BinaryOperator {
609 name,
610 operands: arguments,
611 } => {
612 let mut location = name.location;
613 for arg in arguments.iter() {
614 location.start = location.start.min(arg.location().start);
615 location.end = location.end.max(arg.location().end);
616 }
617 location
618 }
619 }
620 }
621}
622
623#[derive(Debug)]
624pub struct Literal<T>
625where
626 T: TypeSet,
627{
628 pub value: LiteralValue<T>,
629 pub location: Location,
630}
631
632impl<T> Clone for Literal<T>
633where
634 T: TypeSet,
635{
636 fn clone(&self) -> Self {
637 Self {
638 value: self.value.clone(),
639 location: self.location,
640 }
641 }
642}
643
644#[derive(Debug)]
645pub enum LiteralValue<T>
646where
647 T: TypeSet,
648{
649 Integer(T::Integer),
650 Float(T::Float),
651 String(String),
652 Boolean(bool),
653}
654
655impl<T> Clone for LiteralValue<T>
656where
657 T: TypeSet,
658{
659 fn clone(&self) -> Self {
660 match self {
661 Self::Integer(arg0) => Self::Integer(*arg0),
662 Self::Float(arg0) => Self::Float(*arg0),
663 Self::String(arg0) => Self::String(arg0.clone()),
664 Self::Boolean(arg0) => Self::Boolean(*arg0),
665 }
666 }
667}