1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
use crate::lex::token::{Token, TokenVariant::*};
use super::{expression::Expression, statement::Statement};
#[derive(Debug, Clone, Copy)]
pub enum BinaryOperator {
Plus,
Minus,
Star,
Slash,
Eq,
Neq,
Gt,
Gte,
Lt,
Lte,
Assign,
ConstAssign,
Dot,
}
impl BinaryOperator {
pub fn from_token(token: Token) -> Self {
match token.variant {
OpPlus => Self::Plus,
OpMinus => Self::Minus,
OpStar => Self::Star,
OpSlash => Self::Slash,
OpEq => Self::Eq,
OpNeq => Self::Neq,
OpLt => Self::Lt,
OpGt => Self::Gt,
OpLte => Self::Lte,
OpGte => Self::Gte,
Assign => Self::Assign,
ConstAssign => Self::ConstAssign,
Dot => Self::Dot,
_ => panic!("Can't create binary operator from '{:?}'.", token.variant),
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum UnaryOperator {
Minus,
Not,
}
impl UnaryOperator {
pub fn from_token(token: Token) -> Self {
match token.variant {
OpMinus => Self::Minus,
OpNot => Self::Not,
_ => panic!("Can't create unary operator from '{:?}'.", token.variant),
}
}
}
#[derive(Debug, Clone)]
pub enum Literal {
Int(u32),
Float(f32),
Str(String),
Bool(bool),
}
impl Literal {
pub fn from_token(token: Token) -> Self {
match token.variant {
Int(int) => Self::Int(int),
Float(float) => Self::Float(float),
Str(string) => Self::Str(string),
KeywordTrue => Self::Bool(true),
KeywordFalse => Self::Bool(false),
_ => panic!("Can't create literal from '{:?}'.", token.variant),
}
}
}
pub type Identifier = String;
// If the contraint is None the type will have to be inferred
// during analysis.
#[derive(Debug, Clone)]
pub struct TypedIdentifier {
pub identifier: Identifier,
pub type_constraint: Option<Identifier>,
}
#[derive(Debug, Clone)]
pub struct FnNode {
pub header: FnHeader,
pub body: BlockNode,
}
#[derive(Debug, Clone)]
pub struct FnHeader {
pub has_self_receiver: bool,
pub parameters: Vec<TypedIdentifier>,
pub return_type: Option<Identifier>,
}
#[derive(Debug, Clone)]
pub struct IfNode {
pub conditionals: Vec<ConditionalBlock>,
pub else_block: Option<BlockNode>,
}
#[derive(Debug, Clone)]
pub struct LoopNode {
pub condition: Option<Expression>,
pub body: BlockNode,
}
#[derive(Debug, Clone)]
pub struct BlockNode {
pub statements: Vec<Statement>,
pub tail_expression: Option<Expression>,
}
#[derive(Debug, Clone)]
pub struct ConditionalBlock {
pub condition: Expression,
pub block: BlockNode,
}
|