Skip to main content

somni_parser/
ast.rs

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}