1#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct Span {
7 pub offset: usize,
8 pub line: u32,
9 pub column: usize,
10 pub len: usize,
11}
12
13impl Span {
14 pub fn dummy() -> Self {
16 Self {
17 offset: 0,
18 line: 1,
19 column: 1,
20 len: 0,
21 }
22 }
23
24 pub fn to_lsp_range(&self) -> (u32, u32, u32, u32) {
26 let start_line = self.line.saturating_sub(1);
27 let start_char = self.column.saturating_sub(1);
28 let end_char = start_char.saturating_add(self.len);
29 (start_line, start_char as u32, start_line, end_char as u32)
30 }
31}
32
33#[cfg(test)]
34mod tests {
35 use super::Span;
36
37 #[test]
38 fn span_dummy() {
39 let s = Span::dummy();
40 assert_eq!(s.offset, 0);
41 assert_eq!(s.line, 1);
42 assert_eq!(s.column, 1);
43 assert_eq!(s.len, 0);
44 }
45}
46
47#[derive(Debug, Clone)]
48pub struct Node<T> {
49 pub span: Span,
50 pub value: T,
51}
52
53impl<T: PartialEq> PartialEq for Node<T> {
54 fn eq(&self, other: &Self) -> bool {
55 self.value == other.value
56 }
57}
58
59impl<T: Eq> Eq for Node<T> {}
60
61impl<T> Node<T> {
62 pub fn new(span: Span, value: T) -> Self {
63 Self { span, value }
64 }
65}
66
67impl<T> std::ops::Deref for Node<T> {
68 type Target = T;
69 fn deref(&self) -> &T {
70 &self.value
71 }
72}
73
74pub trait AstNode {
76 fn span(&self) -> Span;
77}
78
79impl<T> AstNode for Node<T> {
80 fn span(&self) -> Span {
81 self.span.clone()
82 }
83}
84
85#[derive(Debug, Clone, PartialEq, Eq)]
87pub enum BinaryOperator {
88 Eq,
89 Ne,
90 StrictEq,
91 StrictNe,
92 Lt,
93 Le,
94 Gt,
95 Ge,
96 Add,
97 Sub,
98 Mul,
99 Div,
100 Mod,
101 Exp,
102 Pow,
103 And,
104 Or,
105 Xor,
106 Implies,
107 Range,
108 BitOr,
109 BitAnd,
110 Other(String),
112}
113
114impl BinaryOperator {
115 pub fn from_token(token: &str) -> Self {
116 match token {
117 "==" => Self::Eq,
118 "!=" => Self::Ne,
119 "===" => Self::StrictEq,
120 "!==" => Self::StrictNe,
121 "<" => Self::Lt,
122 "<=" => Self::Le,
123 ">" => Self::Gt,
124 ">=" => Self::Ge,
125 "+" => Self::Add,
126 "-" => Self::Sub,
127 "*" => Self::Mul,
128 "/" => Self::Div,
129 "%" => Self::Mod,
130 "^" => Self::Pow,
131 "**" => Self::Exp,
132 "&&" | "and" => Self::And,
133 "||" | "or" => Self::Or,
134 "xor" => Self::Xor,
135 "implies" => Self::Implies,
136 ".." => Self::Range,
137 "|" => Self::BitOr,
138 "&" => Self::BitAnd,
139 other => Self::Other(other.to_string()),
140 }
141 }
142
143 pub fn as_str(&self) -> &str {
144 match self {
145 Self::Eq => "==",
146 Self::Ne => "!=",
147 Self::StrictEq => "===",
148 Self::StrictNe => "!==",
149 Self::Lt => "<",
150 Self::Le => "<=",
151 Self::Gt => ">",
152 Self::Ge => ">=",
153 Self::Add => "+",
154 Self::Sub => "-",
155 Self::Mul => "*",
156 Self::Div => "/",
157 Self::Mod => "%",
158 Self::Pow => "^",
159 Self::Exp => "**",
160 Self::And => "&&",
161 Self::Or => "||",
162 Self::Xor => "xor",
163 Self::Implies => "implies",
164 Self::Range => "..",
165 Self::BitOr => "|",
166 Self::BitAnd => "&",
167 Self::Other(s) => s.as_str(),
168 }
169 }
170}
171
172#[derive(Debug, Clone, PartialEq, Eq)]
174pub enum UnaryOperator {
175 Plus,
176 Minus,
177 Not,
178 BitNot,
179 Other(String),
180}
181
182impl UnaryOperator {
183 pub fn from_token(token: &str) -> Self {
184 match token {
185 "+" => Self::Plus,
186 "-" => Self::Minus,
187 "not" => Self::Not,
188 "~" => Self::BitNot,
189 other => Self::Other(other.to_string()),
190 }
191 }
192
193 pub fn as_str(&self) -> &str {
194 match self {
195 Self::Plus => "+",
196 Self::Minus => "-",
197 Self::Not => "not",
198 Self::BitNot => "~",
199 Self::Other(s) => s.as_str(),
200 }
201 }
202}
203
204#[derive(Debug, Clone, PartialEq, Eq)]
206pub enum Expression {
207 LiteralInteger(i64),
208 LiteralReal(String),
209 LiteralString(String),
210 LiteralBoolean(bool),
211 FeatureRef(String),
213 MemberAccess(Box<Node<Expression>>, String),
215 Index {
217 base: Box<Node<Expression>>,
218 index: Box<Node<Expression>>,
219 },
220 Bracket(Box<Node<Expression>>),
222 LiteralWithUnit {
224 value: Box<Node<Expression>>,
225 unit: Box<Node<Expression>>,
226 },
227 BinaryOp {
229 op: BinaryOperator,
230 left: Box<Node<Expression>>,
231 right: Box<Node<Expression>>,
232 },
233 UnaryOp {
235 op: UnaryOperator,
236 operand: Box<Node<Expression>>,
237 },
238 Invocation {
240 callee: Box<Node<Expression>>,
241 args: Vec<Node<Expression>>,
242 },
243 Tuple(Vec<Node<Expression>>),
245 Null,
247}