1use crate::ast::resolved_variable::{ResolvedVariable, VariableId};
2use crate::ast::spanned::Spanned;
3use crate::ast::type_expressions::TypeExpression;
4use crate::global::operators::BinaryOperator;
5use crate::global::operators::ComparisonOperator;
6use crate::global::operators::assignment::AssignmentOperator;
7use crate::global::operators::{ArithmeticUnaryOperator, UnaryOperator};
8use crate::references::reference::ReferenceMutability;
9use crate::stdlib::vec::Vec;
10use crate::values::core_value::CoreValue;
11pub use crate::values::core_values::callable::CallableKind;
12use crate::values::core_values::decimal::Decimal;
13use crate::values::core_values::decimal::typed_decimal::TypedDecimal;
14use crate::values::core_values::endpoint::Endpoint;
15use crate::values::core_values::integer::Integer;
16use crate::values::core_values::integer::typed_integer::TypedInteger;
17use crate::values::core_values::r#type::Type;
18use crate::values::pointer::PointerAddress;
19use crate::values::value::Value;
20use crate::values::value_container::ValueContainer;
21use core::fmt::Display;
22use core::ops::{Neg, Range};
23
24#[derive(Clone, Debug)]
25pub struct DatexExpression {
27 pub data: DatexExpressionData,
28 pub span: Range<usize>,
29 pub ty: Option<Type>,
30}
31impl Default for DatexExpression {
32 fn default() -> Self {
33 DatexExpression {
34 data: DatexExpressionData::Statements(Statements {
35 statements: Vec::new(),
36 is_terminated: false,
37 unbounded: None,
38 }),
39 span: 0..0,
40 ty: None,
41 }
42 }
43}
44impl DatexExpression {
45 pub fn new(data: DatexExpressionData, span: Range<usize>) -> Self {
46 DatexExpression {
47 data,
48 span,
49 ty: None,
50 }
51 }
52}
53
54impl PartialEq for DatexExpression {
56 fn eq(&self, other: &Self) -> bool {
57 self.data == other.data
58 }
59}
60
61#[derive(Clone, Debug, PartialEq)]
62#[derive(Default)]
64pub enum DatexExpressionData {
65 #[default]
68 Noop,
69
70 Recover,
71 NativeImplementationIndicator,
72
73 Null,
75 Boolean(bool),
77 Text(String),
79 Decimal(Decimal),
81
82 TypedDecimal(TypedDecimal),
84
85 Integer(Integer),
87
88 TypedInteger(TypedInteger),
90
91 Identifier(String),
93
94 Endpoint(Endpoint),
96 List(List),
98 Map(Map),
100 Statements(Statements),
102 GetReference(PointerAddress),
104
105 Conditional(Conditional),
107
108 VariableDeclaration(VariableDeclaration),
111 VariableAssignment(VariableAssignment),
113 VariableAccess(VariableAccess),
115
116 TypeDeclaration(TypeDeclaration),
121
122 TypeExpression(TypeExpression),
124
125 CallableDeclaration(CallableDeclaration),
127
128 CreateRef(CreateRef),
131
132 Deref(Deref),
134
135 Slot(Slot),
137
138 SlotAssignment(SlotAssignment),
140
141 PointerAddress(PointerAddress),
143
144 BinaryOperation(BinaryOperation),
146
147 ComparisonOperation(ComparisonOperation),
149
150 DerefAssignment(DerefAssignment),
152
153 PropertyAssignment(PropertyAssignment),
155
156 UnaryOperation(UnaryOperation),
158
159 Apply(Apply),
161
162 PropertyAccess(PropertyAccess),
164
165 GenericInstantiation(GenericInstantiation),
167
168 Placeholder,
170
171 RemoteExecution(RemoteExecution),
173
174 VariantAccess(VariantAccess),
176}
177
178impl Spanned for DatexExpressionData {
179 type Output = DatexExpression;
180
181 fn with_span<T: Into<Range<usize>>>(self, span: T) -> Self::Output {
182 DatexExpression {
183 data: self,
184 span: span.into(),
185 ty: None,
186 }
187 }
188
189 fn with_default_span(self) -> Self::Output {
190 DatexExpression {
191 data: self,
192 span: (0..0),
193 ty: None,
194 }
195 }
196}
197
198impl TryFrom<&DatexExpressionData> for ValueContainer {
200 type Error = ();
201
202 fn try_from(expr: &DatexExpressionData) -> Result<Self, Self::Error> {
203 Ok(match expr {
204 DatexExpressionData::UnaryOperation(UnaryOperation {
205 operator,
206 expression,
207 }) => {
208 let value = ValueContainer::try_from(&expression.data)?;
209 match value {
210 ValueContainer::Value(Value {
211 inner: CoreValue::Integer(_) | CoreValue::Decimal(_),
212 ..
213 }) => match operator {
214 UnaryOperator::Arithmetic(
215 ArithmeticUnaryOperator::Plus,
216 ) => value,
217 UnaryOperator::Arithmetic(
218 ArithmeticUnaryOperator::Minus,
219 ) => value.neg().map_err(|_| ())?,
220 _ => Err(())?,
221 },
222 _ => Err(())?,
223 }
224 }
225 DatexExpressionData::Null => ValueContainer::Value(Value::null()),
226 DatexExpressionData::Boolean(b) => ValueContainer::from(*b),
227 DatexExpressionData::Text(s) => ValueContainer::from(s.clone()),
228 DatexExpressionData::Decimal(d) => ValueContainer::from(d.clone()),
229 DatexExpressionData::Integer(i) => ValueContainer::from(i.clone()),
230 DatexExpressionData::TypedInteger(i) => {
231 ValueContainer::from(i.clone())
232 }
233 DatexExpressionData::TypedDecimal(d) => {
234 ValueContainer::from(d.clone())
235 }
236 DatexExpressionData::Endpoint(e) => ValueContainer::from(e.clone()),
237 DatexExpressionData::List(list) => {
238 let entries = list
239 .items
240 .iter()
241 .map(|e| ValueContainer::try_from(&e.data))
242 .collect::<Result<Vec<ValueContainer>, ()>>()?;
243 ValueContainer::from(
244 datex_core::values::core_values::list::List::from(entries),
245 )
246 }
247 DatexExpressionData::Map(pairs) => {
248 let entries = pairs
249 .entries
250 .iter()
251 .map(|(k, v)| {
252 let key = ValueContainer::try_from(&k.data)?;
253 let value = ValueContainer::try_from(&v.data)?;
254 Ok((key, value))
255 })
256 .collect::<Result<Vec<(ValueContainer, ValueContainer)>, ()>>()?;
257 ValueContainer::from(
258 crate::values::core_values::map::Map::from(entries),
259 )
260 }
261 _ => Err(())?,
262 })
263 }
264}
265
266#[derive(Clone, Debug, PartialEq)]
267pub struct BinaryOperation {
268 pub operator: BinaryOperator,
269 pub left: Box<DatexExpression>,
270 pub right: Box<DatexExpression>,
271 pub ty: Option<Type>,
272}
273
274#[derive(Clone, Debug, PartialEq)]
275pub struct ComparisonOperation {
276 pub operator: ComparisonOperator,
277 pub left: Box<DatexExpression>,
278 pub right: Box<DatexExpression>,
279}
280
281#[derive(Clone, Debug, PartialEq)]
282pub struct DerefAssignment {
283 pub operator: AssignmentOperator,
284 pub deref_expression: Box<DatexExpression>,
285 pub assigned_expression: Box<DatexExpression>,
286}
287
288#[derive(Clone, Debug, PartialEq)]
289pub struct PropertyAssignment {
290 pub operator: AssignmentOperator,
291 pub base: Box<DatexExpression>,
292 pub property: Box<DatexExpression>,
293 pub assigned_expression: Box<DatexExpression>,
294}
295
296#[derive(Clone, Debug, PartialEq)]
297pub struct Conditional {
298 pub condition: Box<DatexExpression>,
299 pub then_branch: Box<DatexExpression>,
300 pub else_branch: Option<Box<DatexExpression>>,
301}
302
303#[derive(Clone, Debug, PartialEq)]
304pub enum TypeDeclarationKind {
305 Nominal,
306 Structural,
307}
308impl Display for TypeDeclarationKind {
309 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
310 match self {
311 TypeDeclarationKind::Nominal => core::write!(f, "type"),
312 TypeDeclarationKind::Structural => core::write!(f, "typealias"),
313 }
314 }
315}
316impl TypeDeclarationKind {
317 pub fn is_nominal(&self) -> bool {
318 matches!(self, TypeDeclarationKind::Nominal)
319 }
320 pub fn is_structural(&self) -> bool {
321 matches!(self, TypeDeclarationKind::Structural)
322 }
323}
324
325#[derive(Clone, Debug, PartialEq)]
326pub struct TypeDeclaration {
327 pub id: Option<VariableId>,
328 pub name: String, pub definition: TypeExpression,
330 pub hoisted: bool,
331 pub kind: TypeDeclarationKind,
332}
333
334#[derive(Clone, Debug, PartialEq)]
335pub struct UnaryOperation {
336 pub operator: UnaryOperator,
337 pub expression: Box<DatexExpression>,
338}
339
340#[derive(Clone, Debug, PartialEq)]
341pub struct Apply {
342 pub base: Box<DatexExpression>,
343 pub arguments: Vec<DatexExpression>,
344}
345
346#[derive(Clone, Debug, PartialEq)]
347pub struct PropertyAccess {
348 pub base: Box<DatexExpression>,
349 pub property: Box<DatexExpression>,
350}
351
352#[derive(Clone, Debug, PartialEq)]
353pub struct GenericInstantiation {
354 pub base: Box<DatexExpression>,
355 pub generic_arguments: Vec<TypeExpression>,
356}
357
358#[derive(Clone, Debug, PartialEq)]
359pub struct RemoteExecution {
360 pub left: Box<DatexExpression>,
361 pub right: Box<DatexExpression>,
362}
363
364#[derive(Clone, Debug, PartialEq)]
365pub struct UnboundedStatement {
366 pub is_first: bool,
367 pub is_last: bool,
368}
369
370#[derive(Clone, Debug, PartialEq)]
371pub struct Statements {
372 pub statements: Vec<DatexExpression>,
373 pub is_terminated: bool,
374 pub unbounded: Option<UnboundedStatement>,
375}
376impl Statements {
377 pub fn empty() -> Self {
378 Statements {
379 statements: Vec::new(),
380 is_terminated: true,
381 unbounded: None,
382 }
383 }
384 pub fn new_terminated(statements: Vec<DatexExpression>) -> Self {
385 Statements {
386 statements,
387 is_terminated: true,
388 unbounded: None,
389 }
390 }
391 pub fn new_unterminated(statements: Vec<DatexExpression>) -> Self {
392 Statements {
393 statements,
394 is_terminated: false,
395 unbounded: None,
396 }
397 }
398}
399
400#[derive(Clone, Debug, PartialEq)]
401pub struct VariableDeclaration {
402 pub id: Option<VariableId>,
403 pub kind: VariableKind,
404 pub name: String,
405 pub type_annotation: Option<TypeExpression>,
406 pub init_expression: Box<DatexExpression>,
407}
408
409#[derive(Clone, Debug, PartialEq)]
410pub struct VariableAssignment {
411 pub id: Option<VariableId>,
412 pub name: String,
413 pub operator: AssignmentOperator,
414 pub expression: Box<DatexExpression>,
415}
416
417#[derive(Clone, Debug, PartialEq)]
418pub struct VariableAccess {
419 pub id: VariableId,
420 pub name: String,
421}
422
423#[derive(Clone, Debug, PartialEq)]
424pub struct CallableDeclaration {
425 pub name: Option<String>,
426 pub kind: CallableKind,
427 pub parameters: Vec<(String, TypeExpression)>,
428 pub rest_parameter: Option<(String, TypeExpression)>,
429 pub return_type: Option<TypeExpression>,
430 pub yeet_type: Option<TypeExpression>,
431 pub body: Box<DatexExpression>,
432}
433
434#[derive(Clone, Debug, PartialEq)]
435pub struct List {
436 pub items: Vec<DatexExpression>,
437}
438
439impl List {
440 pub fn new(items: Vec<DatexExpression>) -> Self {
441 List { items }
442 }
443}
444
445#[derive(Clone, Debug, PartialEq)]
446pub struct Map {
447 pub entries: Vec<(DatexExpression, DatexExpression)>,
448}
449
450impl Map {
451 pub fn new(entries: Vec<(DatexExpression, DatexExpression)>) -> Self {
452 Map { entries }
453 }
454}
455
456#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
457pub enum VariableKind {
458 Const,
459 Var,
460}
461
462impl Display for VariableKind {
463 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
464 match self {
465 VariableKind::Const => core::write!(f, "const"),
466 VariableKind::Var => core::write!(f, "var"),
467 }
468 }
469}
470
471#[derive(Clone, Debug, PartialEq)]
472pub enum Slot {
473 Addressed(u32),
474 Named(String),
475}
476impl Display for Slot {
477 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
478 core::write!(f, "#")?;
479 match self {
480 Slot::Addressed(addr) => core::write!(f, "{}", addr),
481 Slot::Named(name) => core::write!(f, "{}", name),
482 }
483 }
484}
485
486#[derive(Clone, Debug, PartialEq)]
487pub struct SlotAssignment {
488 pub slot: Slot,
489 pub expression: Box<DatexExpression>,
490}
491
492#[derive(Clone, Debug, PartialEq)]
493pub struct VariantAccess {
494 pub name: String,
495 pub variant: String,
496 pub base: ResolvedVariable,
497}
498
499#[derive(Clone, Debug, PartialEq)]
500pub struct Deref {
501 pub expression: Box<DatexExpression>,
502}
503
504#[derive(Clone, Debug, PartialEq)]
505pub struct CreateRef {
506 pub mutability: ReferenceMutability,
507 pub expression: Box<DatexExpression>,
508}